Skip to main content

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 registry
  • docker push image - Push image to registry
  • docker pull image - Pull image from registry
  • docker tag source target - Tag image for registry
  • docker 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