Container Registry Guide
Registry Comparison
| Registry | Provider | Free Tier | Best For |
|---|---|---|---|
| Docker Hub | Docker Inc. | 1 private repo, rate-limited pulls | Public images, open-source projects |
| Amazon ECR | AWS | 500 MB/month (private) | AWS-native workloads, EKS/ECS |
| Google Artifact Registry | GCP | 0.5 GB free | GCP/GKE workloads, multi-format (Maven, npm) |
| Azure Container Registry (ACR) | Azure | No free tier | Azure/AKS workloads, geo-replication |
| GitHub Container Registry (GHCR) | GitHub | Free for public, 1 GB for private | GitHub Actions CI/CD, open-source |
| Harbor | Self-hosted (CNCF) | Free (self-hosted) | Air-gapped, enterprise, multi-tenant |
Image Tagging Strategy
# Semantic versioning (recommended)
myapp:latest # always points to newest (avoid in prod!)
myapp:1.2.3 # immutable specific version
myapp:1.2 # mutable minor version tag
myapp:1 # mutable major version tag
# Git-based tagging (CI/CD)
myapp:main # branch name (mutable)
myapp:sha-abc1234 # git commit SHA (immutable, preferred in prod)
myapp:pr-456 # pull request builds
# Environment-based
myapp:prod-1.2.3 # environment + version
# Build and push with multiple tags
docker build -t myregistry/myapp:1.2.3 \
-t myregistry/myapp:1.2 \
-t myregistry/myapp:latest .
docker push myregistry/myapp --all-tags
Multi-Arch Builds (ARM + AMD64)
# Build for multiple architectures with buildx
docker buildx create --use --name multiarch
docker buildx inspect --bootstrap
# Build and push for linux/amd64 + linux/arm64
docker buildx build \
--platform linux/amd64,linux/arm64 \
--tag myregistry/myapp:latest \
--push .
# GitHub Actions: multi-arch + GHCR
# - name: Build and push
# uses: docker/build-push-action@v5
# with:
# platforms: linux/amd64,linux/arm64
# push: true
# tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
# ECR login (AWS CLI)
aws ecr get-login-password --region us-east-1 \
| docker login --username AWS --password-stdin \
123456789.dkr.ecr.us-east-1.amazonaws.com
# Create ECR repo
aws ecr create-repository --repository-name myapp \
--image-scanning-configuration scanOnPush=true