Topic 1.4
Image Names, Tags & Docker Hub
In one line
An image reference like postgres:16-alpine packs three pieces of information into one string — decode it correctly and you'll never be confused about which exact image you're running again.
Think of it like this
A book's ISBN plus edition. postgres is the book title (the repository name). 16-alpine is the specific edition (the tag) — the same title can have many editions (versions/variants) that differ in content.
Key ideas
- 01
Full anatomy of an image reference:
[registry/][namespace/]repository[:tag]. E.g.docker.io/library/postgres:16-alpine—docker.iois the registry (Docker Hub, and it's the DEFAULT so you can omit it),libraryis the official-images namespace (also usually omittable),postgresis the repository,16-alpineis the tag. - 02
If you omit the tag entirely (just
docker run nginx), Docker defaults to thelatesttag — which is JUST A CONVENTION, not automatically 'the newest version'. A maintainer can pointlatestat whatever they choose, and relying on it in production is a common, avoidable source of surprise breakage when it silently changes underneath you. - 03
Common tag conventions worth recognizing: version tags (
16,16.2), variant suffixes like-alpine(built on the tiny Alpine Linux base, much smaller) or-slim(a trimmed-down Debian-based variant), andlatest(the default, unpinned, convention-only tag). - 04
Every image also has a content-addressed DIGEST (a SHA256 hash) that uniquely and immutably identifies its exact content — unlike a tag, a digest can never silently point to different content later. Production deployments that need absolute certainty pin to a digest (
myapp@sha256:abcdef...) rather than a tag. - 05
Docker Hub is the default public registry, hosting both OFFICIAL images (maintained by Docker/the software vendor, like
postgres,nginx,node) and community/personal images (someuser/theirimage). Companies typically also run a PRIVATE registry (AWS ECR, Google Artifact Registry, self-hosted Harbor/Nexus) for their own proprietary images. - 06
docker pull <image>explicitly downloads an image without running it.docker tag <image> <newname>creates an additional name/tag pointing at the SAME image content — useful before pushing to a different registry.
In your stack
- →
Official Java-relevant base images worth knowing by name:
eclipse-temurin(the modern, actively-maintained OpenJDK distribution — the current recommended default),openjdk(the older official image, now deprecated in favor of eclipse-temurin), andmaven(bundles Maven + a JDK, useful for multi-stage BUILD stages covered in Phase 7).
Code & diagrams
The exact anatomy of an image reference, decoded piece by piece.
# Full explicit form:
# registry namespace repository tag
# | | | |
docker.io / library / postgres : 16-alpine
# In practice, you almost always write the short form (registry+namespace assumed):
docker pull postgres:16-alpine
# No tag = "latest" is assumed (a convention, not "the newest")
docker pull nginx # same as: docker pull nginx:latest
# Pinning to an exact, immutable content digest (production-grade certainty)
docker pull nginx@sha256:2d194184b067db3598771b4cf326cfe6ee9994b0f9e5f0b64d2ea86e88a5eea
# Tagging: give the SAME image content an additional name (e.g. before pushing elsewhere)
docker tag myapp:v2 myregistry.example.com/myteam/myapp:v2
docker push myregistry.example.com/myteam/myapp:v2Explain it without notes
Why is deploying with the latest tag in production considered risky, even though it's the most convenient default?
What is the practical difference between a tag and a digest, and why would a bank's deployment pipeline insist on the digest?
Practice
Pull three different tags of the same image (e.g. node:20, node:20-alpine, node:20-slim) and compare their sizes with docker images.
Find the exact digest of an image you've pulled using docker inspect <image> --format='{{.RepoDigests}}' (or read it from docker images --digests).
Trade-offs
- ↔
Pinning to a digest is maximally reproducible but means you must EXPLICITLY update it to get any new patches/security fixes — pinning to a specific version tag (like
16.2rather thanlatestor bare16) is usually the practical middle ground most teams choose.
Done when you can
I can decode any image reference into registry/namespace/repository/tag.
I never rely on the
latesttag for anything I'd call 'production'.I know the difference between a tag and a digest, and when each matters.