Jenkins Pipeline to Create Docker Image and Push to Dockerhub

Brandon Jones
The Startup
Published in
5 min readNov 4, 2020

--

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.

New Multibranch Pipeline Project

Now the pipeline is ready to be created. Go back to the dashboard and select new Item. Enter a name for the new item, select Multibranch Pipeline and click OK.

Enter a Display Name for the pipeline.

General Tab

Under Branch Sources, enter the Github repo URL and click Validate. Since this is a public repo, you won’t need to add any credentials, but if you’re using a private repo, you will need the credentials.

Branch Sources Tab

Under Build Configuration leave the default Jenkinsfile because this will look for the Jenkinsfile in the cloned repo.

Build Configuration

That’s it, click save and the project should begin running immediately.

The project will take a few minutes to run, but the initial output should look similar to mine.

Scan Repository Log

You can find the entire finished project here. It really is very simple to implement after you’ve finished the project once to see how everything works together. Everything here should be working, but we all know how that goes. If you run into any issues, feel free to reach out and I’ll try to help you work through the problem.

Automate the planet!

-Brandon

@brandon_jones08

--

--

Brandon Jones
The Startup

SysAdmin, Devops, Containers, Networks, Automation, Fiddle, Banjo, Pups