Jenkins Pipeline to Create Docker Image and Push to Dockerhub
By: Brandon Jones
Tags: Jenkins, Jenkins Pipeline, Dockerhub, Jenkinsfile, Docker

Recently, I have been spending some time learning Jenkins and automating tasks. I wanted to figure out a way to create a pipeline which pulled from a Github repo, created a docker image, and pushed the image to Dockerhub. I was unable to find a guide that walked users through this simple task and ended up piecing together several posts to complete the task. As a Jenkins newbie this can be frustrating so I wanted to create a blog post which walked users through the process. All the code for this can be found at the repo here.

The project I turned into an image was just a simple Angular application. I literally just ran the ng new <new-project-name> command and used that for my test pipeline project. This Jenkinsfile should work for any project that you have a Dockerfile for and able to create an image. I’ve used this method for express projects too, just using different Dockerfiles.

First just create the Angular project…

ng new <new-project-name>

Once you have the angular project created, you’ll need to create a Dockerfile for the image. You can find mine here… Make sure to place the Dockerfile within the root directory of the project. The Dockerfile is pretty straightforward, but I can walk you through how it works. The FROM command is using node as the base for the image which the entire application is built. The RUN mkdir -p /app creates an app directory and WORKDIR indicates this is where the application will be created. COPY copies the package.json files into the working directory and RUN npm install installs all the dependencies located in the package.json file. The remaining files are copied over using the COPY command. Since it’s an angular application, port 4200 is exposed and the CMD npm run start command is run to start the application.

To test the Dockerfile, move into the root directory of the project and run the command “docker build .” and don’t forget the ‘.’ at the end. This indicates there is a Dockerfile found in the current directory. The output should be like mine below. If there are any errors something is most likely wrong with the Dockerfile.

FROM node:latest as node

RUN mkdir -p /app

WORKDIR /app

COPY package*.json /app/

RUN npm install

COPY . /app/

EXPOSE 4200

CMD ["npm", "run", "start"]

Output from docker build . command

The Jenkins pipeline depends on a Jenkinsfile and you can find mine here. Jenkins files can be pretty complex, but I kept mine very simple for learning purposes. The Jenkinsfile is divided into 4 stages, a clone, build, test, and push stage. The clone stage checks out the repo from github. The build state builds the image and stores it in a variable named ‘app’. Be sure to change ‘brandonjones085’ to which Dockerhub repo you’d like to push the image to. I left the Test stage in the file as a placeholder for future unit tests. At this point, the logs will just echo ‘Tests’. Finally, the image is pushed to Dockerhub with the ‘latest’ tag and using the stored ‘git’ credentials. Create this file in the same root directory as the Dockerfile that was previously created.

Once you have the Jenkinsfile created, create a Github repo and push the entire project to the repo.

node {

def app

stage('Clone repository') {



checkout scm

} stage('Build image') {



app = docker.build("brandonjones085/test")

} stage('Test image') { app.inside {



sh 'echo "Tests passed"'

}

} stage('Push image') {

docker.withRegistry('https://registry.hub.docker.com', 'git') { app.push("${env.BUILD_NUMBER}")

app.push("latest")

}

}

}

Now we can begin working in Jenkins and creating the project. I’m assuming you already have a Jenkins server installed and running. First, let’s add the Dockerhub credentials in Jenkins. These credentials will be used to log into Dockerhub. Click Manage Jenkins, then Manage Credentials.

Manage Credentials

Global

Click global, then Add Credentials to add a new credential with a Global Scope.

Enter Credentials

Add your Dockerhub username and password. The ID is was is used in the Jenkinsfile and your credentials are stored and you can see this used in the Jenkinsfile.