Docker uses tags to identify distinct versions of an image. In common with the broader container community, tags should be used to mark each release so users can select between different versions.

Tags may also be used to describe other characteristics of an image such as the identity of a key dependency when multiple options are offered. It’s not uncommon to find image vendors offering this kind of tag:

example-image:1.1.0-apache
example-image:1.1.0-nginx
example-image:1.2.0-apache
example-image:1.2.0-nginx

This tag scheme lets you pick between different versions of the image while offering either Apache or NGINX as the image’s base.

You can add your own tags to any image you build or pull. Local tags give you a way to quickly identify specific images in the future. In this guide, we’ll show how to manage image tags with the Docker CLI.

Adding Tags

Tags are added to images using the docker tag command. Tags can also be attached when you’re building an image with docker build by passing the -t flag.

The tag command takes two arguments: an existing tag identifying an image and a new “target” tag to assign to that image:

# docker tag <source image> <new tag>
docker tag example-image:1.1.0 example-image:1.1.0-apache

Both tags will now refer to the same image so you can start to use them interchangeably. However, running docker pull example-image:1.1.0 would not affect the 1.1.0-apache tag. A tag’s image reference isn’t updated unless you’ve manually included it in a CLI command.

The one exception to this rule is the often misunderstood latest tag. When you pull a “bare” image without a tag, such as docker pull example-image, Docker implicitly uses latest.

Untagged Images

The docker tag command will accept image IDs as the source reference instead of an existing tag. If you end up with an untagged image, run the docker images command to find its ID, then use docker tag to assign a new tag:

docker tag 0e3e06b48755 example-image:latest

It’s possible to have untagged images when you pull a new version of a tag:

# already has example-image:latest
docker pull example-image:latest

The original target of the example-image:latest tag still exists on your system but is now untagged. The pull downloaded the new image data and reassigned the latest tag to reference it.

Using Tags to Push Images

One situation where you need to add a new tag is when you’re pushing images between registries. The registry URL is part of the tag. Add a new tag that includes the registry you want to push to, then use docker push to upload it:

docker tag example-image:latest registry.example.com/example-image:latest
docker push registry.example.com/example-image:latest

Pushing a bare tag without a URL component will send the image data to Docker Hub. Consequently you must add a tag with your server’s hostname and optional port number when you’re interacting with a private registry.

Replacing and Modifying Tags

The docker tag command will silently replace a tag’s reference if an existing tag is used as the target:

docker tag first-image:latest demo
docker tag second-image:latest demo

The demo tag now refers to second-image and cannot be used to reference first-image. You can still interact with the first image using its remaining tag, first-image:latest. The second image can be selected with either second-image:latest or demo.

Image tags should generally be treated as immutable. This technique of modifying a tag’s reference is best avoided except for tags you’re using for local organizational purposes. It’s not a good idea to push an updated tag to a public registry as users depending on it will receive an unexpectedly modified image next time they pull. Push another new tag instead in this situation.

# Build and push v1
docker build -t example-image:v1 .
docker push example-image:v1

# v1 now refers to different image data
# This is fine for local use (tags in the 
# registry are independent of your local tags).
docker build -t example-image:v1 .

# Don't do this - now the tag in the registry
# has been changed too, which could negatively 
# impact existing users.
docker push example-image:v1

Removing Tags

You can remove tags from images that you’ve pulled to your machine. Use the docker rmi command, specifying the tag you’d like to delete:

docker rmi example-image:1.1.0-apache

Any other tags referencing the same image data will remain usable. In the event the referenced image would become untagged, the Docker CLI deletes the image data altogether. This ensures you don’t end up with untagged images as a result of explicit removal instructions.

Removing a tag only has an effect locally, even if you’re referencing a tag that includes a registry URL:

# Does not remove the tag from the registry!
docker rmi registry.example.com/example-image:latest

You can’t currently delete a specific tag from a registry. This is in keeping with the principle of tag immutability: once you’ve pushed content, it could be used as a dependency by downstream consumers, so the Registry API omits a tag deletion endpoint. However many third-party registry implementations do provide an equivalent mechanism; it’s worth checking the documentation for yours if you have a compelling reason to delete a pushed tag.

Summary

Tags are used to label Docker images with key distinguishing information such as their build version and included dependencies. Tags are much simpler to work with than the image SHA IDs which you can view with docker images. Tags are also the primary mechanism for interacting with images in remote registries.

You can manage your own tags on your local machine but changes will not affect registry content. You should also consider that although tags are mutable, this property should not be abused and is best avoided when pushing tags to a registry. This helps protect your users from unwanted breaking changes.

Profile Photo for James Walker James Walker
James Walker is a contributor to How-To Geek DevOps. He is the founder of Heron Web, a UK-based digital agency providing bespoke software development services to SMEs. He has experience managing complete end-to-end web development workflows, using technologies including Linux, GitLab, Docker, and Kubernetes.
Read Full Bio »