If you’ve worked with Docker even for a little bit, I bet you’ve come across tags. They often look like “my_image_name:1” where the part after the colon if known as that tag. It’s not always specified when tagging images, we’ll get to the bottom of that later.
Ever since I started using Docker, I’ve been very confused about tags. The docs don’t help in understanding them. Neither are there thorough explanations on the topic. Which is why I decided to write this post.
So…what exactly are tags? In simple words, tags are just aliases to the ID of your image which often looks like this:f1477ec11d12. It’s just a way of referring to your image. A good analogy is how git tags refer to a particular commit in your history.
The two most common cases where tags come into play are:
- When building an image, we use the following command:
docker build -t username/image_name:tag_name .
Let’s try to unpack what this command does for a bit. We tell the Docker daemon to fetch the Docker file present in the current directory (that what the .at the end does). Next, we tell the Docker daemon to build the image and give it the specified tag.ow, if you run docker images, you should see an image whose repository is username/image_name and tag is tag_name.
username/image_name is not a mandatory format for specifying the name of the image. It’s just a useful convention to avoid tagging your images again when you need to push it to a registry. Your image can be named anything you want. For the public Docker registry, you’re restricted to a two-level hierarchy while naming images, i.e., your image cannot have the name a/b/c:1. This restriction usually doesn’t exist in private registries. As stated before, it’s not mandatory to specify a tag_name. We’ll see what happens in that case soon.
- Explicitly tagging an image through the tag command:
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
This command just creates an alias (a reference) by the name of the TARGET_IMAGE that refers to the SOURCE_IMAGE. That’s all it does. It’s like assigning an existing image another name to refer to it. Notice how the tag is specified as optional here as well, by the [:TAG] .
Alright, now let’s uncover what happens when you don’t specify a tag while tagging an image. This is where the latest tag comes into the picture. Whenever an image is tagged without an explicit tag, it’s given the latest tag by default. It’s an unfortunate naming choice that causes a lot of confusion. But I like to think of it as the default tag that’s given to images when you don’t specify one.
A lot of confusion around latest is caused due to the expectation that it’s the latest version of the image, especially in Dockerfiles. Let’s consider the various scenarios with an example:
Suppose we’ve the following statement in our Dockerfile:
Since we don’t specify any tag, Docker will add the latest tag and try to pull the imagfe debian:latest .
Since the tag is explicitly mentioned here, Docker will pull the Debian image tagged 9.3
Another thing to keep in mind is that there is no rule which states that an image needs to have just one tag. An image can have multiple tags and they’re usually used to specify major and minor versions. For example, consider this:
At the time of writing of this post, the latest tag for the Debian image points to the 9.3 release AND the 9 release. This will most likely change in the future whenever the major or minor version is bumped for the image.
Please note that tags being used for semantic versioning is a convention that’s followed, but tags weren’t designed just for that purpose.
The main takeaway from what we’ve covered so far is that: latest is just like any other tag. The onus is on the developer to tag the images properly such that latest always points to the latest stable release of the image.
Hence, if don’t explicitly specify a tag in our Dockerfiles when pulling images, the next time we pull our image, we might end up with a completely different version of the base image that what we had used before. There are no guarantees about whether it’ll be a major bump or minor bump. Even an old release can be tagged as latest.
P.S. — If you find any misconceptions/errors in the post, please feel free to tweet to me @ScribbingOn.
Thanks to Jérôme Petazzoni for helping me make sense of some of this.
(open source and trusted by devs everywhere ❤️)