How to Build a Docker Image from Github and push to Docker Hub using a Jenkins Job
Tags: devops, jenkins, docker, beginners
Published: 2024-05-26 22:26:13

Instead of manually building a docker image every time you make changes in your source code, you can build a Jenkins job that pulls the source code, builds the image, and publishes it to to docker hub. 

How do you achieve that? Let's find out

### 1. Setting up the DockerHub credentials on Jenkins
Jenkins will need the docker hub credentials to build and push the image to the docker hub. Instead of using dockerHub username and password, we will Create an Access Token in the dockerHub.
1. Log in to DockerHub
2. Click on the profile Icon and click on the Account settings

![Jenkins](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xig2b0jmgrukr3gziw13.png)
3.Click on the Security tab on the left menu, click on the "New Access Token and Enter a brief Description. After clicking the "Generate" button, click on the "Copy and Close" button. 

#### How to save the credentials on Jenkins 

On Jenkins navigate to add a global credential

![Jenkins](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/by9n6wou8t9czy416z8v.png)
Enter the details needed to create the credential and save

![Jenkins](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ay3q1xcpznx3tcdsv468.png)
### 2. Setting up the project on Github
If you don't have a project you can clone this https://github.com/Ericawanja/Jenkins-DockerHub-Automation

Delete the Jenkinsfile and Dockerfile to follow along
### 3. Setting up the Dockerfile
The docker file contains instructions on how to package the different computer pieces needed for a software application into a single package called an image. 

We will create a simplified Dockerfile which copies all files into a work directory. Since we're not accessing this application from a browser, we will not be exposing any port.

```groovy
FROM node:20-alpine 

WORKDIR /app

COPY . .
```

### 4. Creating and updating the Jenkins file
Create a Jenkins file on the root folder and follow along to update it

**Step 1: Logging in to Docker**

In the first step of the Jenkinsfile, we will log in to docker using with credentials() method which allows us to bind credentials into a pipeline script. Binding credentials using withCredentials method prevents exposing them  in the script or on the Jenkins console.

```groovy
stages{
        stage('Login') {
            steps {
                withCredentials([usernamePassword(credentialsId: 'dockerJenkinsID', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
                    
                   sh "docker login -u $USERNAME -p $PASSWORD"                  
                  
                }
            }
        }
```

- "usernamePassword" denotes the type of credentials.
- `credentialsId` is the ID of the credential stored in Jenkins
- `usernameVariable` and `passwordVariable` populate the username and password stored in Jenkins 

**Step 2: Building the docker image** 

Building a docker image is gathering all the artifacts needed for your software to run and packaging them so that the software can run anywhere.

To do so, the system uses a dockerfile which contains step-by-step instructions on how to build the image. Since we already have our dockerfile ready, we will be adding the command to trigger the image build.

```groovy
 stage('Build'){
            steps {
                sh 'docker build -t ericawanja/todoapp:latest .'
            }
        }
```

**Step 3: Pushing the image to the docker hub**

Dockerhub is a cloud-based repository built for finding, using, and sharing docker container images. We will our push the image to the docker hub to make it available for other developers to pull and use it.

```groovy
 stage('Push'){
            steps {
                //Deploy our app to DockerHub
               sh 'docker push ericawanja/todoapp:latest'
            }
        }
    }
```

**Step 4: Log out from Docker**

Logging out from service after logging in is a good security practice that prevents attacks such as session hijacking or unauthorized access.

We will log out from Jenkins in the "post" section which defines actions that are executed after the main stages in the Jenkins pipeline script have been completed.

The commands contained in the "always" block are executed every time the pipeline script runs regardless of the pipeline outcome.

```
 post {
        always {
            sh 'docker logout'
        }
    }
``` 
### 4. Creating and Running the Jenkins Jobs
In this step, we will create a Jenkins job that pulls the source code from GitHub and uses the Jenkins file to build and push the image to dockerhub.

Log in to Jenkins, click "+ New item" and select a pipeline Job type. Don't forget to enter the name before clicking the OK button.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5benaiqdbvi3qusspvuk.png)

Because we're using a Jenkinsfile, the pipeline script will be from SCM. I'm using a public GitHub repository, therefore I don't have to configure the credentials. Remember to change the branch to "main" or the branch name you want to build.

Finish setting the job and run it.

### Conclusion
Automation aims at saving time and effort. By building a Jenkins pipeline that pulls the source code changes, builds an image, and pushes it to docker, will save you time and effort spent doing that manually.