What's Wrong With The Docker :latest Tag?
For me, “latest” is an anti-pattern
Do not run any container with the latest tag. Been there, done that. Did not end very well.
Latest is a proliferating ball of confusion that should be avoided like a ravine full of venomous snakes
Docker images tagged with :latest have caused many people a lot of trouble.
But what exactly is wrong with the :latest tag? Should you avoid it completely when working with Docker images?
Let’s go over the most frequent misconceptions and ways in which the :latest tag can cause suffering - and how to avoid the :latest pain.
Latest is Just a Tag
The ‘latest’ tag does not actually mean latest, it doesn’t mean anything
Some people expect that :latest always points to the most-recently-pushed version of an image. That’s not true.
It’s just the tag which is applied to an image by default which does not have a tag. Those two commands will both result in a new image being created and tagged as :latest:
# those two are the same: $ docker build -t company/image_name . $ docker build -t company/image_name:latest .
Nothing magical. Just a default value.
Latest is Not Dynamic
So many people are not realizing that :latest is not dynamic
If you push a new image with a tag which is neither empty nor ‘latest’, :latest will not be affected or created.
$ docker build -t company/image_name:0.1 . # :latest doesn't care $ docker build -t company/image_name # :latest was created $ docker build -t company/image_name:0.2 . # :latest doesn't care $ docker build -t company/image_name:latest . # :latest was updated
If you are not pushing it explicitly, the :latest tag will stay the same.
Latest is Easily Overwritten By Default
Latest is however the default value, which makes it both vulnerable to human mistakes and concurrent usage patterns.
I’m weary of using latest on a team as I can see somebody forgetting to tag a build
Imagine your image building scripts are a bit off, or used incorrectly. Any developer who does not provide an image tag can overwrite the :latest image without meaning to.
Also, imagine the confusion which can be caused if you rely on :latest pointing to your most recent image, but another team member pushes their version in the meanwhile.
Latest is Not Descriptive and Hard to Work With
The Kubernetes docs are pretty clear on using Docker images with the :latest tag in production environments:
You should avoid using the :latest tag when deploying containers in production, because this makes it hard to track which version of the image is running and hard to roll back.
If you’re working with an image which is tagged with “latest”, that’s all the information you have apart from the image ID. Operations like deploying a new version of your app, or rolling back are simply not possible, if you don’t have two distinctly tagged images which are stable.
There’s no tool which will make it pleasant to deploy a “new :latest image” instead of the “old :latest image”.
Are You Really Using the :latest You Intended to?
The CI used the :latest tag […] suddenly and magically, people started having issues with their images
Depending on the tooling, you might be working with a stale image. Kubernetes is configured to always try to pull an image if it’s tagged with :latest. Even if a copy is already available.
Other tools might not be designed to be used with images which are updated while keeping the same label. This can cause confusion, complicated workflows and tricky bugs.
Is :latest Evil?
No. But it’s misunderstood and can be used poorly without much effort.
“Latest” is just another tag name, but vulnerable to sloppy mistakes by design and people are expecting too much of it.
If you’re a developer, are building images locally for your own consumption and are careful about it - :latest can be a reliable way to save effort and frustration. However, you should not use it for deployments as that practice will backfire badly, repeatedly and in many interesting ways.
If you’re looking for a way to tag your Docker images, a safe bet is to use the Git commit hash as the image tag. This way, you will be able to:
- Tell immediately what code version is running based on the image tag
- Roll back and deploy new versions of your app
- Avoid naming collisions among developers
- Make accidental overwrites harder to do
When using “moving tags”, use custom ones instead of :latest - :stable, :master or a shorter version of semantic versioning are nice examples. This way you can avoid default overwrites by accident. Make sure that your tools handle different images with the same tag well.
If you want to implement semantic versioning or moving tags, it’s best to do so in addition to the SHA-based tags - just push the same image with multiple tags. Make sure to be careful about pushing different images with the same tag - do your workflows account for it?
And finally, don’t use moving tags for permanent or production deployments. Try to be as precise and specific as possible about what is running to make operations predictable and reliable to save yourself from yet another painful :latest-esque experience.
You should always be explicit about versioning, otherwise things will break
Join the mailing list!
Subscribe to get notified about future articles and stay in touch via email.
I write about Django, Kubernetes, Docker, automation- and deployment topics, but would also like to keep you up to date about news around the business-side of things.