How to setup CI/CD pipeline using Jenkins and docker?

Get started with your first pipeline using Git, Jenkins, and Docker, leveraging docker and running Jenkins as a container in the Docker installed in your system.

You can’t get rid of bugs/issues. You can fix them early than facing a disaster.

Doing it more frequently and facing the pain at first is better than getting agonized later.

What is Continuous Integration(CI)?

It is a process of continuously pushing your code into a repository and merging with the main branch followed by the building the integrated code which is further followed by automated tests against the build. It checks that application is not broken after merging new code into the main branch.

What is Continuous Delivery(CD)?

It extends the flow by taking a releasable artifact after passing through all previous steps successfully and creating an automated pipeline to deploy the application in a staging/pre-production environment and upon confirmation(can be just a button click) deploy the same to the production.

Some of us might think of it as Continuous Deployment. But here’s a difference,

As in Continuous Delivery, we decide when to deploy our new application version just on a click of a button whereas in Continuous Deployment we take out this single manual intervention and all the releasable artifacts will be deployed through an automated pipeline directly to the production environment.

It depends on some other factors like organization and business needs and their decision.

The integrated flow of CI/CD

cicd pipeline
cicd pipeline

Now, Let’s start building our first CI/CD pipeline:

Git(Codebase):

codebase is any single repo (in a centralized revision control system like Subversion), or any set of repos who share a root commit (in a decentralized revision control system like Git). There is only one codebase per app, but there will be many deploys of the app.

https://12factor.net/

I assume you are aware of anyone code management system like Git, Gitlab, Github and you have your repository ready to push and merge your new codes into the main branch.

Pre-requisites for next steps are:

  • Docker is installed and configured to run properly in your machine.
  • Basic commands to create an image from a dockerfile and run a container from it.

Check out below links to get some hands-on building an image and running a container along with sample docker file

Jenkins:

Now we can set up Jenkins on the host itself, but wait we have Docker already with us and we know the containers running are very lightweight processes.

Follow the steps in order to set up your Jenkins inside docker,

1. First lets create a dockerfile

FROM jenkins/jenkins:latest
USER root
RUN curl -sSL https://get.docker.com/ |sh
USER jenkins

We have to use the Docker daemon of the host in order to run docker commands inside the Jenkins which is already running as a container in the docker. This is something we say running Docker in Docker!

Lets see what we are getting from the dockerfile

  • temporarily switched to the root user to install Docker
  • run a Docker install script
  • switch back to the Jenkins user

2. Build an image with the dockerfile

docker build -t myjenkins . 

3. Start Jenkins by running this command

 docker run --rm --group-add 0 -v "/var/run/docker.sock:/var/run/docker.sock" -v “jenkinsvol:/var/jenkins_home” -p 8080:8080 --name jenkins myjenkins

Here we are mounting a volume to allow access to the Docker socket, /var/run/docker.sock

What is /var/run/docker.sock ?

Note: Bind mounting the Docker daemon socket gives a lot of power to a container as it can control the daemon. It must be used with caution.

  • The other volume is to persist the work what we will be doing inside the Jenkins.
  • Now you can see Jenkins up and running on localhost:8080 in your browser.
Unlock Jenkins
  • You can get the password from the terminal once Jenkins is up and running or can move to the specified path using the docker exec command.
Jenkins Password
  • Put the password and click continue
  • Click on suggested plugin to be installed.This will take a while.
Install Jenkins Plugins
Install Jenkins Plugins
  • Create a user with a password that will be used to login to Jenkins or skip and continue with admin credentials. Click next and there you can see Jenkins home page.
Create Admin User

Creating a new Pipeline Project

  • Click on New Project.
  • Give a project name Myapp and select the Pipeline project.
  • Go Down in Pipeline section, here we have two options in definition, Pipeline Script or Pipeline script from SCM. Select Pipeline Script.

Lets see the stages of the pipeline:

  1. First of all it should be able to pull the source code from the specified repository.

2. Next is to build the source code pulled in stage 1. Here we will build a docker image from the dockerfile which is present in the root directory of the source code repo.

Sample dockerfile for a nodejs application :

FROM node:alpine
# set working directory
WORKDIR /app

# add `/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:$PATH

# install app dependencies
COPY package.json ./
COPY package-lock.json ./
RUN npm install

# add app
COPY . ./

EXPOSE 3000
# start app
CMD ["npm", "start"]

Now to build docker image and to execute any shell command one can use sh ‘your command’

sh 'docker build -t localhost:5000/myimage .'

