Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker: What are the best practices when tagging images for an environment

Tags:

I have multiple environments. They are debug, dev, and prod. I'd like to refer to an image by the latest dev (latest) or dev (version 1.1) or prod (latest). How would I go about tagging builds and pushes?

My first thought was to create separate repositories for each environment debug, dev, and prod. But I am starting to wonder if I can do this with just one repository. If its possible to do with one container what would the syntax be when building and pushing?

like image 719
Luke101 Avatar asked Jun 12 '17 22:06

Luke101


People also ask

Why you should pin your Docker images with Sha instead of tags?

By pinning the container version to a specific SHA you're trading off “avoiding potential build failures” for “getting potential security patches for free”.

Which of the following is the correct command to tag an image?

Which of the following is the correct command to tag an image? Options are : docker build tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG] docker tag TARGET_IMAGE[:TAG] SOURCE_IMAGE[:TAG]


2 Answers

This is what has worked best for me and my team and I recommend it:

I recommend having a single repo per project for all environments, it is easier to manage. Especially if you have microservices, then your project is composed by multiple microservices. Managing one repo per env per project is a pain.

For example, I have a users api. The docker repo is users. And this repo is used by alpha, dev and beta.

We create an env variable called $DOCKER_TAG in our CI/CD service and set it at the time the build is created, like this:

DOCKER_TAG: $(date +%Y%m%d).$BUILD_NUMBER => This is in bash.

Where $BUILD_NUMBER is previously set by the build being run when the CI/CD run is triggered. For example, when we merge a PR, a build is triggered, as build no. 1, so $BUILD_NUMBER: 1.

The resulting tag looks like this when used: 20171612.1 so our docker image is: users:20171612.1

Why this format?

  • It allows us to deploy the same tag on different environments with a run task.
  • It helps us keep track when an image was created and what build it belongs to.
  • Through the build number, we can find the commit information and map all together as needed, nice for trobleshooting.
  • It allows us to use the same docker repo per project.
  • It is nice to know when we created the image from the tag itself.

So, when we merge, we create a single build. Then that build is deployed as needed to the different environments. We don't create an independent build per environment. And we keep track on what's deployed where.

If there's a bug in an environment with certain tag, we pull such tag, build and trobleshoot and reproduce the issue under that condition. If we find an issue, we have the build number in the tag 20171612.1 so we know the build no. 1 has the issue. We check our CI/CD service and that tells us what commit is the most current. We check out that commit hash from git and debug and fix the issue. Then we deploy it as a hotfix, for example.

If you don't have a CI/CD yet, and you are doing this manually, just set the tag in that format manually (pretty much type the full string as is) and instead of a build number, use a commit short git hash (if you are using git):

20170612.ed73d4f

So you know what is the most current commit so you can troubleshoot issues with a specific image and map back to the code to create fixes as needed.

You can also define any other suffix for your tag that maps to the code version, so you can easily troubleshoot (e.g. map to git tags if you are using those).

Try it, adjust it as need it and do what it works best for you and your team. There's many ways to go around tagging. We tried many and this one is our favorite so far.

Hope this is of help.

like image 180
Juan Avatar answered Sep 20 '22 16:09

Juan


There's two schools of thought, stable tagging, where you update a single tag, and unique tagging. Each have their pros and cons. Stable tags can create instability when deploying to self healing clusters as a new node might pull a new version, while the rest of the cluster is running a slightly older version. Unique tagging is a best practice for deployment. However, to manage base image updates of OS & Framework patching, you'll want to build upon stable tags in your dockerfile, and enable automatic container builds. For a more detailed walk through, with visuals, here's a post: https://blogs.msdn.microsoft.com/stevelasker/2018/03/01/docker-tagging-best-practices-for-tagging-and-versioning-docker-images/

like image 44
Steve Lasker Avatar answered Sep 19 '22 16:09

Steve Lasker