Registries, tags and digests

Docker · lesson 16 of 31 · 3 min read

Push an image to a registry, and learn why a tag is a moving label and a digest is not.

Open this lesson in the learning hub

Key points

  • A reference is registry/namespace/name:tag. Leave the registry off and Docker quietly assumes Docker Hub.
  • docker tag is free and local: it only adds a name to bytes you already have. docker push is what uploads layers.
  • A tag is a mutable pointer. Anyone can re-push :1.0 tomorrow, so a tag is never a build identity.
  • The digest @sha256:... is the hash of the manifest. Deploy digests and a rollback is exact, not approximate.
  • Layers the registry already holds are skipped on push. That is why a shared base image makes every deploy faster.
  • docker login stores a token in ~/.docker/config.json. On CI use a scoped robot account, never your own.

Example

# name it for a real registry, then upload
docker tag myapp:1.0 ghcr.io/acme/myapp:1.0.3-b57
docker login ghcr.io -u ci-bot --password-stdin < token.txt
docker push ghcr.io/acme/myapp:1.0.3-b57

# what did that push actually produce?
docker inspect --format "{{index .RepoDigests 0}}" ghcr.io/acme/myapp:1.0.3-b57
#  ghcr.io/acme/myapp@sha256:9f2c1a4b7d3e...

# deploy the digest, not the tag - this can never drift
docker run -d ghcr.io/acme/myapp@sha256:9f2c1a4b7d3e...

# inspect a remote image without pulling it
docker manifest inspect ghcr.io/acme/myapp:1.0.3-b57

Tag for humans, deploy by digest.

This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Docker course, and every lesson in it is listed on the Docker contents page.