Docker Tutorial · Building Images · Lesson 14 of 26
Tags, Digests and Registries
Name, tag and push images, and pin exactly what you run with digests.
Image names
registry/namespace/repository:tag, for example ghcr.io/acme/api:1.8.2. Without a registry, Docker Hub is
assumed; without a tag, latest.
Tags move, digests don't
A tag is a movable pointer: api:1.8 can be re-pushed. A digest (api@sha256:…) identifies exact content
and never changes. Deployment systems often resolve a tag to a digest once and deploy the digest everywhere.
Pushing
docker login ghcr.io
docker tag api:dev ghcr.io/acme/api:1.8.2
docker push ghcr.io/acme/api:1.8.2
A common convention: an immutable tag per build (Git commit SHA or semantic version) plus moving tags for
humans (1.8, latest).
trap 'docker image rm -f rc-api:dev localhost:5000/acme/api:1.8.2 localhost:5000/acme/api:1.8 > /dev/null 2>&1' EXIT
printf 'FROM alpine:3.24\nCMD ["echo", "api"]\n' > Dockerfile
docker build -q -t rc-api:dev . > /dev/null
docker tag rc-api:dev localhost:5000/acme/api:1.8.2
docker tag rc-api:dev localhost:5000/acme/api:1.8
docker image ls --format '{{.Repository}}:{{.Tag}}' | grep -E 'rc-api|acme/api' | sort
same=$(docker image inspect rc-api:dev localhost:5000/acme/api:1.8.2 --format '{{.Id}}' | sort -u | wc -l)
echo "distinct image IDs behind these three tags: $same"
Output
localhost:5000/acme/api:1.8 localhost:5000/acme/api:1.8.2 rc-api:dev distinct image IDs behind these three tags: 1
Run this on your computer — see “Get Started” for setup.
See docker image tag.
Test yourself
How do you make sure every environment runs exactly the same image?
Use latest everywhereDeploy by digest (image@sha256:...) or an immutable tagRebuild in each environmentCopy the Dockerfile
Show answer
Answer: Deploy by digest (image@sha256:...) or an immutable tag
Digests identify exact content; rebuilding can produce different images.