Docker path · Building images · Topic 7 of 12

Registries, tags and digests

Not started

A registry is a content store with names on top. Docker Hub, GitHub Container Registry, Amazon ECR, Google Artifact Registry and the open-source registry all implement the OCI distribution specification: layers and manifests are uploaded and fetched by their SHA-256 digest, and a tag is a human-friendly name that points to one manifest. The digest identifies content; the tag is only a label someone can move.

Why it matters: If you deploy by tag, the same YAML can run different code tomorrow. Pinning by digest is how a build or a rollback stays exactly reproducible.

  1. 1A registry stores content by digest

    Registries implement the OCI distribution spec: blobs and manifests are stored by their SHA-256 digest, and tags are names that point to a manifest.

  2. 2Tags are mutable pointers

    Anyone with push rights can move node:22-alpine, or latest, to a new image at any time. latest is only the default tag name, not 'the newest'.

  3. 3Digests are immutable

    name@sha256:... always resolves to exactly the same bytes, or fails. That is what you want in production and in FROM lines.

  4. 4Pin the index, automate the bumps

    Pin a multi-platform image by its index digest, and let a bot such as Renovate or Dependabot open pull requests when the tag moves.

1

How it works

The explanation, with examples you can run.

Anatomy of an image name

ghcr.io/acme/payments:1.4.2└─ registry ─┘└ repository ┘└ tag ┘ node:22-alpine   is short for   docker.io/library/node:22-alpine

With no registry, Docker assumes Docker Hub; with no namespace on Hub, library/ (the official images); with no tag, latest.

Tags versus digests

Ask the registry what a tag currently points to:

docker buildx imagetools inspect alpine:3.22# Name:      docker.io/library/alpine:3.22# MediaType: application/vnd.oci.image.index.v1+json# Digest:    sha256:5291449c3df73caf6ed85e649dec1b9e818b39a5d8c871e97afc13e9cd5e8fa8# Manifests:#   Name:      docker.io/library/alpine:3.22@sha256:3e9b4b68...#   Platform:  linux/amd64#   ...

The top-level digest is the image index (one entry per platform); each entry below has its own manifest digest. Tomorrow alpine:3.22 may point to a rebuilt index with a different digest (a patched package, a new base). The digest above will always mean exactly these bytes.

Pin by digest where reproducibility matters, and keep the tag for humans:

FROM alpine:3.22@sha256:5291449c3df73caf6ed85e649dec1b9e818b39a5d8c871e97afc13e9cd5e8fa8
# Kubernetes: what runs is exactly what you testedimage: ghcr.io/acme/payments:1.4.2@sha256:<digest printed by your CI push>

When both are present, the digest wins and the tag is ignored for resolution. Pin the index digest, not a single platform's manifest, or you lose the other architectures.

Living with pinned digests

Pinning only helps if the pins are updated: a base pinned for a year collects a year of vulnerabilities. Tools such as Renovate and Dependabot recognise tag@sha256: pins and open pull requests when the tag moves, so updates are deliberate, reviewed and revertible. For your own images, tag every build with something immutable by convention (the version or git SHA), never reuse a version tag, and have CI record the pushed digest for deployment.

Other things registries do

  • Pull limits. Docker Hub limits anonymous and free pulls; CI that pulls a lot should authenticate or use a mirror or pull-through cache.
  • Attestations and signatures. BuildKit can attach provenance and SBOM attestations to an image, and tools such as cosign sign a digest. Both refer to the digest, which is another reason to deploy by digest.
  • Garbage. Untagged manifests are kept until the registry's retention or garbage collection removes them, so set lifecycle rules on private registries.
2

Check yourself

3 questions. Get them all right to finish this topic.

  1. 1.Your Dockerfile says FROM node:22-alpine. The maintainers push a new 22.x build under that tag. What does your next uncached build use?
  2. 2.A multi-platform image has an index digest and one manifest digest per platform. Which should you pin in a Dockerfile used on arm64 Macs and amd64 CI runners?
  3. 3.What does the tag latest mean?

0 of 3 right so far. Get all three to finish this topic.