Tagging, Versioning, and Registries
Every Docker image you build needs a name (tag) and a place to store it (registry). How you name your images determines whether you can trace a production issue back to a specific commit, roll back safely, or even tell which version is running. This lesson covers tagging strategies that make deployments predictable and auditable.
Image Naming Anatomy
A full image reference has this structure:
registry.example.com/team/app:1.4.2
└── registry ──────┘ └─ namespace ─┘ └ tag ┘
| Part | Example | Purpose |
|---|---|---|
| Registry | registry.example.com | Where the image is stored (Docker Hub if omitted) |
| Namespace | team/app | Organization and project grouping |
| Tag | 1.4.2 | Human-readable version label |
| Digest | @sha256:abc123... | Immutable content hash (assigned by registry) |
Tags vs Digests
This is the most important concept in image identification:
flowchart TD
A["Image Content<br/>(layers + config)"] -->|"content hash"| B["Digest: sha256:abc123..."]
B -->|"labeled as"| C["Tag: 1.4.2"]
B -->|"also labeled as"| D["Tag: stable"]
B -->|"also labeled as"| E["Tag: latest"]
F["New Image Content"] -->|"content hash"| G["Digest: sha256:def456..."]
G -->|"now labeled as"| H["Tag: latest ⚠️"]
style B fill:#e8f5e9,stroke:#2e7d32
style G fill:#fff3e0,stroke:#ef6c00
style H fill:#ffebee,stroke:#c62828
| Property | Tag | Digest |
|---|---|---|
| Format | app:1.4.2 | app@sha256:abc123... |
| Mutable? | Yes -- can be reassigned to different content | No -- always points to same content |
| Use for | Human-readable versioning | Exact artifact identification |
Key insight: Tags can lie. Someone can push a new image with the tag 1.4.2, and the tag now points to different content. Digests never lie -- the same digest always means the same image bytes.
Why latest Is Dangerous
The latest tag is not special or magical. It is just a default tag name that Docker uses when you do not specify one:
docker build -t app . # Tags as app:latest
docker pull nginx # Pulls nginx:latest
The problem: latest changes silently every time someone pushes without a version tag. You have no way to know which version is running, and no way to roll back to a specific latest.
Never use latest as a deployment target in production. Always use explicit version tags or digests.
Recommended Tagging Strategy
For every release, create at least two tags:
# Version tag: human-readable release identifier
docker build -t registry.example.com/app:1.4.2 .
# Commit tag: exact source code traceability
docker tag registry.example.com/app:1.4.2 registry.example.com/app:sha-abc1234
# Push both
docker push registry.example.com/app:1.4.2
docker push registry.example.com/app:sha-abc1234
| Tag Type | Example | Purpose |
|---|---|---|
| Semantic version | 1.4.2 | Human-readable release label |
| Commit SHA | sha-abc1234 | Trace image back to exact source code |
| Channel (optional) | stable, staging | Convenience pointer for environments |
The Promotion Workflow
Build once, promote the same artifact through environments. This ensures staging and production run identical code:
flowchart LR
A["CI Build"] -->|"Build + Tag"| B["Registry"]
B -->|"app:1.4.2"| C["Staging"]
C -->|"Tests Pass"| D["Tag as stable"]
D -->|"Same digest"| E["Production"]
style A fill:#e3f2fd,stroke:#1565c0
style C fill:#fff3e0,stroke:#ef6c00
style E fill:#e8f5e9,stroke:#2e7d32
# CI builds and pushes
docker build -t $IMAGE:$VERSION -t $IMAGE:sha-$GIT_SHA .
docker push $IMAGE:$VERSION
docker push $IMAGE:sha-$GIT_SHA
# After staging validation, promote to stable
docker tag $IMAGE:$VERSION $IMAGE:stable
docker push $IMAGE:stable
The key principle: the image that ran in staging is the exact same image (same digest) that runs in production. You never rebuild for production.
Working with Registries
Pushing an Image
# Log in to your registry
docker login registry.example.com
# Tag the image with the registry path
docker tag my-app:1.4.2 registry.example.com/team/my-app:1.4.2
# Push
docker push registry.example.com/team/my-app:1.4.2
Pulling an Image
# Pull by tag
docker pull registry.example.com/team/my-app:1.4.2
# Pull by digest (guaranteed same content)
docker pull registry.example.com/team/my-app@sha256:abc123...
Inspecting Remote Images
# View image details without pulling
docker manifest inspect registry.example.com/team/my-app:1.4.2
Versioning Strategies
| Strategy | Format | Best For |
|---|---|---|
| Semantic versioning | 1.4.2 | APIs and libraries where compatibility matters |
| Date-based | 2026.02.13 | Rolling releases with frequent deploys |
| Commit-based | sha-abc1234 | Maximum traceability, every build is unique |
| Hybrid | 1.4.2-sha-abc1234 | Human-readable version with source traceability |
Most teams should use semantic version + commit SHA as their standard tag set.
Rollback with Tags
When a deployment fails, you need to deploy the previous known-good version. This only works if:
- You have a tagged previous version (e.g.,
1.4.1) - That tag has not been overwritten with different content
# Roll back to previous version
docker pull registry.example.com/team/my-app:1.4.1
docker compose up -d
For maximum safety, record the digest of each deployment so you can pull by digest even if tags are moved.
Common Mistakes
| Mistake | Consequence | Fix |
|---|---|---|
Only using latest | Cannot identify what is running, cannot roll back | Always tag with version + commit SHA |
| No commit SHA tag | Cannot trace production issue to source code | Add sha-<shortsha> tag to every build |
| Overwriting release tags | Rollback goes to wrong version | Treat release tags as immutable |
| No registry retention policy | Registry storage grows forever | Set up automated cleanup for old CI tags |
| Not capturing digest after push | Cannot prove what was deployed | Record digest in deployment logs |
Key Takeaways
- Tags are mutable (can be moved), digests are immutable (always same content). Use both.
- Never deploy
latestto production -- always use explicit version tags. - Build once, promote everywhere -- the same image artifact should flow from CI through staging to production.
- Tag every build with both a version number and a commit SHA for traceability.
- Record the digest of every deployment for guaranteed rollback safety.
What's Next
- Continue to Buildx and Multi-Architecture Builds to learn how to build images for both amd64 and arm64.