^ Thanks DALL·E for the “knitted docker whale”


  1. Avoid using the latest tag for your Docker images: This will lead to compatibility issues; always version pin using Semantic Versioning
  2. Use RC Docker tags for branches which aren’t main
  3. Use a task in your pipeline to check if the target Docker tag already exists in your Docker Container Registry
  4. Use a clean up task (repo: desholmes/acr-tag-deleter) in your CI/CD pipeline, or Docker Registry policies to keep your Docker Registry tidy

Clone the Open Source desholmes/ repo and follow the post below…


Knowing which strategy to use for generating Docker tags can be challenging. However, if you keep it closely aligned to a trunk-based git branching strategy you’ll save yourself a world of pain and you’ll have deployable, immutable infrastructure to “run anywhere” throughout your development cycle.

Simple feature branching strategy

The above shows a simple, trunk-based git branching strategy. It branches from main at version 1.0.0 and merges back into main as 1.1.0 after 4 commits.

Your repo will need a way of tracking the version, for Node.js you can use the package.json version, and for Python and Java you can use a file.

Let’s assume you have a CI/CD pipeline in place to run all of your quality control checks (lint, unit tests etc). Now, as well as running your tests, you’re also going to be building and pushing a Docker image to your Container Registry for each push to your remote.

Within the pipeline we’ll configure a Release Candidate (RC) build, using the target Docker tag version combined with the build number (ie: 1.1.0-rc.1 for the first build in your pipeline).

At the point of merging your git branch back into main you will build and push a Docker tag using 1.1.0, and run a clean up step to remove the associated RC tags from your Docker Container Registry.

Walking through the process

Clone the Open Source desholmes/ repo and follow along with the steps below.

Simple feature branching strategy

  1. Git branch feature/add-more-greetings is created locally from main and the version in package.json is bumped to 1.1.0
  2. We make the first commit and push to the remote
  3. The CI/CD pipeline builds a docker image 1.1.0-rc.10 (assuming there have been 9 previous pipeline executions to get version 1.0.0 merged into main)
  4. 3 more commits and pushes are made to the remote, these result in 1.1.0-rc.11, 1.1.0-rc.12, 1.1.0-rc.13 being built and pushed to the Docker Container Registry
  5. A pull request is raised and the branch is merged into main
  6. A CI/CD pipeline build is triggered resulting in 1.1.0 being built and pushed to the Docker Container Registry and a final task is executed in the CI/CD pipeline to remove RC builds 1.1.0-rc.10 - 1.1.0-rc.13 from the Docker Container Registry

Dealing with clashes

What if another developer is targeting my version? And… How can I make sure my tag isn’t already in my Docker Container Registry and will get over written?

This is the final piece of solution. Within your CI/CD pipeline your first task to will need to check if the Docker tag your are targeting (1.1.0 in the walk through above) already exists in your Docker Container Registry.

If it does your pipeline should fail and output a “The tag 1.1.0 already exists in the Container Registry, bump the version and try again.” message.

This will ensure you don’t Docker push over existing tags.

Popular related posts for Azure, Azure DevOps and CI/CD:

Related Posts