Building Docker images to Docker Hub using Jenkins Pipelines
Tags: docker, tutorial, jenkins, devops
Published: 2020-04-09 12:49:57

**Jenkins Pipeline** is a powerful tool when you are using Jenkins to automate your deployments. Flexible and customized actions split between stages are a good reason to try this feature.Building your own Docker Image and upload to Docker Hub to keep your repository updated is a good example to understand how Jenkins Pipelines can improve your way of work.

#Prerequisites#

* A server with Jenkins and Docker running on it (Jenkins user should be allowed to run Docker).
* Github account.
* Docker hub account.

#Setting up your environment#

Install the [Docker Pipelines plugin](https://docs.cloudbees.com/docs/admin-resources/latest/plugins/docker-workflow) on Jenkins: 

**Manage Jenkins → Manage Plugins**.

Search Docker Pipelines, click on *Install without restart* and wait until is done.  

Upload your Dockerfile definition to your Github repository. Click on the green button *Clone* or *Download* and copy the URL as you will need it later.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/5j4neuacdnzvhlbp1fdf.png)

On Jenkins you need to create a new credential with your Docker Hub account details. Go to **Credentials → Global → Add** credentials and fill out the form with your username and password. Fill in ID and Descriptions. Note that if you set the ID, you will need this specific ID to refer this credential from your scripts. Here we are just using *dockerhub_id*.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/a4pnp1gvq5d62llfne6z.png)

#Creating your first Jenkins Pipeline#

Now, we are ready to create our first **Pipeline**. On Jenkins go to  **New Item → Pipeline**, type the name you want for this Pipeline project and then click OK.


![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/x13mck2jrg8hl71rtk7k.png)


Following that you can skip all *General* and *Build Trigger* options and go straight to the *Pipeline* section. Here you can include a Pipeline definition (usually named Jenkinsfile) or you can refer to an external location like Git or Subversion. 

The Pipeline we are defining have four stages: 
* The first one is to get the Dockerfile from our Github repository,
* The second one will build the image using `$BUILD_NUMBER` to tag the version,
* The third one is pushing the built image to your Docker Hub registry.

Please note you need to modify the code with your specific Docker Hub and Github details:

```
pipeline {
environment {
registry = "YourDockerhubAccount/YourRepository"
registryCredential = 'dockerhub_id'
dockerImage = ''
}
agent any
stages {
stage('Cloning our Git') {
steps {
git 'https://github.com/YourGithubAccount/YourGithubRepository.git'
}
}
stage('Building our image') {
steps{
script {
dockerImage = docker.build registry + ":$BUILD_NUMBER"
}
}
}
stage('Deploy our image') {
steps{
script {
docker.withRegistry( '', registryCredential ) {
dockerImage.push()
}
}
}
}
stage('Cleaning up') {
steps{
sh "docker rmi $registry:$BUILD_NUMBER"
}
}
}
}
```

#Run your Pipeline and build Images#

Now we are ready to run the Pipeline and check the output if an error is present on any stage during the run.
Go to your Pipeline project on Jenkins and click on **Build Now** to run manually. You should get a sequential output of the different stages similar to this one:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/yk68g2kr07j2zp7om2y3.png)

If everything is fine, you can check your Docker Hub repository for a new image tagged with the Jenkins build version matching with your Docker Hub registry:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/14wgohqe2ejz0eeixl0u.png)

This was a basic example of how to work with Pipelines and integrate different components of your deployments. There are possibilities of creating numerous complex integrations through Pipelines as you go ahead. 

Some ideas to go further with Jenkins:
* Define a webhook to run Pipeline when a commit is submitted to your Github repository.
* Include several containers in the same pipeline to keep different stages (like backend and frontend) or different environments (dev/prod)
* Set a notification by Email/Telegram/Slack with the status and/or output of your Pipeline.

As you can see, a lot of options are easily achievable. Just keep playing and getting deeper on Jenkins Pipelines Orchestration.