Automate pushing multiple Docker tags into DockerHub with hooks/post_push

Sometimes you have a situation where you want to push multiple tags when you push a Docker Image to Docker Hub using the Docker Hub build automation.   We will override the default behavior to do this.

Video links related to this blog are available down below.

Default behavior

The default behavior is to build and push every time there is a change on master.  That auto-built  image is always tagged with :latest and pushed to the repository as :latest

Standard default build on master pushed with tag latest

Docker Hub supports overriding its build and deploy behavior with a set of hooks.

Pushing Multiple Tags to Docker Hub

This is the approach we will take
The following variables are available.
  • SOURCE_BRANCH: the name of the branch or the tag that is currently being tested.
  • SOURCE_COMMIT: the SHA1 hash of the commit being tested.
  • COMMIT_MSG: the message from the commit being tested and built.
  • DOCKER_REPO: the name of the Docker repository being built.
  • DOCKERFILE_PATH: the dockerfile currently being built.
  • DOCKER_TAG: the Docker repository tag being built.
  • IMAGE_NAME: the name and tag of the Docker repository being built. (This variable is a combination of DOCKER_REPO:DOCKER_TAG.)

hooks/build that applies multiple tags

This script builds a docker image tagged with version 5.5.1 and latest.  You have to tag this with latest because the default build definition, shown above, expects to push latest as it's last step.

I could have avoided hard coding my repository name by using ${DOCKER_REPO} in place of freemansoft/cp-server.  

The image must  include the latest tag if you use the default master branch build configuration. The  build will fail with a deployment failure if the image is not tagged with default.


TIMESTAMP=$(date +%Y%m%d%H%M%S)
echo "Basing this on kafka version: $CONFLUENT_VERSION and Jolokia version: $JOLOKIA_VERSION"
# Our version matches the Kafka version we build from
docker build \
--tag freemansoft/cp-server:$CONFLUENT_VERSION \
--tag freemansoft/cp-server:$CONFLUENT_VERSION-$TIMESTAMP \
    --tag freemansoft/cp-server:latest \
This build file could have used the $DOCKER_REPO in place of freemansoft/cp-server


This post_push file runs after Docker Hub has built the container and pushed it with a tag of latest. The script finds all of the tags that were applied at build time and pushes those tags to Docker Hub.


# only for local testing

# I'm hoping there are no old images hanging around in this area - let us see
echo "can see `docker images | tail -n +1`"

# find all the tags applied in the build - could be modified to ignore latest
# ignore the header line
for aVersion in $(docker images $DOCKER_REPO | tail -n +2 | awk '{print $2}' | grep -v "none")
echo "pushing $DOCKER_REPO:$aVersion"
docker push $DOCKER_REPO:$aVersion

Video Branch Build

Git Tag Driven Image Build and Deployment

A build can be triggered when the repository is tagged. Docker Hub build automation can detect a tag and trigger a build.

The following build definition pulls from master every time a semantic version is tag is applied. This means you can commit as much as you want and only deploy to Docker Hub by applying a tag is applied.
Tag driven build
You don't need to apply the :latest tag in this situation since Docker Hub will only try and push the semantic version tag as defined in the build rule.

Setting and pushing a tag to force a deployment

You can set a new tag with the following.  DockerHub will start the build when you push the tag
git tag -a <tagname>
git push --tags

You can move a tag with the following. It essentially force moves the tag and force pushes the tag to GitHub.  DockerHub will start the build when you push the tag
git tag -f -a <tagname>
git push -f --tags

Video - Tag Driven Image Deployment


Popular posts from this blog

Understanding your WSL2 RAM and swap - Changing the default 50%-25%

Installing the RNDIS driver on Windows 11 to use USB Raspberry Pi as network attached

DNS for Azure Point to Site (P2S) VPN - getting the internal IPs