What is Jenkins?
Jenkins is a tool that helps automate tasks in software development, especially tasks related to building, testing, and deploying software. It is widely used in Continuous Integration (CI) and Continuous Deployment (CD) pipelines. Jenkins allows developers to easily integrate their code into a shared repository, automate testing, and deploy software applications.
What is CI/CD?
• Continuous Integration (CI) is a software development practice where code changes are automatically integrated into the main branch multiple times a day. This ensures that bugs are caught early and integration problems are avoided.
• Continuous Deployment (CD) refers to the automatic deployment of applications to production once the code is successfully built, tested, and verified. In a CD pipeline, once the code passes all tests, it is deployed to the live environment automatically.
Together, CI/CD aims to streamline the software development process, ensuring high quality and fast delivery.
Is Jenkins a CI or CD tool?
Jenkins is both a CI (Continuous Integration) and CD (Continuous Deployment) tool.
How Jenkins fits into CI/CD:
1. Continuous Integration (CI):
• Jenkins automatically builds the software every time a developer makes a change to the code (for example, by pushing it to a code repository).
• It also runs tests on the new code to make sure everything works as expected.
2. Continuous Delivery (CD):
• Once the code is tested and ready, Jenkins can automatically deploy it (move it to a live environment) to make it available for users.
Jenkins is like an assistant for developers, constantly checking the code, making sure it works, and pushing it to where it needs to go, all without manual effort. This makes the development process faster and smoother!
Key Components of Jenkins:
1. Jenkins Controller:
• Think of the Controller as the “brain” of Jenkins. It controls everything and manages the overall setup.
• It schedules and monitors jobs, manages Jenkins settings, and keeps track of the status of builds and tests.
• The Controller is where you interact with Jenkins (usually through a web interface), and it’s where the Jenkins dashboard is located.
2. Jenkins Agents:
• Agents are separate machines or computers that do the heavy lifting of running jobs (like builds or tests).
• Instead of the Controller doing all the work, the Controller delegates tasks to these Agents to speed things up and balance the load.
3. Executors:
• Executors are the “workers” on each machine (Controller or Agents).
• Each Executor is responsible for running one task/job (like building or testing code).
• A Jenkins machine (Controller or Agents) can have multiple Executors to run multiple jobs at the same time.
How the Jenkins Controller and Agents Communicate
Jenkins has a Controller that manages Agents, which run the actual jobs. They communicate using different methods:
TCP (JNLP - Java Network Launch Protocol):
• The most common way for agents to connect when running on different machines.
• The agent starts the connection using a JNLP file and talks to the controller over TCP.
SSH:
• Used mainly for Linux-based agents.
• The Jenkins Controller connects to an agent securely using SSH.
WebSockets:
• Helps agents connect when regular TCP connections are blocked (like in cloud environments with firewalls).
• Uses standard web traffic (HTTP/S) to keep the connection open.
Message Queues & Cloud Services:
• Some cloud setups use special messaging systems (like Kubernetes APIs) to manage agent connections.
How does Jenkins work?
1. Install Jenkins: Jenkins runs on a server (can be local or cloud-based).
2. Create Jobs: A job is a task that Jenkins performs. For example, building code, testing, etc.
3. Set up a Pipeline: A sequence of steps that Jenkins will execute. These steps could be building the software, running tests, and deploying it.
4. Automated Execution: Jenkins checks for changes in the code repository (e.g., Git). If changes are detected, it triggers jobs (builds) to be executed.
5. Reports and Notifications: After the job completes, Jenkins can generate reports and notify users of success or failure.
How It All Works Together:
• The Controller tells the Agents what jobs to run.
• The Agents have Executors that actually perform the tasks (like building the code or running tests).
• This setup helps Jenkins handle many tasks at once, making the process faster and more efficient.
What is Pipeline?
A Pipeline in Jenkins is a series of automated steps that define the process from code commit to deployment. It could include building, testing, and deploying the software. Pipelines can be written in Jenkinsfile (which is a text file containing pipeline definitions in code).
What is a Jenkins Pipeline?
A Jenkins Pipeline is a set of automated steps defined in a Jenkinsfile to handle various tasks like building, testing, and deploying code. It can be configured with two types of syntax:
1. Declarative Pipeline – Simple and structured syntax for beginners.
2. Scripted Pipeline – More flexible and dynamic syntax for advanced users.
Scripted vs. Declarative Pipelines
• Declarative Pipeline: More structured and user-friendly. It’s easier to understand and write for most developers.
• Syntax Example:
pipeline {
agent any
stages {
stage('Build') {
steps {
echo 'Building...'
}
}
}
}
• Scripted Pipeline: More flexible and allows for greater customization, using regular Groovy scripts.
• Syntax Example:
node {
stage('Build') {
echo 'Building...'
}
}
Jenkins Pipeline Syntax
Jenkins Pipeline is written in Groovy. The syntax consists of:
• Pipeline Block: Defines the pipeline.
• Stages: Blocks where you define different stages of the pipeline (like build, test, deploy).
• Steps: Commands to run during each stage.
Example:
pipeline {
agent any
stages {
stage('Build') {
steps {
echo 'Building application'
}
}
}
}
What are the Benefits of Using Jenkins?
• Automation: Automates the CI/CD processes.
• Plugins: Large ecosystem of plugins.
• Distributed Builds: Supports distributed builds (using multiple agents).
• Scalability: Easily scales for large teams and projects.
• Integration with other tools: Jenkins integrates well with tools like Git, Maven, Docker, etc.
What are the Disadvantages of Jenkins?
• Complexity: Can become complex for beginners.
• Maintenance: Requires regular maintenance and updates.
• UI: The user interface may feel outdated.
• Performance Issues: Can suffer from performance issues in large projects.
Jenkins Installation Using Docker
Prerequisites
Before beginning the installation, ensure that you have the following:
Docker installed and running on your system.
A basic understanding of Docker commands.
Access to a terminal or command-line interface.
- Build the Jenkins Image on Docker
Dockerfile:
FROM jenkins/jenkins:lts
USER root
# Install necessary dependencies
RUN apt-get update && apt-get install -y lsb-release python3-pip curl
# Add Docker’s official GPG key
RUN curl -fsSLo /usr/share/keyrings/docker-archive-keyring.asc \
https://download.docker.com/linux/debian/gpg
# Add Docker repository
RUN echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.asc] \
https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker CLI
RUN apt-get update && apt-get install -y docker-ce-cli
# Switch back to Jenkins user
USER jenkins
# Install necessary Jenkins plugins
RUN jenkins-plugin-cli --plugins "blueocean docker-workflow"
In the folder containing the Dockerfile, run the following command to build the Jenkins BlueOcean image:
docker build -t my-jenkins .
This command will:
Read the Dockerfile in the current directory (.).
Tag the image as my-jenkins
Create a Docker Network for Jenkins
Before running the container, you need to create a Docker network named jenkins to facilitate communication between the Jenkins container and other containers (such as Docker for Jenkins’ Docker integration). Run the following command:
docker network create jenkins
- Run the Jenkins Container
Now that the image is built or pulled, you can run Jenkins with the necessary configurations. The exact command varies depending on your operating system.
For MacOS / Linux
docker run -d --name my-jenkins -p 8080:8080 -p 50000:50000 \
-v jenkins_home:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
my-jenkins
Windows with WSL 2 backend
docker run -d --name my-jenkins -p 8080:8080 -p 50000:50000 ^
-v jenkins_home:/var/jenkins_home ^
-v //var/run/docker.sock:/var/run/docker.sock ^
my-jenkins
Check logs to get the initial password:
docker logs my-jenkins
- Access Jenkins Web Interface
Now that Jenkins is running, you can access the Jenkins web interface by visiting the following URL in your web browser:
https://localhost:8080/
Add a New Folder in Jenkins:
1. Log into Jenkins:
• Open your Jenkins instance in a web browser. By default, it’s available at http://localhost:8080 if you are running Jenkins locally.
• Log in with your Jenkins credentials.
2. Go to the Jenkins Dashboard:
• Once logged in, you’ll be taken to the Jenkins dashboard. This is where you see all your existing jobs and folders.
3. Click on “New Item”:
• On the left-hand sidebar of the Jenkins dashboard, you will see an option for “New Item”. Click it.
4. Create a Folder:
• In the “New Item” dialog box, type the name of your folder (for example, “Sandbox”).
• Choose “Folder” from the list of options.
• Click OK to proceed.
5. Configure Folder (Optional):
• You will now be taken to a configuration page for the folder. Here, you can configure various properties such as:
• Description: You can add a description to explain the purpose of this folder (e.g., “A sandbox for learning and testing new jobs”).
• Permissions: Set folder-level permissions, such as who can view or modify the jobs within this folder.
6. Save the Folder:
• After configuring (or skipping the configuration steps), scroll down and click Save.
7. Access Your Folder:
• Once the folder is created, it will appear on the Jenkins dashboard. You can now add jobs to this folder by clicking inside the folder and creating new jobs within it.
To Add Jobs to the Folder:
1. After creating the folder, you can add jobs by navigating to the folder and selecting “New Item”.
2. From there, you can create any type of Jenkins job (e.g., Freestyle project, Pipeline, etc.) as you normally would, but they will now reside inside the folder you created.
Example Workflow:
1. Create a folder named “Sandbox”.
2. Inside the “Sandbox” folder, create multiple Jenkins jobs that you want to test or experiment with.
3. Organize these jobs logically within the folder without cluttering the main Jenkins dashboard.
Benefits of Using Folders in Jenkins:
• Organize Jobs: Helps keep your Jenkins dashboard clean and organized.
• Access Control: You can apply permissions to the folder level, allowing different teams or users to have access to specific sets of jobs.
• Clarity: Grouping related jobs (e.g., experimental or test jobs) into folders improves clarity and workflow management.
Pipelines Introduction
1. Open Jenkins in your browser (http://localhost:8080).
2. Once you are logged in, click on “New Item” on the left side.
3. In the “Item name” field, enter a name for your job.
4. Select “Pipeline” and click OK.
5. This will create a new pipeline job where you can define your pipeline logic.
In Jenkins, the Jenkinsfile is a text file that defines the steps in your pipeline. It can be stored inside your project repository or directly in Jenkins.
A basic example of a Jenkinsfile looks like this:
pipeline {
agent any // This specifies that the pipeline can run on any available agent
stages {
stage('Build') {
steps {
echo 'Building the application...'
// Add build commands here (e.g., mvn, gradle, npm, etc.)
}
}
stage('Test') {
steps {
echo 'Running tests...'
// Add test commands here (e.g., run unit tests, integration tests, etc.)
}
}
stage('Deploy') {
steps {
echo 'Deploying the application...'
// Add deployment steps here (e.g., deploy to staging server, cloud, etc.)
}
}
}
}
Explanation:
• pipeline block: Defines the entire Jenkins pipeline.
• agent any: Specifies that this pipeline can run on any available machine.
• stages: A collection of individual tasks (stages) for your pipeline, such as Build, Test, and Deploy.
• steps: Commands that are executed during each stage.
- Run the Pipeline
To run the pipeline:
1. After you’ve created your job and added your Jenkinsfile, click Save.
2. On the job dashboard, click Build Now on the left side.
3. Jenkins will start the pipeline and show the progress in real-time.
Pipelines with variables
In Jenkins Pipelines, variables help make scripts more flexible and reusable. You can define variables in multiple ways and use them throughout your pipeline.
Defining Variables in a Jenkinsfile
You can define variables at the top of your Jenkinsfile and reference them inside different stages.
Example: Using a Simple Variable
def buildTool = 'Maven'
pipeline {
agent any
stages {
stage('Build') {
steps {
echo "Building with ${buildTool}"
}
}
}
}
✅ Explanation:
• The variable buildTool is defined outside the pipeline block using def.
• It is referenced inside the Build stage using ${buildTool}.
Environment Variables in a Pipeline
Jenkins allows defining environment variables that can be used across different stages.
Example: Using Environment Variables
pipeline {
agent any
environment {
JAVA_HOME = '/usr/lib/jvm/java-11'
APP_NAME = 'MyApp'
}
stages {
stage('Build') {
steps {
echo "Building ${APP_NAME} with Java located at ${JAVA_HOME}"
}
}
}
}
✅ Explanation:
• environment block is used to define environment variables.
• Variables like JAVA_HOME and APP_NAME can be used inside the pipeline.
Dynamically Assigning Variables
Variables can be dynamically set during execution.
Example: Assigning Variables Inside the Pipeline
pipeline {
agent any
stages {
stage('Set Variables') {
steps {
script {
def currentDate = new Date().format('yyyy-MM-dd')
env.BUILD_DATE = currentDate
echo "Today's date is ${env.BUILD_DATE}"
}
}
}
}
}
✅ Explanation:
• script block is used for complex Groovy scripting.
• A variable currentDate is assigned dynamically.
• env.BUILD_DATE is used to store the value.
Global vs Local Variables
• Global Variables: Defined outside the pipeline block, accessible throughout the pipeline.
• Local Variables: Defined inside a script block, accessible only within that block.
// Global variable (Accessible throughout the pipeline)
def globalVar = "I am a global variable"
pipeline {
agent any
stages {
stage('Global Variable Example') {
steps {
script {
echo "Accessing global variable: ${globalVar}"
}
}
}
stage('Local Variable Example') {
steps {
script {
// Local variable (Accessible only within this script block)
def localVar = "I am a local variable"
echo "Accessing local variable: ${localVar}"
}
}
}
stage('Trying to Access Local Variable') {
steps {
script {
// This will cause an error because localVar is not accessible here
echo "Trying to access local variable: ${localVar}"
}
}
}
}
}
Explanation:
1. globalVar is defined outside any script block, making it accessible in all stages.
2. localVar is defined inside a script block, meaning it can only be used within that block.
3. The last stage will fail because localVar is not accessible outside its script block.
Using Variables in Shell Commands
You can pass variables to shell scripts using sh.
Example: Using Variables in a Shell Command
pipeline {
agent any
environment {
GREETING = "Hello, Jenkins!"
}
stages {
stage('Print Message') {
steps {
sh 'echo $GREETING'
}
}
}
}
✅ Explanation:
• The environment variable GREETING is accessed inside the shell script using $GREETING.
Parameterized Pipeline
• Define parameters that allow users to customize the build.
parameters {
string(name: 'BRANCH', defaultValue: 'main', description: 'Git Branch')
}
pipeline {
agent any
stages {
stage('Checkout') {
steps {
git branch: params.BRANCH, url: 'https://github.com/your-repo.git'
}
}
}
}
Post Actions
• Use the post section to define actions that will happen after the build (success, failure, etc.).
pipeline {
agent any
stages {
stage('Build') {
steps {
echo 'Building...'
}
}
}
post {
success {
echo 'Build was successful!'
}
failure {
echo 'Build failed!'
}
}
}
When Conditions
• Conditional execution can be added using when statements.
pipeline {
agent any
stages {
stage('Build') {
when {
branch 'main'
beforeAgent true
}
steps {
echo 'Building on main branch'
}
}
stage('Test') {
when {
branch 'develop'
expression { return env.BRANCH_NAME == 'develop' }
}
steps {
echo 'Running tests on develop branch'
}
}
stage('Deploy') {
when {
branch 'release/*'
}
steps {
echo 'Deploying to production from release branch'
}
}
}
}
Pipeline Options
• Use pipeline options to control resources like timeouts, retries, etc.
pipeline {
options {
timeout(time: 1, unit: 'HOURS')
}
stages {
stage('Build') {
steps {
echo 'Building...'
}
}
}
}
Interactive Pipelines
• You can interact with the pipeline using input steps.
pipeline {
agent any
stages {
stage('Approval') {
steps {
input 'Approve Deployment?'
}
}
}
}
Triggering Pipeline
• Pipelines can be triggered manually or automatically (e.g., on commit).
triggers {
cron('H/5 * * * *') # This checks for new commits every 5 minutes.
}
This article explains Jenkins fundamentals, covering what Jenkins is, how it fits into CI/CD, and why it’s useful. It introduces Jenkins components like the Controller, Agents, and Executors, showing how they work together to automate software development tasks.
We also learn about Jenkins Pipelines, including Declarative and Scripted Pipelines, with examples of how to define and run them. The guide walks through installing Jenkins using Docker, creating folders, setting up jobs, and using pipelines with variables, conditions, and triggers.
We now have a solid understanding of how to use Jenkins to automate builds, tests, and deployments, making your software development process faster, smoother, and more efficient!
Find the GitHub repo here.
If you find this blog helpful too, give back and show your support by clicking heart or like, share this article as a conversation starter and join my newsletter so that we can continue learning together and you won’t miss any future posts.
Thanks for reading until the end! If you have any questions or feedback, feel free to leave a comment.