Here I am using a local registry to push my build images(artifacts) and hence tagged like localhost:5000/your_image_name. To create a local registry run the following command in command prompt

docker run -d -p 5000:5000 –restart=always –name registry registry:2

You can tag your image with username/your_image_name if you want to push your image into the docker hub registry.

  1. Next stage is to push your image into the registry of your choice using docker push
  2. The last stage is to pull the image from the registry and run a container from it using docker run.

Dont worry about script! Copy Paste the following into the Script area.

node{
  stage("scm checkout"){
    git credentialsId: 'your repo credential', url: 'your git repo URL'
  }
  stage("building docker image"){
    sh 'docker build -t localhost:5000/myimage .'
  }
  stage("push image to registry"){
    sh 'docker push localhost:5000/myimage'
  }
  stage("deploying through cotainer"){
    sh 'docker stop nodeapp || true && docker rm nodeapp || echo "not found"'
    sh 'docker run -p 8087:3000 -d --name nodeapp localhost:5000/myimage'
  }
}

You can use Pipeline Syntax option as per need in various stages.

If you want to see a practical demo of pipeline script in Jenkins, you can have a look at the below video from Java Home Cloud YouTube Channel

How to use Pipeline Syntax to generate the pipeline script’s command?

  • Click on pipeline syntax. Select the sample step as git:Git.
  • Enter repository URL, branch master. Add the repository Credentials, so that it will be able to pull the code.
  • Click on Generate Pipeline Script. Copy it.
  • Replace the stage one command with the one you got above.

Note :

  1. In stage 4 you need to check from the second time when you run the build, if the container exists first you need to stop and remove it then only you can run the container with the same name.
  2. Change/modify your image name with whatever you want in the above script
  3. Make sure indentation is maintained throughout the script as above.

Save the project and click on Build Now from left panel.

You can see the building of the application stage by stage and finally deploying into a container.

CI/CD Pipeline

Go to your browser check for the app with localhost:8082 and there it is!(use the port specified while running the container in last stage).

All Done!

Hold on, as we understood the CI/CD process is an automated one, but here we are building the pipeline manually as of now by clicking Build Now in Jenkins.

We want to start the process as when some pushed/merged code into main branch of our code repository.

To achieve this we will use “webhook” which will trigger the process to start whenever we push our codes.

Webhook

For this go to your repository’s git platform .

  • Under settings check for webhooks. Click on Add webhook
  • In payload URL enter, https://your_jenkins_url/
  • For Github append github-webhook/ at the end of above URL
  • Select content type as application/json and events which will trigger the webhook as Just the Push event.
  • Save/update the webhook and you will see a green tick, which says the webhook is working fine.
  • Go to Jenkins, configure your project and under, build trigger select “Github hook trigger for Githubscm polling and save it” .

So if you want to make localhost:8080 expose to the internet then you can use ngrok

Now modify/add some code in the application and push it your repository .

Go to Jenkins and you will see new build has been trigged and can see the pipeline in action.

Now its done!

You got your first CI/CD pipeline ready and running.

Pro tips:

What we have done above is created a script into Jenkins. You can create the same script locally through editors like the visual studio and save it is as Jenkinsfile.

In this case, you have to select the Definition as Pipeline script from SCM in project configuration in Jenkins. Then provide a git repo URL and credentials. Next, you have to tell where your Jenkinsfile is located into the Script path. Save and you can the same action whenever someone pushes some code in the repo.

In this way you can configure the Pipeline script without going to Jenkins .

You can share your feedbacks,suggestions or ask a question in case of any doubt.

Thanks for having your time! Happy learning 🙂

Frequently Asked Question(FAQ)

What is a cicd pipeline?

In the modern-day software development life cycle, the CICD pipeline acts as a bridge between development and operation activities. It is a process of automating, continuous integration of your code followed by testing which will be further followed by continuous delivery/deployment.

Is Docker a cicd tool?

The benefits and use cases of Docker have made it a must-have tool in cicd process. One can focus on application development irrespective of the environment where the app will be deployed. Build, Ship, Run is the motto Docker follows.
The heck of where it went wrong? when deploying any application to other environments with the fact it was running fine in the developer’s machine has flown away with the arrival of Docker.

You may also like...

7 Responses

  1. Hadiuz Zama says:

    Very Well Explained!!

  2. Ansu Antony says:

    Thanks

  3. Aman says:

    Great stuff

  4. Priya says:

    Easy step by step explanation. Thanks for a basic understandable content 👍