Docker build/push with declarative pipeline in Jenkins

Docker build/push with declarative pipeline in Jenkins

Table of contents

No heading

No headings in the article.

Here is a quick and full example to build a docker image from private GitHub repo and push to docker hub with declarative pipeline in Jenkins.

I created a sample repo with basic Dockerfile and Jenkinsfile

$ cat DockerfileFROM ubuntu:20.04
RUN apt update && apt upgrade -y

Configure Jenkins

Ensure that you installed docker engine on Jenkins instance and git, docker plugins

Install Docker-CE on Ubuntu 18 from https://docs.docker.com/engine/install/ubuntu/

After that, allow Jenkins users to access the docker socket.

sudo usermod -aG docker jenkins
sudo systemctl restart jenkins

Test your docker access with Jenkins user

$ sudo su - jenkins
$ docker psCONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

Create credentials on Jenkins for GitHub and docker hub

To create a GitHub credentials we need to create a token. Check the following URL to create a personal API Token

https://support.cloudbees.com/hc/en-us/articles/234710368-GitHub-Permissions-and-API-token-Scopes-for-Jenkin

To create a GitHub credentials go to Manage Jenkins->Manage Credentials(Under Security) click to Jenkins Store

Then click to Global credentials

Click Add Credentials on the left menu.

Choose Username and Password

Username is the GitHub user ID and Password is the personal API Token

Create another user and password credentials for Docker Hub login.

Create Webhook on Github

Go to the Settings->Webhook in your repo and add

Type your https://jenkinsURL/github-webhook/

WARNING!!!

Don’t forget to put / at the end of the URL! Otherwise you may lose some hairs until the figure out the issue :)

Choose Content-Type as application/json and choose Let me select individual events select Pull Requests and Pushes

Whenever you do a pull or push in the repo, Github will inform the Jenkins. Ensure that your Jenkins URL is accessible from Github.

Now time to configure Pipeline.

Click on New item and select pipeline

Give a name and select Pipeline

Enable GitHub hook trigger for GITScm polling at Build Triggers

And Configure Pipeline

Choose Definition Pipeline script from SCM
SCM: Git

Credentials: The one we created earlier. You can create the credentials in this section too.

Branch to build: This is just test build I chose the master origin/master

Script Path: Where you keep Jenkinsfile. We keep it in the repo base directory. If this is in the subpath, please specify here.

here is the content of the Jenkinsfile

pipeline {environment {imagename = "yenigul/hacicenkins"registryCredential = 'yenigul-dockerhub'dockerImage = ''}agent any
stages {
stage('Cloning Git') {
steps {git([url: 'https://github.com/ismailyenigul/hacicenkins.git', branch: 'master', credentialsId: 'ismailyenigul-github-user-token'])}}stage('Building image') {steps{script {dockerImage = docker.build imagename}}}stage('Deploy Image') {steps{script {docker.withRegistry( '', registryCredential ) {dockerImage.push("$BUILD_NUMBER")dockerImage.push('latest')}}}}stage('Remove Unused docker image') {
steps{
sh "docker rmi $imagename:$BUILD_NUMBER"
sh "docker rmi $imagename:latest"
}
}
}
}

You can download this file from gist

Just update something in the repo and push the changes

git add  . ; git commit -m "jenkins test" ; git push

and here are the logs

Started by GitHub push by ismailyenigul
Obtained Jenkinsfile from git https://github.com/ismailyenigul/hacicenkins.git
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in /jenkins/workspace/Github-pipeline-test
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Declarative: Checkout SCM)
[Pipeline] checkout
using credential ismailyenigul-github-user-token
 > git rev-parse --is-inside-work-tree # timeout=10
Fetching changes from the remote Git repository
 > git config remote.origin.url https://github.com/ismailyenigul/hacicenkins.git # timeout=10
Fetching upstream changes from https://github.com/ismailyenigul/hacicenkins.git
 > git --version # timeout=10
 > git --version # 'git version 2.17.1'
using GIT_ASKPASS to set credentials ismailyenigul-github-user-token
 > git fetch --tags --progress -- https://github.com/ismailyenigul/hacicenkins.git +refs/heads/*:refs/remotes/origin/* # timeout=10
 > git rev-parse refs/remotes/origin/master^{commit} # timeout=10
 > git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=10
Checking out Revision 1dea626998dc25e33cc23245141a606aa880b50e (refs/remotes/origin/master)
 > git config core.sparsecheckout # timeout=10
 > git checkout -f 1dea626998dc25e33cc23245141a606aa880b50e # timeout=10
Commit message: "jenkins test"
 > git rev-list --no-walk b95e729ab1cbde17a2355a1b50f5226d4df66f64 # timeout=10
[Pipeline] }
[Pipeline] // stage
[Pipeline] withEnv
[Pipeline] {
[Pipeline] withEnv
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Cloning Git)
[Pipeline] git
using credential ismailyenigul-github-user-token
 > git rev-parse --is-inside-work-tree # timeout=10
