Docker registries cheatsheet.

Image naming

[registry/]namespace/repo[:tag][@digest]

docker.io/library/nginx:latest
ghcr.io/myorg/myapp:v1.0
123456.dkr.ecr.us-east-1.amazonaws.com/myapp:v1
nginx@sha256:abc123...

Default registry is Docker Hub if omitted.

Tag + push

docker build -t myapp:v1 .
docker tag myapp:v1 ghcr.io/me/myapp:v1
docker push ghcr.io/me/myapp:v1

Multiple tags:

docker tag myapp ghcr.io/me/myapp:v1
docker tag myapp ghcr.io/me/myapp:latest
docker push --all-tags ghcr.io/me/myapp

Login

# Docker Hub
docker login -u USER

# GHCR
echo $GITHUB_TOKEN | docker login ghcr.io -u USER --password-stdin

# AWS ECR
aws ecr get-login-password --region us-east-1 \
  | docker login --username AWS --password-stdin 123456.dkr.ecr.us-east-1.amazonaws.com

# GCP Artifact Registry
gcloud auth configure-docker us-central1-docker.pkg.dev

Self-hosted registry

docker run -d \
  -p 5000:5000 \
  -v $(pwd)/registry:/var/lib/registry \
  --restart=unless-stopped \
  --name registry \
  registry:2
docker tag myapp localhost:5000/myapp:v1
docker push localhost:5000/myapp:v1

For non-localhost: needs HTTPS or --insecure-registry in daemon.json.

Registry with auth + TLS

docker run -d \
  -p 5000:5000 \
  -v $(pwd)/certs:/certs \
  -v $(pwd)/auth:/auth \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/cert.pem \
  -e REGISTRY_HTTP_TLS_KEY=/certs/key.pem \
  -e REGISTRY_AUTH=htpasswd \
  -e REGISTRY_AUTH_HTPASSWD_REALM="Registry" \
  -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
  registry:2

Generate htpasswd:

docker run --rm --entrypoint htpasswd httpd:2 -Bbn USER PASS > auth/htpasswd

Harbor (enterprise)

For scanning, signing, replication, RBAC, vulnerability management — use Harbor.

# Quick start
git clone https://github.com/goharbor/harbor
cd harbor
./install.sh

Mirror Docker Hub

// /etc/docker/daemon.json
{ "registry-mirrors": ["https://mirror.example.com"] }

Useful in low-egress environments.

Pull-through cache

docker run -d --restart=always \
  -e REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io \
  -p 5000:5000 \
  registry:2

Caches images from upstream.

docker save/load (no registry)

docker save -o myapp.tar myapp:v1
scp myapp.tar server:
ssh server "docker load < myapp.tar"

For air-gapped deployments.

Image promotion pipeline

dev → staging → prod

Same image, different tags:

docker pull ghcr.io/me/myapp:sha-abc123
docker tag ghcr.io/me/myapp:sha-abc123 ghcr.io/me/myapp:staging
docker push ghcr.io/me/myapp:staging
# After QA:
docker tag ghcr.io/me/myapp:sha-abc123 ghcr.io/me/myapp:prod
docker push ghcr.io/me/myapp:prod

Pin by SHA, promote by re-tag. No re-build.

Garbage collection

Registries hold unused blobs. Cleanup:

# Docker registry
docker exec registry registry garbage-collect /etc/docker/registry/config.yml

# Harbor: UI / API

Multi-registry CI

- uses: docker/login-action@v3
  with:
    registry: ghcr.io
    username: ${{ github.actor }}
    password: ${{ secrets.GITHUB_TOKEN }}

- uses: docker/build-push-action@v6
  with:
    push: true
    tags: |
      ghcr.io/${{ github.repository }}:latest
      ghcr.io/${{ github.repository }}:${{ github.sha }}

Cosign (signing)

cosign generate-key-pair
cosign sign --key cosign.key myreg/myapp:v1
cosign verify --key cosign.pub myreg/myapp:v1

Keyless with OIDC:

cosign sign myreg/myapp:v1

Uses GitHub OIDC. Public verification via certificate transparency log.

Pull rate limits

Docker Hub: 100 anonymous pulls / 6h / IP. 200 with login.

Solutions:

  • Use mirror.
  • Cache images in self-hosted registry.
  • Pull-through cache.
  • Switch to GHCR / similar without rate limits.

Common mistakes

  • Pushing latest only — no version pinning.
  • Forgetting credentials in CI — push fails.
  • Pulling from wrong region (slow).
  • Storing huge unused images.
  • Hardcoded registry URL — hard to migrate.

Read this next

If you want my registry + cosign workflow, it’s at rajpoot.dev .


Building something AI-, backend-, or data-heavy and want a second pair of eyes? I do consulting and freelance work — see my projects and ways to reach me at rajpoot.dev .