Skip to Content

Registries: Docker Hub, ECR, GHCR

When to use

Share your image with teammates, CI, or production.

Analogy

a registry is a library; you publish your book (image), others check it out (pull). Tag carefully - latest is a default but a trap.

Data-flow diagram

  local                   registry                runner
  docker build ---> docker push (auth tag) ---> docker pull
  Public:  Docker Hub (rate-limited free tier ~200 pulls/6hr)
  Private: AWS ECR (per-account, per-Region)
  Public D: GitHub Container Registry (GHCR)

Deep explanation

A registry stores and serves images identified by repository:tag. Tagging convention: registry/owner/image:tag (e.g. 123456.dkr.ecr.us-east-1.amazonaws.com/myteam/myapp:1.0.0). Common registries: Docker Hub (default public), AWS ECR (private, IAM-authenticated, Region-scoped), GitHub Container Registry (GHCR), Azure ACR, GCP Artifact Registry. Repo links are immutable (you can’t overwrite an image with the same tag - you must push a new tag).

Examples

Example 1

docker tag myapp:1.0.0 \
  123456.dkr.ecr.us-east-1.amazonaws.com/myteam/myapp:1.0.0
aws ecr get-login-password --region us-east-1 | \
  docker login --username AWS --password-stdin \
  123456.dkr.ecr.us-east-1.amazonaws.com
docker push 123456.dkr.ecr.us-east-1.amazonaws.com/myteam/myapp:1.0.0

tags local image for ECR, authenticates with temporary ECR password, pushes.

Example 2

docker pull ghcr.io/myorg/myapp:1.0.0
docker run --rm ghcr.io/myorg/myapp:1.0.0 --version

pulls a public image from GHCR; --rm cleans up the container after exit.

Example 3

docker manifest inspect myapp:1.0.0 | jq '.manifests[].platform'
# multi-arch image inspection

inspects manifest list; multi-arch images include entries for amd64, arm64.

Common mistake

Pulling from Docker Hub anonymously (rate-limited and slow in CI). Pushing the same tag twice (immutable -> creates orphaned images that still cost). Forgetting to set retention policies.

Key takeaway

Pin by SHA256 digest in prod; use blue/green tags; set ECR repo policy for cross-account pulls; use lifecycle policies to expire untagged images.

Production Failure Playbook

Failure scenario 1: docker-hub-rate-limit

Failure scenario 2: image-overwritten-by-tag