DockerBeginner 11 min Lesson 9 of 10

Registries and Docker Hub

Store and distribute images: tagging conventions, authentication, private registries, rate limits and image scanning.

Docker · Lesson 9 of 10
0/10 done(0%)

What is it? #

A registry stores images so they can be pulled onto other machines. Docker Hub is the default public one; every cloud provider offers a private equivalent.

The workflow is: build, tag with the registry address, authenticate, push. Deployment then pulls that tag.

Tagging deserves a deliberate convention. A tag is how you know what is running, and latest tells you nothing.

Two practical concerns bite quickly: Docker Hub rate limits on anonymous pulls, and the need to scan images for known vulnerabilities before they reach production.

Think of it like this #

A warehouse for finished goods with labelled shelves.

You produce an item, label it precisely, put it on the shelf, and any branch can collect that exact item later. A shelf labelled "newest" means nobody knows what they collected.

Simple example #

CI builds an image, tags it with the commit hash and a version number, pushes both to a private registry, and the deployment pulls the exact hash.

Code #

BASH
# Build, tag, push
docker build -t myapp:1.4.2 .
docker tag myapp:1.4.2 registry.example.com/team/myapp:1.4.2
docker tag myapp:1.4.2 registry.example.com/team/myapp:sha-a1b2c3d

echo "$REGISTRY_TOKEN" | docker login registry.example.com -u ci --password-stdin
docker push registry.example.com/team/myapp:1.4.2
docker push registry.example.com/team/myapp:sha-a1b2c3d

# On the server
docker pull registry.example.com/team/myapp:sha-a1b2c3d
TEXT
A tagging convention that works

sha-a1b2c3d        the commit — always unique, what deployments should use
1.4.2              the release version — what humans refer to
1.4                moving minor tag — convenient, not for production pinning
staging, prod      environment pointers — moved, never pinned
latest             avoid entirely in deployments

Push both an immutable tag and a human-readable one. Deploy the
immutable one so you always know exactly what is running.
BASH
# Digests: the strongest form of pinning
docker pull registry.example.com/team/myapp@sha256:9c1c0b...
docker inspect --format='{{index .RepoDigests 0}}' myapp:1.4.2

# Base images in a Dockerfile can be pinned the same way
# FROM python:3.12-slim@sha256:abc123...
TEXT
Docker Hub rate limits

Anonymous pulls are limited per IP address per six hours. On a shared
CI runner or a NAT-ed office network, that limit is reached quickly and
builds start failing with "toomanyrequests".

Fixes: authenticate (a free account raises the limit), mirror the base
images you depend on into your own registry, or cache them in CI.
BASH
# Scanning before deployment
docker scout cves myapp:1.4.2
trivy image myapp:1.4.2 --severity HIGH,CRITICAL
# Run this in CI and fail the build on critical findings in your own
# dependencies. Base image findings often need a base image update.

How it works #

An image name encodes its registry: registry.example.com/team/myapp:tag. Without a registry prefix, Docker assumes Docker Hub.

Tagging does not copy anything. It adds another name for the same image, which is why tagging with both a version and a commit hash costs nothing extra.

Pushing uploads only the layers the registry does not already have. Pushing a small change to a large image transfers very little.

--password-stdin keeps the token out of shell history and process listings, which matters in CI where the command line is often logged.

Digests are content addresses. A digest refers to exactly one image forever, whereas a tag can be moved to point at something else. Deploying by digest or by commit-hash tag removes all ambiguity about what is running.

The Docker Hub rate limit is a practical operational issue rather than a theoretical one. Shared CI runners hit it regularly, and the usual fix is authenticating or mirroring base images.

Scanning reports vulnerabilities in the image's packages. Findings in your own dependencies are actionable immediately; findings in the base image usually mean updating or changing the base, which is another argument for minimal images.

Real-world use #

Private registries hold application images. Cloud registries integrate with their platform's authentication, and GitHub and GitLab both offer one alongside the repository.

CI builds and pushes on every merge, tagging with the commit hash. Deployments reference that hash, so the running version maps exactly to a commit.

Base image mirroring is common in larger organisations, both to avoid rate limits and to control which versions are available internally.

Retention policies matter. Registries accumulate images quickly, and storage costs add up, so old untagged images are usually pruned automatically.

Signing images is the next step in supply-chain security: proving an image was built by your pipeline and has not been substituted.

Common mistakes #

  • Deploying latest, so nobody can tell what version is running.
  • Anonymous pulls in CI, hitting Docker Hub rate limits mid-build.
  • Passing registry credentials on the command line instead of via stdin.
  • Never scanning images, shipping known vulnerabilities to production.
  • No retention policy, so registry storage grows without limit.

Practice #

Build an image and tag it with both a version and a commit hash. Push both to a registry, then pull by digest on another machine and confirm it is the same image. Run a vulnerability scan and note which findings come from your dependencies and which from the base image.

Quick quiz

  1. 1. What should deployments reference?

  2. 2. What does tagging an image do?

  3. 3. Why use `--password-stdin` when logging in?

  4. 4. What causes "toomanyrequests" errors in CI?

  5. 5. Why do many scan findings come from the base image?

Summary

  • Registries store and distribute images; tag with the registry address to push.
  • Adopt a tagging convention and deploy an immutable tag or digest.
  • Authenticate to avoid rate limits, and pass tokens via stdin.
  • Scan images in CI and prefer minimal base images.
  • Set a retention policy so registry storage does not grow forever.