✦ For everyone, free.

Practical knowledge for real and everyday life

Home

19.1.4.2 Push Tag Selection

A focused guide to Push Tag Selection, connecting core concepts with practical Docker and container operations.

Tag selection is one of the most critical decisions when pushing Docker images to a registry. The tag you specify determines how the image is identified, versioned, and retrieved by other users or systems. A poorly chosen tag can lead to version confusion, unexpected upgrades, or broken deployments.

What a Tag Represents

A Docker image tag is a mutable pointer to a specific image manifest. When you push an image with a given tag, that tag in the registry is updated to point to the newly pushed manifest. Tags are appended to an image name using a colon:

docker push myregistry.example.com/myapp:1.4.2

If no tag is specified, Docker defaults to latest:

docker push myregistry.example.com/myapp
# equivalent to:
docker push myregistry.example.com/myapp:latest

Common Tagging Strategies

Semantic Versioning Tags

Semantic versioning (MAJOR.MINOR.PATCH) is the most widely adopted approach for production images. It communicates the nature of changes:

docker push myapp:1.0.0
docker push myapp:1.0.1
docker push myapp:2.0.0

You can also push multiple tags for the same image to provide coarse-grained aliases:

docker tag myapp:1.4.2 myapp:1.4
docker tag myapp:1.4.2 myapp:1
docker push myapp:1.4.2
docker push myapp:1.4
docker push myapp:1

This pattern allows consumers to pin to 1 (latest in major series), 1.4 (latest patch in minor series), or 1.4.2 (exact release).

The latest Tag

The latest tag is automatically assigned when no tag is specified. It is commonly used to represent the most recent stable build, but it comes with a significant caveat: it is mutable and provides no version history guarantee.

docker tag myapp:2.1.0 myapp:latest
docker push myapp:latest

Relying solely on latest in production environments is discouraged because:

  • Pulls of latest may retrieve different images at different times.
  • Rollbacks require knowing which previous tag to specify.
  • CI/CD pipelines lose traceability.
Git Commit SHA Tags

Tagging with a Git commit SHA creates an immutable, traceable identifier tied directly to source control:

GIT_SHA=$(git rev-parse --short HEAD)
docker tag myapp:build myapp:$GIT_SHA
docker push myapp:$GIT_SHA

This is common in CI pipelines where auditability matters. The image can be traced back to the exact code state that produced it.

Environment or Stage Tags

Some teams use tags to indicate deployment stage:

docker push myapp:dev
docker push myapp:staging
docker push myapp:production

This approach is convenient for internal workflows but carries the same mutability risk as latest.

Date or Build Number Tags

For systems where daily builds are relevant:

docker push myapp:20240615
docker push myapp:build-1042

These are easy to understand chronologically but do not convey compatibility or stability information.

Pushing Multiple Tags for the Same Image

A single image manifest can be referenced by multiple tags. After building an image, you assign additional tags before pushing each one:

docker build -t myapp:3.2.1 .

docker tag myapp:3.2.1 myapp:3.2
docker tag myapp:3.2.1 myapp:3
docker tag myapp:3.2.1 myapp:latest

docker push myapp:3.2.1
docker push myapp:3.2
docker push myapp:3
docker push myapp:latest

All four tags point to the same underlying image layers. Pushing them does not duplicate layer storage; the registry deduplicates layers by content digest.

Tag Naming Constraints

Docker tag names must comply with the following rules:

  • Maximum 128 characters.
  • Valid characters: letters (a–z, A–Z), digits (0–9), underscores (_), hyphens (-), and periods (.).
  • Must not start with a period or hyphen.
  • Case-sensitive: myapp:Latest and myapp:latest are different tags.

Invalid examples:

docker push myapp:my tag    # spaces not allowed
docker push myapp:.hidden   # cannot start with a period
docker push myapp:          # empty tag not valid

Overwriting an Existing Tag

Pushing to an existing tag silently overwrites it in the registry. The previous image manifest becomes untagged (a dangling manifest) but remains accessible by its digest:

docker push myapp:stable   # overwrites whatever stable pointed to before

To preserve the previous state, always create a new versioned tag before overwriting a mutable one.

Immutable Tags in Registries

Some container registries support immutable tag policies, which prevent overwriting a tag once it has been pushed. Amazon ECR, for example, allows enabling image tag immutability at the repository level. When enabled, attempting to push an image with an existing tag returns an error:

docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp:1.0.0
# Error if 1.0.0 already exists and immutability is enabled

This enforces a discipline of always incrementing versions before pushing, which improves deployment reliability.

Digest-Based References vs Tags

Beyond tags, Docker images can also be referenced by their content-addressable digest:

docker pull myapp@sha256:a1b2c3d4e5f6...

While digests are immutable and precise, they are not human-readable. The practical workflow is to push with a meaningful tag and optionally record the digest for strict pinning in deployment manifests.

Tag Selection in CI/CD Pipelines

Automated pipelines benefit from combining multiple tagging strategies simultaneously. A common pattern:

VERSION="1.5.3"
GIT_SHA=$(git rev-parse --short HEAD)
BRANCH=$(git rev-parse --abbrev-ref HEAD)

docker build -t myapp:$VERSION -t myapp:$GIT_SHA -t myapp:$BRANCH .

docker push myapp:$VERSION
docker push myapp:$GIT_SHA
docker push myapp:$BRANCH

This ensures that every push is traceable by version, commit, and branch simultaneously.