Docker Hub is like Github for Docker images, making all our lives way easier.
Yet, it can quickly become a nightmare to maintaining multiple docker images. We don’t want to build the images manually each time we make a change to the Dockerfile. Also, we might want to support multiple variations of the same Docker image. For example, to support multiple node versions.
So good thing you’ve found this tutorial!
In the next few minutes, we will see how we can automate our builds by connecting our Docker Hub repo to a Github repo for automated builds. Finally, we’ll go deeper on the subject by exploring advanced options such as writing a build script that will give us complete control on the building process.
And you will then ascend to Docker Godhood!
Connecting a Github Repo to Docker Hub
The simplest way to automate your builds is to connect a Github repo containing a Dockerfile to your Docker Hub repo.
Here you can see I created a Github repo with a simple Dockerfile.
https://github.com/SamueleA/docker-hub-auto-build-tutorial
(ignore the build folder for now I will explain soon)
Now, that you have a Github repo go to Docker Hub, click on your repo and, in the build tab, click on Configure Automated Builds.
Then, select your repo, fill the form and…that’s it!
When you will push a commit to your Github repo, Docker Hub will detect the commit and build a new image from your Dockerfile.
But that is still limiting, isn’t it?
What about the situation in which I have this Dockerfile that depends on a node version and maybe I want to support ALL the node versions, not just one. Maybe we could specify the node version in the docker tag. Do I then need to create multiple Dockfile? It would be so much easier if there was a way to only modify one Dockerfile and have that Dockerfile generate all the images for all the node versions…
That’s where build hooks come in.
Hooks: Complete Control on the Build Process!
So our goal is simple. We’ll have one Dockerfile and we will want to have it specify the node version through the docker tag, then Docker Hub will generate all the builds based on the tags.
For instance, my-image:node-10 will use node 10, my-image:node-11 will use node 11 and my-image:latest will use the latest version available.
We will need a build hook for that. The build hook will replace Docker Hub’s build process with our own by running a bash script.
Let’s start by creating a folder called hooks and a file called build inside that folder, just like in my example repo. Then copy the following code in the build file:
#!/bin/bash
NODE_VERSION=$(echo $DOCKER_TAG | cut -d "-" -f2)
if [ $DOCKER_TAG == "latest" ]
then
docker build . --build-arg NODE_VERSION=${DOCKER_TAG} -t ${IMAGE_NAME}
else
docker build . --build-arg NODE_VERSION=${NODE_VERSION} -t ${IMAGE_NAME}
fi
Build is a script written in bash, hence the first line of code. It reads the environment variable DOCKER_TAG and figures out the node version specified (just like we said we would by formatting our Docker tag in the format my-image:node-VERSION).
This DOCKER_TAG variable is set by Docker Hub itself. You can find a list of all the other environment variables made available by Docker Hub here.
Then, there’s an if statement. Basically, it’s to deal with the case when the docker tag is latest. In that case, we’ll simply use the latest node version. In any case, depending on the docker tag, we are going to pass an argument to our build with the –build-arg flag.
Now, if you look at the Dockerfile in my Github repo:
ARG NODE_VERSION
FROM node:$NODE_VERSION
We are calling the variable NODE_VERSION which we’ve just set earlier with the docker build command inside our build script!
Now, in the build settings on Docker Hub, all I’ll have to do is to set the name of the Docker tags according to our convention and all my images will build automatically! I can support pretty much any node version without the headache of maintaining multiple Dockerfile!
And here is my Docker Hub repo, if you want to see the final builds: https://hub.docker.com/repository/docker/samueleago/auto-build-tutorial
As you can imagine, the limit is your imagination at this point. You can have your build script do whatever you envision it to do! And if you are an amazing Bash scripter… knock yourself out with the amazing control it gives you!!
Automate Away!
Hopefully, this tutorial was useful to you and you can now automate your Docker Images for your projects!
Automate! Automate! Automate!