Fetching changes from the remote Git repository
 > git config remote.origin.url https://github.com/ismailyenigul/hacicenkins.git # timeout=10
Fetching upstream changes from https://github.com/ismailyenigul/hacicenkins.git
 > git --version # timeout=10
 > git --version # 'git version 2.17.1'
using GIT_ASKPASS to set credentials ismailyenigul-github-user-token
 > git fetch --tags --progress -- https://github.com/ismailyenigul/hacicenkins.git +refs/heads/*:refs/remotes/origin/* # timeout=10
 > git rev-parse refs/remotes/origin/master^{commit} # timeout=10
 > git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=10
Checking out Revision 1dea626998dc25e33cc23245141a606aa880b50e (refs/remotes/origin/master)
 > git config core.sparsecheckout # timeout=10
 > git checkout -f 1dea626998dc25e33cc23245141a606aa880b50e # timeout=10
 > git branch -a -v --no-abbrev # timeout=10
 > git branch -D master # timeout=10
 > git checkout -b master 1dea626998dc25e33cc23245141a606aa880b50e # timeout=10
Commit message: "jenkins test"
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Building image)
[Pipeline] script
[Pipeline] {
[Pipeline] isUnix
[Pipeline] sh
+ docker build -t yenigul/hacicenkins .
Sending build context to Docker daemon  182.8kB

Step 1/2 : FROM ubuntu:20.04
 ---> 1e4467b07108
Step 2/2 : RUN apt update && apt upgrade -y
 ---> Using cache
 ---> 2b6d31a5bc9c
Successfully built 2b6d31a5bc9c
Successfully tagged yenigul/hacicenkins:latest
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Deploy Image)
[Pipeline] script
[Pipeline] {
[Pipeline] withEnv
[Pipeline] {
[Pipeline] withDockerRegistry
$ docker login -u yenigul -p ******** https://index.docker.io/v1/
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /jenkins/workspace/Github-pipeline-test@tmp/00168e58-b69d-40c3-8308-3a3f5648bb84/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
[Pipeline] {
[Pipeline] isUnix
[Pipeline] sh
+ docker tag yenigul/hacicenkins yenigul/hacicenkins:4
[Pipeline] isUnix
[Pipeline] sh
+ docker push yenigul/hacicenkins:4
The push refers to repository [docker.io/yenigul/hacicenkins]
ac803a9a305b: Preparing
095624243293: Preparing
a37e74863e72: Preparing
8eeb4a14bcb4: Preparing
ce3011290956: Preparing
095624243293: Layer already exists
a37e74863e72: Layer already exists
8eeb4a14bcb4: Layer already exists
ac803a9a305b: Layer already exists
ce3011290956: Layer already exists
4: digest: sha256:72e91529ef0f3a4c43ec27db780e017ba7234ef5c2846fc619769e97be00e526 size: 1364
[Pipeline] isUnix
[Pipeline] sh
+ docker tag yenigul/hacicenkins yenigul/hacicenkins:latest
[Pipeline] isUnix
[Pipeline] sh
+ docker push yenigul/hacicenkins:latest
The push refers to repository [docker.io/yenigul/hacicenkins]
ac803a9a305b: Preparing
095624243293: Preparing
a37e74863e72: Preparing
8eeb4a14bcb4: Preparing
ce3011290956: Preparing
ac803a9a305b: Layer already exists
a37e74863e72: Layer already exists
095624243293: Layer already exists
ce3011290956: Layer already exists
8eeb4a14bcb4: Layer already exists
latest: digest: sha256:72e91529ef0f3a4c43ec27db780e017ba7234ef5c2846fc619769e97be00e526 size: 1364
[Pipeline] }
[Pipeline] // withDockerRegistry
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Remove Unused docker image)
[Pipeline] sh
+ docker rmi yenigul/hacicenkins:4
Untagged: yenigul/hacicenkins:4
[Pipeline] sh
+ docker rmi yenigul/hacicenkins:latest
Untagged: yenigul/hacicenkins:latest
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

Extra: Build a Docker image with the Docker plugin with Free Style project

If you want to build a docker image without writing pipeline, you can create FreeStyle project with Docker Plugin. You need to configure Docker in Nodes section of the Jenkins
Go to Manage Jenkins -> Manage Nodes and Clouds -> Configure Clouds-> Add New Cloud.

Select Docker here.

Type unix:///var/run/docker.sock for Docker Host URI and Click Enabled Then save

And here is the build spec for Free Style project

At Add Build Step Select Build / Publish Docker Image

and fill the form

Here is another example if you want to push docker images to AWS ECR repo.

You need to install aws ecr plugin and create a new credentials with AWS Credentials kind(ismail-ecr in my tests)

I am Sunil kumar, Please do follow me here and support #devOps #trainwithshubham #github #devopscommunity #devops #cloud #devoparticles #trainwithshubham

sunil kumar

Shubham Londhe

Connect with me over linkedin : linkedin.com/in/sunilkumar2807