Registry Operations
Complete guide to Docker registry operations, including Docker Hub, private registries, and deployment strategies.
Docker Hub Operations
Authentication
# Login to Docker Hub
docker login
# Login with username and password
docker login -u username -p password
# Login to specific registry
docker login registry.example.com
# Store credentials in credential store
docker login --password-stdin
# Logout
docker logout
# Logout from specific registry
docker logout registry.example.com
Image Management
# Tag image for Docker Hub
docker tag myapp:latest username/myapp:latest
docker tag myapp:latest username/myapp:v1.0.0
# Push to Docker Hub
docker push username/myapp:latest
docker push username/myapp:v1.0.0
# Pull from Docker Hub
docker pull username/myapp:latest
docker pull username/myapp:v1.0.0
# Push multiple tags
docker push username/myapp --all-tags
# Remove tag from registry (requires API call)
curl -X DELETE \
-H "Authorization: Bearer $TOKEN" \
https://hub.docker.com/v2/repositories/username/myapp/tags/v1.0.0/
Repository Management
# Create repository (via Docker Hub web interface or API)
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "myapp", "description": "My application"}' \
https://hub.docker.com/v2/repositories/
# Set repository visibility
curl -X PATCH \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"is_private": false}' \
https://hub.docker.com/v2/repositories/username/myapp/
Private Registry Setup
Docker Registry Server
# Run local registry
docker run -d -p 5000:5000 --name registry registry:2
# Run with persistent storage
docker run -d -p 5000:5000 --name registry \
-v /opt/registry:/var/lib/registry \
registry:2
# Run with authentication
docker run -d -p 5000:5000 --name registry \
-v /opt/registry/auth:/auth \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \
registry:2
# Run with TLS
docker run -d -p 5000:5000 --name registry \
-v /opt/registry/certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry:2
Registry Configuration
# config.yml
version: 0.1
log:
level: info
storage:
filesystem:
rootdirectory: /var/lib/registry
delete:
enabled: true
http:
addr: :5000
headers:
X-Content-Type-Options: [nosniff]
health:
storagedriver:
enabled: true
interval: 10s
threshold: 3
auth:
htpasswd:
realm: basic-realm
path: /auth/htpasswd
Authentication Setup
# Create htpasswd file
docker run --rm --entrypoint htpasswd registry:2 -Bbn username password > htpasswd
# Add more users
docker run --rm --entrypoint htpasswd registry:2 -Bbn user2 pass2 >> htpasswd
# Use bcrypt encryption
docker run --rm --entrypoint htpasswd registry:2 -Bbn user3 pass3 >> htpasswd
Private Registry Operations
Working with Private Registry
# Tag for private registry
docker tag myapp:latest registry.example.com/myapp:latest
docker tag myapp:latest localhost:5000/myapp:latest
# Push to private registry
docker push registry.example.com/myapp:latest
docker push localhost:5000/myapp:latest
# Pull from private registry
docker pull registry.example.com/myapp:latest
docker pull localhost:5000/myapp:latest
# List repositories in registry
curl http://localhost:5000/v2/_catalog
# List tags for repository
curl http://localhost:5000/v2/myapp/tags/list
# Get image manifest
curl http://localhost:5000/v2/myapp/manifests/latest
Registry API Operations
# Check registry version
curl http://localhost:5000/v2/
# List repositories
curl http://localhost:5000/v2/_catalog
# List tags
curl http://localhost:5000/v2/myapp/tags/list
# Get manifest
curl -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
http://localhost:5000/v2/myapp/manifests/latest
# Delete image (requires digest)
# First get the digest
DIGEST=$(curl -I -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
http://localhost:5000/v2/myapp/manifests/latest | grep Docker-Content-Digest | cut -d' ' -f2)
# Then delete
curl -X DELETE http://localhost:5000/v2/myapp/manifests/$DIGEST
Cloud Registry Services
Amazon ECR
# Install AWS CLI and login
aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.us-west-2.amazonaws.com
# Create repository
aws ecr create-repository --repository-name myapp
# Tag and push
docker tag myapp:latest 123456789012.dkr.ecr.us-west-2.amazonaws.com/myapp:latest
docker push 123456789012.dkr.ecr.us-west-2.amazonaws.com/myapp:latest
# Pull image
docker pull 123456789012.dkr.ecr.us-west-2.amazonaws.com/myapp:latest
# List repositories
aws ecr describe-repositories
# List images
aws ecr list-images --repository-name myapp
Google Container Registry (GCR)
# Configure authentication
gcloud auth configure-docker
# Tag and push
docker tag myapp:latest gcr.io/project-id/myapp:latest
docker push gcr.io/project-id/myapp:latest
# Pull image
docker pull gcr.io/project-id/myapp:latest
# List images
gcloud container images list
gcloud container images list-tags gcr.io/project-id/myapp
Azure Container Registry (ACR)
# Login to ACR
az acr login --name myregistry
# Tag and push
docker tag myapp:latest myregistry.azurecr.io/myapp:latest
docker push myregistry.azurecr.io/myapp:latest
# Pull image
docker pull myregistry.azurecr.io/myapp:latest
# List repositories
az acr repository list --name myregistry
# List tags
az acr repository show-tags --name myregistry --repository myapp
CI/CD Integration
GitHub Actions
name: Build and Push Docker Image
on:
push:
branches: [main]
tags: ['v*']
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: |
username/myapp:latest
username/myapp:${{ github.sha }}
GitLab CI
# .gitlab-ci.yml
variables:
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: '/certs'
services:
- docker:dind
build:
stage: build
image: docker:latest
before_script:
- echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY
script:
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
- docker tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA $CI_REGISTRY_IMAGE:latest
- docker push $CI_REGISTRY_IMAGE:latest
Jenkins Pipeline
pipeline {
agent any
environment {
DOCKER_REGISTRY = 'registry.example.com'
IMAGE_NAME = 'myapp'
}
stages {
stage('Build') {
steps {
script {
def image = docker.build("${DOCKER_REGISTRY}/${IMAGE_NAME}:${BUILD_NUMBER}")
image.push()
image.push("latest")
}
}
}
}
}
Registry Security
TLS Configuration
# Generate self-signed certificate
openssl req -newkey rsa:4096 -nodes -sha256 -keyout domain.key -x509 -days 365 -out domain.crt
# Run registry with TLS
docker run -d -p 443:5000 --name registry \
-v /opt/registry/certs:/certs \
-v /opt/registry/data:/var/lib/registry \
-e REGISTRY_HTTP_ADDR=0.0.0.0:5000 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry:2
# Configure Docker daemon to trust registry
# Add to /etc/docker/daemon.json
{
"insecure-registries": ["registry.example.com:5000"]
}
Access Control
# Registry config with RBAC
auth:
token:
realm: https://auth.example.com/token
service: registry.example.com
issuer: auth.example.com
rootcertbundle: /auth/root.crt
# Using Harbor for RBAC
version: '3.8'
services:
harbor-core:
image: goharbor/harbor-core:latest
environment:
- CORE_SECRET=secret123
- JOBSERVICE_SECRET=secret456
volumes:
- ./harbor/core:/etc/core
Registry Maintenance
Cleanup Operations
# Registry garbage collection
docker exec registry bin/registry garbage-collect /etc/docker/registry/config.yml
# Delete unused images
docker exec registry bin/registry garbage-collect --delete-untagged /etc/docker/registry/config.yml
# Prune local images
docker image prune -a
# Remove specific tags from registry
curl -X DELETE http://localhost:5000/v2/myapp/manifests/sha256:digest
Backup and Restore
# Backup registry data
tar -czf registry-backup.tar.gz /opt/registry/data
# Backup with docker
docker run --rm -v registry_data:/data -v $(pwd):/backup alpine tar czf /backup/registry-backup.tar.gz -C /data .
# Restore registry data
tar -xzf registry-backup.tar.gz -C /opt/registry/
# Restore with docker
docker run --rm -v registry_data:/data -v $(pwd):/backup alpine tar xzf /backup/registry-backup.tar.gz -C /data
Monitoring Registry
# Check registry health
curl http://localhost:5000/v2/
# Monitor storage usage
du -sh /opt/registry/data
# Check registry logs
docker logs registry
# Monitor with Prometheus
# Add to registry config
http:
debug:
addr: :5001
prometheus:
enabled: true
path: /metrics
Image Distribution Strategies
Multi-Architecture Images
# Build multi-arch image
docker buildx create --use
docker buildx build --platform linux/amd64,linux/arm64 -t username/myapp:latest --push .
# Inspect multi-arch image
docker buildx imagetools inspect username/myapp:latest
Image Mirroring
# Mirror images between registries
docker pull source.registry.com/myapp:latest
docker tag source.registry.com/myapp:latest dest.registry.com/myapp:latest
docker push dest.registry.com/myapp:latest
# Automated mirroring with Skopeo
skopeo copy docker://source.registry.com/myapp:latest docker://dest.registry.com/myapp:latest
Content Distribution
# Docker Compose with registry mirror
version: '3.8'
services:
registry-mirror:
image: registry:2
ports:
- '5000:5000'
environment:
REGISTRY_PROXY_REMOTEURL: https://registry-1.docker.io
volumes:
- mirror-data:/var/lib/registry
volumes:
mirror-data:
Quick Reference
Registry Commands
docker login- Authenticate with registrydocker push image- Push image to registrydocker pull image- Pull image from registrydocker tag source target- Tag image for registrydocker logout- Logout from registry
Registry URLs
- Docker Hub:
docker.io(default) - AWS ECR:
<account>.dkr.ecr.<region>.amazonaws.com - Google GCR:
gcr.io/<project> - Azure ACR:
<registry>.azurecr.io - Local Registry:
localhost:5000
Best Practices
- Use specific image tags in production
- Implement registry authentication
- Enable TLS for production registries
- Regular backup of registry data
- Monitor registry storage usage
- Implement image scanning in CI/CD
- Use multi-stage builds to minimize image size
- Implement proper access controls
- Regular cleanup of unused images
- Use registry mirrors for better performance