Introduction
Continuous Integration and Continuous Delivery highly fundamental topics in the software industry especially with the cloud and container technologies.
Container technologies such as Docker, Kubernetes, OpenShift and automation servers like Jenkins make easier to manage our projects workflow.
In this session we will pull sample Jenkins pipeline code from the GitHub repository and create jerkins pipeline using docker containers.
The processes we want to automate for this project:
- Code checkout
- Run tests
- Compile the code
- Run Sonarqube analysis on the code
- Create Docker image
- Push the image to Docker Hub
- Pull and run the image
Before We Begin
- Ubuntu 18.04 server with root or non-root user with sudo privileges
- Docker Installed
- Docker compose Installed
To know how to install Docker and Docker compose check out our previous tutorials sessions on Install Docker and Install docker-compose
Running up the services using docker-compose
Since one of the goals is to obtain the sonarqube report of our project, we should be able to access sonarqube from the Jenkins service. Docker-compose is the best choice to run services working together.
To learn more about sonarqube visit sonarqube official documentation
Create a folder named jenkins-pipeline-demo. We will configure our application services in docker-compose.yml in this folder as below :
Paths of docker files of the containers are specified at the context attribute in the docker-compose file. Content of these files as follows:
nano docker-compose.yml
version: '3.2' services: sonarqube: build: context: sonarqube/ ports: - 9000:9000 - 9092:9092 container_name: sonarqube jenkins: build: context: jenkins/ privileged: true user: root ports: - 8080:8080 - 50000:50000 container_name: jenkins volumes: - /home/jenkins:/var/jenkins_home - /var/run/docker.sock:/var/run/docker.sock depends_on: - sonarqube
We are using two Dockerfiles as below :
FROM sonarqube:lts #sonarqube/Dockerfile
FROM jenkinsci/blueocean #jenkins/Dockerfile
So now our Directory structure look like :
Note:We have two Dockerfiles (inside jenkins & sonarqube folder)
If we run the following command in the same directory as the docker-compose.yml
file, the Sonarqube and Jenkins containers will up and run.
sudo docker-compose -f docker-compose.yml up --build
You will get output look like :
Next check our created containers are running properly or not :
docker ps
We can see that both Jenkins and sonarqube containers are running on specified ports
Jenkins configuration
For this tutorial I am using local ubuntu machine and our jenkins container can be accessed as localhost:8084
To know how to Unlock Jenkins, Create admin user and Install suggested plugins visit our previous tutorials on How to install and configure Jenkins using Docker containers
Install Maven and Docker client on Jenkins
One of our main objective is , we must have the ability to build an image in the Jenkins being dockerized. Take a look at the volume definitions of the Jenkins service in the compose file.
- /var/run/docker.sock:/var/run/docker.sock
The purpose is to communicate between the Docker Daemon
and the Docker Client
(we will install it on Jenkins) over the socket. Like the docker client, we also need Maven
to compile the application. For the installation of these tools, we need to perform the Maven
and Docker Client
configurations under Manage Jenkins -> Global Tool Configuration menu.
Note: If you use Jenkins docker images other than blueocean like jenkins/jenkins:lts , sometimes Docker option unavailable on tool configuration. At that time you need to Install Docker plugin manually. So recommended way is to use jenkinsci/blueocean image
Install Dockerclient
Give name to our Dockerclient tool as myDocker and check the Install automatically
checkbox.
From the Add installer dropdown,select Download from docker.com.
Your Docker version will show as latest automatically as shown in below :
Install maven also by giving name as myMaven and selecting install automatically option with latest version
Save these settings by clicking apply& save .
These tools are installed by Jenkins when our script(Jenkins file) first runs.We will access these tools with this names in the script file.
Configure Docker hub and Git for Jenkins
In order to perform code checkout and pushing an image to Docker Hub we need to define their credentials on jenkins.These definitions are performed under Jenkins Home Page -> Credentials -> Global credentials (unrestricted) -> Add Credentials menu.
Give your Dockerhub account username ,password and specify ID as myDockerhubaccount.We need to specify this ID to Docker login in the script file.
Note: We will configure GitHub credentials during the Jenkins Job configuration steps. You can clone the jenkins-pipeline project from my repo https://github.com/rjshk013/jenkins-pipelinetest in your own Github account and configure in upcoming steps
Now, we will define pipeline under Jenkins Home Page -> New Item menu.
Give an item name as Jenkins-pipeline_demo -> select Pipeline project ->OK
In General section,Select Github project and give your Github repository for the project
Go to Pipeline section -> select the Pipeline script from SCM
as Definition, define the GitHub repository and the branch name, and specify the script location (Jenkins file).
Note:Configure your GitHub repository credentials in this step
Save the configuration by apply & save.
After that, when a push is done to the remote repository or when you manually trigger the pipeline by Build Now
option, the steps described in Jenkins file will be executed.
After successful build you can see the pipeline stage as :
Check docker image pushed into DockerHub
As jenkinsfile Docker image of our application will be pushed into DockerHub.I can see the newly created dockerimage named jenkins-pipelinedemo in my repositories
Check docker application is running on local machine:
Now check our newly created jenkins-pipeline demo application is running or not
docker ps
As you can see application is running on port 8090.Now check the application on the browser .You will get output look like :
Review important points of the Jenkins file
stage('Initialize'){
def dockerHome = tool 'myDocker'
def mavenHome = tool 'myMaven'
env.PATH = "${dockerHome}/bin:${mavenHome}/bin:${env.PATH}"
}
The Maven
and Docker client
tools we have defined in Jenkins under Global Tool Configuration menu are added to the PATH environment variable
for using these tools with sh command
.
stage('Push to Docker Registry'){
withCredentials([usernamePassword(credentialsId: 'dockerHubAccount', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
pushToImage(CONTAINER_NAME, CONTAINER_TAG, USERNAME, PASSWORD)
}
}
withCredentials
provided by Jenkins Credentials Binding Plugin
and bind credentials to variables. We passed dockerHubAccount value with credentialsId
parameter. Remember that, dockerHubAccount value is Docker Hub credentials ID we have defined it under Jenkins Home Page -> Credentials -> Global credentials (unrestricted) -> Add Credentials menu. In this way, we access to the username and password information of the account for login.
Sonarqube configuration
For Sonarqube
we have made the following definitions in the pom.xml
file of the project.
<sonar.host.url>http://sonarqube:9000</sonar.host.url> ... <dependencies> ... <dependency> <groupId>org.codehaus.mojo</groupId> <artifactId>sonar-maven-plugin</artifactId> <version>2.7.1</version> <type>maven-plugin</type> </dependency> ... </dependencies>
In the docker compose file, we gave the name of the Sonarqube service which is sonarqube
, this is why in the pom.xml
file, the sonar URL was defined as http://sonarqube:9000.
Conclusion
In this tutorial we learned how to dockerize a sample Jenkins pipeline application with docker compose and code from GitHub repository.