Building a Docker image from a Dockerfile, creating a latest tag and pushing it on DockerHub are equivalent to executing three different commands manually. This could be automated by creating a bash script.
Well, that was not a big deal until I had a requirement where I needed to perform above actions and additional task of immediately triggering a “deployment job” already configured on Jenkins. The deployment job performs application deployment using recently updated Docker image on desired servers running in my pre-production environment. So I needed something with which I could perform my task through Jenkins rather than running commands/scripts on a shell. Since I am already using some Jenkins plugins in the current deployment job, so rather than creating a new deployment job I want to leverage the existing job.
In this quest, I came across a couple of Jenkins plugins provided by CloudBees which seemed perfect for this task. These plugins install “Docker Commons Plugin” which provides a base functionality for Docker related plugins.
CloudBees Docker Build and Publish plugin: It enables us to build images from the Dockerfile present on the server and publishing them on the DockerHub.
CloudBees DockerHub Notification: It enables us to trigger one or more Jenkins job by making use of DockerHub’s web hook, thus creating a continuous delivery pipeline. Whenever a new image is pushed, the configured Jenkins job will receive notification as web hook and triggers the job.
Scenario: One click automation of a process of building image from Dockerfile, pushing it on DockerHub and immediately triggering a Jenkins deployment job based on the pushed docker image.
- Installing Plugins:
Install the above two plugins using Jenkins’ “Plugin Manager”.
- Creating and configuring Jenkins job to build images from Dockerfile:
Create a new Jenkins job (say “Build Docker Image“) which will use CloudBees Docker Build and Publish plugin to build images from Dockerfile and push it on DockerHub.
Configure this job as follows under the build section:
Various fields in the above image are explained below:
- Repository Name: As shown we have passed “navjotsingh/custom-image” as the repository name.
- Tag: We are passing “v1.0” as tag or version. We can make this build parametrized and pass custom repository name and tag as two parameters to this job.
- Docker Host URI: Our Docker host is on the same machine where Jenkins is installed, so we are using default Docker ‘s default URI by keeping this field empty.
- Server credentials: Provide user’s credentials who has permission to run Docker commands and have permission to use Docker’s socket “/var/run/docker.sock”. I have provided permission to Jenkins’ user.
- Docker registry URL: We are using public DockerHub registry so we have left “Docker registry URL” field empty.
- Registry credentials: Click “Add” to add the DockerHub account credentials.
- As we can see there are various options provided by this plugin wherein we can choose to skip push, no cache, force pull and skip build.
- This plugin creates fingerprints after building image and are managed by Docker Commons Plugin (installed with this plugin).
- Decorating the build name means builds will be decorated with the repository name and tag name. We can skip it by checking “Skip Decorate” check box.
- Skip tag as latest: If it is unchecked, it will create additional tag “latest” of the currently build image and push it on DockerHub as can be seen in the above image.
- Docker Directory is in: The directory which contain the Dockerfile can be specified in this field otherwise it will try to fetch the Dockerfile from the Job’s workspace.
- Modifying existing Deployment Job to be triggered immediately after building image:
Now we will modify the existing deployment job which we need to be executed whenever that Docker image is updated. We will achieve it by using CloudBees Docker Hub Notification plugin.
Configure the deployment job under “Build Triggers” as follows:
Select “Monitor Docker Hub image changes”, under this select “Any referenced Docker image can trigger this job”. We can make this job to be triggered on specified repositories by selecting “Specified repositories will trigger this job” and specifying repository name against “Repositories” field. Multiple repositories can be specified in the text field, one repository per line.
Now, we have configured our deployment job to be triggered if any new image gets available in navjotsingh/custom-image repository.
- Configuring webhook in DockerHub:
Now, we need to configure webhook for our Jenkins server in the DockerHub as follows:
- Login to your DockerHub account.
- Select the repository which is “navjotsingh/custom-image” in our case.
- Click on “Webhooks” and then on “Add Webhook”.
- Provide your favourite Webhook name under “ Webhook Name” field (say Jenkins Webhook).
- Provide below URL under “Hook URL 0”.
- Click “Add URL” as shown below:
That’s all! We have completed the whole configuration to get our scenario working.
Summary: Upon our single click to start “Build Docker Image” job, as a new image will be created from provided Dockerfile and pushed on to DockerHub. The new image pushed on DockerHub will trigger webhook notification to Jenkins server and this will trigger our “Deployment Job” to perform the deployment based on this new Docker image.