A lot of companies use Docker to unify their build process. Here we show how to set up a Jenkins pipeline using Docker.

First follow my older post JENKINS ON MINIKUBE to get your own Jenkins instance running on minikube.

Simple test application

We need an application to test our Jenkins pipeline on. Let’s take a simple Java API using Spring. Here is the application I used on github.

Note locally we can use Maven 3.x and Java 8 to build the project. A Dockerfile is included to build an image.

FROM java:8
VOLUME /tmp
ADD target/java-spring-api-1.0.0-SNAPSHOT.jar app.jar
RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

To test your application locally use the following commands:

docker build -t java-spring-api .
docker run -p 8080:8080 java-spring-api
url http://localhost:8080

We have a running app on Docker!!

Dockerhub

Dockerhub is a public registry for docker images. Create an account on hub.docker.com if you didn’t have one already.

dockerhub welcome screen

If we want Jenkins to push our build docker image to dockerhub we need to store our dockerhub credentials on Jenkins. Go to Credentials -> (global) -> Add Credentials and fill in your dockerhub credentials. We can reference these credentials via the ID we give here.

jenkins credentials screen

The pipeline

One of the benefits of Jenkins (2.x) is that we can put our pipeline definition in code. Here is how we do this for our pipeline, found in the Jenkinsfilein our repository.

podTemplate(
label: 'slave-pod',
inheritFrom: 'default',
containers: [
containerTemplate(name: 'maven', image: 'maven:3.3.9-jdk-8-alpine', ttyEnabled: true, command: 'cat'),
containerTemplate(name: 'docker', image: 'docker:18.02', ttyEnabled: true, command: 'cat')
],
volumes: [
hostPathVolume(hostPath: '/var/run/docker.sock', mountPath: '/var/run/docker.sock'),
hostPathVolume(hostPath: '/root/.m2', mountPath: '/root/.m2')
]
) {
node('slave-pod') {
def commitId
stage ('Extract') {
checkout scm
commitId = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim()
}

stage ('Build') {
container ('maven') {
sh 'mvn clean install'
}
}

stage ('Docker build and push') {
container ('docker') {
def repository = "sybrenbolandit/java-spring-api"

withCredentials([usernamePassword(credentialsId: 'dockerhub',
usernameVariable: 'registryUser', passwordVariable: 'registryPassword')]) {

sh "docker login -u=$registryUser -p=$registryPassword"
sh "docker build -t ${repository}:${commitId} ."
sh "docker push ${repository}:${commitId}"
}
}
}
}
}

The first part (everything within podTemplate) is the way we declare which containers and volumes we need with the jenkins kubernetes plugin. Here we need a java-maven image to build the application and a docker image to build and push the docker image. As volumes we want 2 volumes to connect to the docker socket of the host machine and cache the maven dependencies.

Inside node, which refers to our pod template above, we define our build stages. These will be displayed in our Jenkins later. We follow our build stages we did locally.

In the Extractstage we checkout our code from github. The checkoutcommand is Jenkins functionality.

In the Buildstage we build our application inside the declared maven container.

In the Docker build and pushstage we build the docker image of our application in the declared docker container. Then we push to dockerhub where we refer to the dockerhub credentials saved in Jenkins.

Run!

Now Jenkins only needs to know about our fantastic pipeline. One the Jenkins homepage select Add new and select pipeline. Give it a name like java-spring-api and click Ok. Scroll down to the pipeline section and select Pipeline script from SCM than Git. Now put in our github reference with branch */blog/docker-on-jenkins and save.

jenkins pipeline

Our Jenkins pipeline is configured! Select Build now and Jenkins starts our pipeline. Note that is takes some time to instantiate the slave that will do all the work. But finally we see all bars green.

jenkins pipeline overview

Check the result

Select the build that just ran and go to Console output. At the bottom you will find something like this:

jenkins build output

The build was a success and the image was pushed with tag e78267c. On dockerhub we can see the image with the same tag.

pushed image dockerhub

Now everyone can pull this image and run our application:

Run output pulled docker container

Happy building!