Contents
About
Jenkins is a self-contained, open-source automation server for automating tasks in software building, testing, and deployment. It has an unparalleled plugin ecosystem with over a thousand plugins, enabling integration with practically every tool in the continuous integration/continuous delivery (CI/CD) pipeline. Jenkins can orchestrate a wide range of workflows from simple builds to complex release processes, making it a popular choice for implementing CI/CD.
Jenkins Pipeline is a key feature that allows defining an entire build/test/release process as code. Jenkins Pipeline implements the concept of Pipeline as Code, allowing teams to script their build and delivery pipeline via a domain-specific language (DSL). The pipeline definition is typically stored in source control as a Jenkinsfile, providing a single source of truth for the CI/CD workflow. This approach offers benefits like code review and versioning for the build pipeline, automated builds for all branches and pull requests, and a detailed audit trail of the pipeline's history.
flowchart LR
A[Developer commits code] --> B[Build Stage]
B --> C[Test Stage]
C --> D[Deploy Stage]
D --> E[Production Deployment]Figure: A simple Jenkins Pipeline flow from code commit through build, test, and deploy stages.
Setup Guide
Installation Options: Jenkins can be installed via native packages, Docker, or by running its standalone WAR file. Choose the method that best fits your environment:
-
Linux Package: Jenkins provides OS-specific installation packages. For example, on Ubuntu you can add the Jenkins apt repository and install Jenkins as a service:
# Install Jenkins on Ubuntu (after adding Jenkins repo and key) sudo apt-get update && sudo apt-get install jenkinsThis installs Jenkins and starts it as a background service. Refer to the official Jenkins Linux installation documentation for repository setup steps.
-
Docker Container: Use the official Docker image to run Jenkins in a container. For example:
docker run -p 8080:8080 -p 50000:50000 jenkins/jenkins:ltsThis command pulls the latest LTS Jenkins image and runs it, exposing the web UI on port 8080. Docker is a convenient way to sandbox Jenkins and its dependencies.
-
WAR File: Download the Jenkins WAR package and run it directly with Java. For instance:
java -jar jenkins.war --httpPort=8080This starts Jenkins on port 8080 for quick testing or custom setups. The WAR approach requires a Java Runtime Environment and is often used for local trials or advanced custom container deployments.
Initial Setup: After installation, open Jenkins in a web browser (e.g. http://localhost:8080). The first startup triggers a one-time setup wizard:
- Unlocking Jenkins: On first launch, Jenkins displays an Unlock Jenkins screen. Retrieve the initial admin password from the server (printed in the console or in the file
jenkins_home/secrets/initialAdminPassword), then paste it into the UI to unlock. - Install Plugins: Next, Jenkins will prompt to install plugins. You can choose Install suggested plugins, which includes a useful default set for typical CI needs. Jenkins will download and install these plugins – this may take a few minutes.
- Create Admin User: Finally, you'll be asked to create the first administrator user account. After creating a user and finishing the setup wizard, Jenkins is ready for use.
Once these steps are complete, you can access the Jenkins dashboard. From here, you can manage Jenkins, configure credentials, and create your first pipeline project.
Ongoing Usage
Once Jenkins is set up, you can continuously use it to define jobs, run pipelines, and monitor results. Key areas of ongoing usage include creating Jenkins pipeline jobs, understanding pipeline syntax, and managing build execution.
Jenkins Pipeline
Jenkins Pipeline enables defining complex build workflows in a single cohesive process (pipeline). It models the series of stages (build, test, deploy, etc.) your software goes through from commit to deployment. Pipelines are defined in code, typically in a file named Jenkinsfile at the root of your repository. This allows your pipeline configuration to be version-controlled alongside your application code.
Some benefits of using pipeline-as-code include:
- Single source of truth: The Jenkinsfile resides with your code, ensuring the pipeline logic is tracked in source control.
- Code review and iteration: Pipeline changes can be code-reviewed and versioned like any code change, improving collaboration.
- Branch and PR builds: Jenkins can automatically create build pipelines for each branch or pull request, ensuring consistent testing across all development branches.
- Durability: Pipeline executions are resilient; they can survive Jenkins restarts and agent reconnections, resuming where they left off.
- Visibility: The pipeline's stages and results are visualized in Jenkins UI, making it easy to see which stage failed and why.
Jenkins pipelines can be created in two ways: by using the classic Jenkins GUI (creating a Pipeline job and writing the script in the configuration) or by using a Multibranch Pipeline project that scans your source control for branches with a Jenkinsfile. The Jenkins Pipeline documentation recommends committing a Jenkinsfile to your repo and letting Jenkins automatically detect and run it, rather than hand-coding pipeline steps in the web UI.
Jenkins Pipeline Syntax
Jenkins Pipeline has two syntax options: Declarative and Scripted Pipeline. Both are based on Groovy DSL, but they differ in style and complexity:
-
Declarative Pipeline: A modern, simplified syntax that encapsulates the pipeline in a
pipeline { ... }block. It provides a more opinionated structure, making pipelines easier to write and read. Declarative syntax has specific sections likeagent,stages,steps,postfor cleanup, etc., and includes built-in directives for common CI/CD tasks (e.g.,options {},environment {},when {}for conditional execution). It is designed to cover most use cases with minimal code and clearer error messages. To use Declarative pipelines, the "Pipeline: Declarative" plugin must be installed. -
Scripted Pipeline: A lower-level, flexible syntax that uses native Groovy code inside a
node { ... }block. Scripted pipelines offer more control (you can use loops, conditionals, function calls, etc. as in Groovy) and are effectively Jenkins's pipeline engine exposed directly. However, they require more manual scripting and are prone to errors if not carefully written. Scripted syntax is useful for complex logic that may not fit in Declarative's structure, but for most cases Declarative is recommended for its simplicity.
In practice, Declarative Pipeline is the preferred approach for defining CI/CD pipelines, especially for team environments, because of its readability and built-in safeguards. Many pipeline features (parallel stages, matrix builds, post actions) are directly supported in Declarative syntax with a straightforward syntax.
Jenkins provides a built-in Pipeline Syntax Snippet Generator to help craft pipeline code. This is accessible from the Jenkins UI (for example, when configuring a Pipeline job, there's a Pipeline Syntax link). It allows you to select a step (including any plugin-provided steps), fill in parameters, and generates the Groovy code snippet for that step. This tool is extremely helpful when you're learning how to implement specific functionality in your pipeline. The Jenkins Pipeline Syntax reference is also an excellent resource to keep handy.
Jenkins Declarative Pipeline
A Declarative Pipeline is defined in a Jenkinsfile using a simple, human-readable structure. At minimum, it has a pipeline block that encloses an agent specification and one or more stages:
pipeline {
agent any // run on any available agent
stages {
stage('Build') {
steps {
echo 'Building the project...'
sh 'mvn compile'
}
}
stage('Test') {
steps {
echo 'Running tests...'
sh 'mvn test'
}
}
stage('Deploy') {
steps {
echo 'Deploying...'
// Deployment steps (e.g., copy files, docker push, etc.)
}
}
}
post {
always {
echo 'Pipeline finished'
}
}
}In this example, the pipeline has three stages: Build, Test, and Deploy. The agent any line instructs Jenkins to run the pipeline on any available agent (worker machine). Each stage contains a series of steps – shell commands or plugin steps that Jenkins will execute. For instance, the Build stage runs Maven to compile the project, the Test stage runs tests, and the Deploy stage would handle deployment logic. The optional post section defines actions that run after the stages (in this case, always print a completion message). Jenkins declarative syntax handles much of the boilerplate, so you don't need to script how to archive artifacts or notify results – many such tasks can be added via declarative directives or plugins.
Jenkins Pipeline Example
For a concrete example, suppose we have a simple Java application built with Maven. A Jenkinsfile (Declarative Pipeline) for this project might look like:
pipeline {
agent { docker { image 'maven:3.8.7-jdk-11' } } // use a Maven Docker container as build environment
stages {
stage('Checkout') {
steps {
git url: 'https://github.com/example/my-app.git', branch: 'main'
}
}
stage('Build') {
steps {
sh 'mvn -B package --file pom.xml'
}
}
stage('Test') {
steps {
sh 'mvn test'
junit 'target/surefire-reports/*.xml' // archive test results
}
}
stage('Archive') {
steps {
archiveArtifacts artifacts: 'target/*.jar', fingerprint: true
}
}
}
}This Pipeline performs a Git checkout, builds the project, runs tests (recording results with the JUnit plugin), and archives the built JAR artifact. Notably, it uses a Docker agent – Jenkins will run the stages inside a container with Maven installed, ensuring a consistent build environment. Such a Jenkinsfile can be placed in the repository so Jenkins will automatically detect and execute it on each commit.
Build Jenkins Pipeline
To run a Jenkins Pipeline, you typically create a Pipeline job in Jenkins and point it at your repository's Jenkinsfile. In Jenkins classic UI, you would create a new item of type "Pipeline" and configure the Pipeline section to use either pipeline script from SCM (connecting to your Git repository) or directly paste a Jenkinsfile script. For multibranch projects or GitHub Organization folders, Jenkins can auto-detect Jenkinsfiles on all branches and create appropriate jobs.
Once configured, triggering the pipeline can be done manually (via the Build Now button) or automatically. A common approach is to set up a webhook from your source control (GitHub, GitLab, Bitbucket, etc.) so that any commit triggers Jenkins to run the pipeline on that branch. You can also schedule builds or trigger pipelines after other jobs, depending on your CI/CD needs.
(Pipeline: Stage View | Jenkins plugin) Figure: Jenkins Pipeline Stage View. Jenkins's classic interface provides a Stage View that visualizes pipeline runs. Each column represents a defined stage (e.g., "Build", "Unit Test", etc.), and each row is a pipeline run (build number). In the example above, multiple test stages run in parallel (hence multiple columns under testing) with their durations displayed; a failed stage is highlighted in red. This view lets you quickly assess which stage failed in a given run and how long each stage took. You can click on a stage cell to view its log output or on the build number to see full console logs and artifacts.
In addition to the classic UI, Jenkins offers Blue Ocean (a modern UI plugin) that shows pipelines as a visual flow with nodes for each stage. In Blue Ocean or Stage View, you can easily track the progress of a running pipeline and see success/failure of each stage at a glance. Logs and artifacts are accessible for troubleshooting when a stage fails. For example, if the Test stage fails, you can inspect the test reports (like JUnit results) that were archived to pinpoint the failing tests.
Using with FOSSA
About FOSSA: FOSSA is a software composition analysis (SCA) tool that continuously scans open-source components in your project, tracking dependencies, license compliance, and potential vulnerabilities. Integrating FOSSA with Jenkins allows you to automatically audit your project's open-source license and security posture as part of your CI pipeline, preventing problematic dependencies from slipping through.
Integration Setup: To use FOSSA in Jenkins, you'll need the FOSSA CLI tool and an API key for your FOSSA account:
-
Install FOSSA CLI: Ensure the FOSSA CLI (
fossa-cli) is available on the Jenkins build agent. You can pre-install it on the agent machine, or automate the installation at pipeline runtime. FOSSA provides a one-line installation script that works on Linux agents (FOSSA Documentation). For example, you can add a step in your pipeline to run:curl -H 'Cache-Control: no-cache' https://raw.githubusercontent.com/fossas/fossa-cli/master/install-latest.sh | bashThis downloads and installs the latest
fossaclient on the agent. -
Provide FOSSA API Key: In your FOSSA account, generate an API token (found under Integration Settings in FOSSA) and add it to Jenkins. It's best to store this as a secret text credential in Jenkins, then expose it as an environment variable (e.g.,
FOSSA_API_KEY) in your pipeline job (FOSSA Documentation). This key authenticates the CLI to upload scan results to your FOSSA project.
Pipeline Integration: With the CLI installed and API key set, add stages in your Jenkins pipeline for FOSSA. Typically, you'd insert a FOSSA scan stage after your build and test stages, when all project dependencies have been pulled down (so that FOSSA can analyze them) (FOSSA Documentation) (FOSSA Documentation). For example:
stage('FOSSA Analysis') {
steps {
// Ensure FOSSA CLI is installed (if not pre-installed on agent)
sh 'curl -H "Cache-Control: no-cache" https://raw.githubusercontent.com/fossas/fossa-cli/master/install-latest.sh | bash'
// Run FOSSA scan
withEnv(["FOSSA_API_KEY=${env.FOSSA_API_KEY}"]) {
sh 'fossa analyze'
}
}
}In the above snippet, the pipeline downloads the FOSSA CLI (if needed) and then runs fossa analyze. The FOSSA CLI scans the project's dependency tree and uploads the data to FOSSA's service for analysis (FOSSA Documentation). By setting the FOSSA_API_KEY in the environment, the CLI can authenticate (you could also embed the API key directly in the command, but using a secret variable is more secure).
Optionally, you can add a subsequent stage to enforce policies using fossa test. The fossa test command will poll FOSSA for the scan result and exit with a non-zero status if any policy violations or issues are found (FOSSA Documentation). For example, a FOSSA Policy Gate stage could run fossa test --timeout 300 to wait (up to 5 minutes) for FOSSA's analysis and fail the build if a license or security violation is detected. This turns FOSSA into a quality gate in your pipeline – if the open-source audit fails, the Jenkins build is marked unstable or failed.
Value Proposition: Integrating FOSSA into Jenkins pipelines enhances the CI/CD process with automated open-source risk management. It ensures that every build is vetted for license compliance and security vulnerabilities as part of the build process, catching potential issues early when they are easier to address. This integration turns Jenkins into not just a build/test automation server, but also a compliance gatekeeper – providing confidence that each build meets your organization's open-source standards before it progresses down the delivery pipeline.