A Brief Overview of Docker Tags
I was digging into Docker tags recently, so I thought I’d share what I learned while it’s still fresh in my mind.
To set the stage, lets just run docker images
on a typical docker project, and see what we find:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 78a85c484f71 19 hours ago 193 MB
<none> <none> 30557a29d5ab 20 hours ago 193 MB
<none> <none> 5ed6274db6ce 24 hours ago 193 MB
It’s a bunch of docker images.
As you can see, each one has an Image ID, like 78a85c484f71
(which is a truncated version of the full ID). These IDs are unique and we can reference them in various commands, but they don’t tell us very much about the image. It would be better if we could reference images in a way that was more practical and human-readable.
Enter tags
A tag is a way to label an image with useful information for both humans and machines. You’ve probably seen tag names at the top of Dockerfiles, like this:
FROM postgres:9.6.1
The postgres:9.6.1
tag is just an alias for the underlying image ID, but it gives us more information about the environment we’re building. This tag is formatted as [repository]:[version]
, so it would be displayed like this when looking at our images:
REPOSITORY TAG IMAGE ID CREATED SIZE
postgres 9.6.1 77af4d6b9913 19 hours ago 265 MB
The full structure of a tag
There are many possible parts to a tag:
[registry-domain]/[user name]/[repository]:[version]
Some of these parts are optional. For example, these are all valid tag names:
my-registry.mydomain.com/bryanbraun/ruby:4.4.0
bryanbraun/ruby:4.4.0
- This one has no registry defined. If you attempt to push or pull this image, Docker will assume it goes to Docker’s own registry hub.docker.com
bryanbraun/ruby
- This has no version number, which is allowed.
bryanbraun/ruby:latest
- This references
:latest
, a special nickname assigned to some tags. More on this below.
- This references
ruby:4.4.0
- This has no user defined because it is from an “official repository” (ruby) in Docker’s own registry.
As you can see, one of the main reasons to tag images is to associate them with an image registry (like hub.docker.com or registry.gitlab.com). This gives our images the metadata needed to store them in the cloud.
Some registries support other tag name formats, like Gitlab, which provides a namespace so you can store multiple images per Gitlab repo.
Tagging our own images
Our own, custom-built images will be untagged by default, like this one from the list above:
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 78a85c484f71 19 hours ago 193 MB
We can tag it with the docker tag
command:
docker tag 78a85c484f71 registry.gitlab.com/bryanbraun/gridmaster:1.0.0
Now it looks like this:
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.gitlab.com/bryanbraun/gridmaster 1.0.0 78a85c484f71 19 hours ago 193 MB
As you can see, everything except the version number field is considered repository data, and displayed in the repository field.
What about :latest?
It’s common to see tags with the word :latest
taking the place of the version number (like ruby:latest
instead of ruby:4.4.0
). There are whole articles about :latest
because it’s not intuitive. In short, :latest
is a nickname assigned to the last built tag that was NOT given a version. If you explicitly give a version to a tag, it will never be identified as :latest
. It’s probably best to just use version numbers for your tags, instead of relying on :latest
.
At the end of the day, tags are there to help you identify Docker images and push or pull them from external registries. They’re a pretty fundamental concept, so I hope you found this overview useful.