Docker Registry & Images
Understanding Docker Registries
A Docker registry is a centralized repository that stores and distributes Docker images. Registries act as the distribution mechanism for containerized applications, similar to how GitHub stores code or npm stores packages.
Public vs Private Registries
graph LR
A["Docker Image"] -->B["Push/Pull"]
B -->C{Registry Type?}
C -->|Public| D["Docker Hub
Free to Use
Images Public"]
C -->|Private| E["Private Registry
Restricted Access
Secure Storage"]
E -->E1["Self-Hosted
Docker Registry"]
E -->E2["Cloud Services
Azure ACR"]
E -->E3["Docker Hub
Private Repos"]
style D fill:#90EE90
style E fill:#FFB6C6
Docker Hub
The official public registry. Free to use for public images; private repositories require a subscription.
# Push image to Docker Hub
docker tag myapp:v1 username/myapp:v1
docker push username/myapp:v1
# Pull image from Docker Hub
docker pull ubuntu:22.04
Private Registries
Store proprietary images securely. Options include self-hosted registries or cloud-managed services.
# Push to private registry
docker tag myapp:v1 myregistry.azurecr.io/myapp:v1
docker push myregistry.azurecr.io/myapp:v1
# Pull from private registry
docker pull myregistry.azurecr.io/myapp:v1
Image Tags and Versioning
Tags identify specific versions of images. Proper tagging is essential for reproducibility and version management.
# Build and tag with multiple names
docker build -t myapp:v1.0 \
-t myapp:latest \
-t myregistry.azurecr.io/myapp:v1.0 .
# Show all tags for image
docker image ls | grep myapp
# TAG: repository:version or repository:latest
# Example: nginx:1.24.0, myapp:latest, ubuntu:22.04-slim
Tagging Strategy
# Use semantic versioning
docker tag myapp:v1.2.3 myregistry.azurecr.io/myapp:v1.2.3
docker tag myapp:v1.2.3 myregistry.azurecr.io/myapp:v1.2
docker tag myapp:v1.2.3 myregistry.azurecr.io/myapp:v1
docker tag myapp:v1.2.3 myregistry.azurecr.io/myapp:latest
# Push all tags
docker push myregistry.azurecr.io/myapp:v1.2.3
docker push myregistry.azurecr.io/myapp:latest
Managing Images
Image Cleanup
Images consume disk space. Regular cleanup prevents storage issues.
# List all images
docker images
# Remove specific image
docker rmi myapp:v1.0
# Remove unused images
docker image prune
# Remove unused images and dangling volumes
docker system prune -a --volumes
# Show image size
docker images --format "table {{.Repository}}\t{{.Size}}"
Image Inspection
Understand image contents and configuration.
# View image history and layers
docker history myapp:latest
# Inspect image metadata
docker inspect myapp:latest
# View image contents
docker run --rm myapp:latest ls -la /app
Working with Registries
Authenticate to Registry
# Login to Docker Hub
docker login
# Login to private registry
docker login myregistry.azurecr.io
# Logout
docker logout myregistry.azurecr.io
Dockerfile with Registry
# Use image from private registry
FROM myregistry.azurecr.io/base-python:3.9-alpine
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
CMD ["python", "app.py"]
Build and push:
docker build -t myregistry.azurecr.io/myapp:v1.0 .
docker push myregistry.azurecr.io/myapp:v1.0
Real-World Workflow: Complete Pipeline
graph LR
A["Source Code
Git"] -->B["Build Image
CI/CD Pipeline"]
B -->C["Tag Image
v1.2.3"]
C -->D["Push to Registry
Private Registry"]
D -->E["Pull in Production
Deployment"]
E -->F["Run Container
Orchestration"]
style A fill:#e1f5ff
style B fill:#fff3e0
style C fill:#e8f5e9
style D fill:#f3e5f5
style E fill:#ffe0b2
style F fill:#c8e6c9
Complete CI/CD example:
# .github/workflows/deploy.yml
name: Build and Push
on:
push:
tags:
- 'v*'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Login to Registry
run: docker login -u ${{ secrets.REGISTRY_USERNAME }} -p ${{ secrets.REGISTRY_PASSWORD }} myregistry.azurecr.io
- name: Build Image
run: docker build -t myregistry.azurecr.io/myapp:${{ github.ref_name }} .
- name: Push Image
run: docker push myregistry.azurecr.io/myapp:${{ github.ref_name }}
Image Security Best Practices
Scan for Vulnerabilities
# Using Docker Scout (built-in)
docker scout cves myapp:latest
# Using Trivy (external tool)
trivy image myregistry.azurecr.io/myapp:v1.0
Sign Images
Verify image authenticity and integrity.
# Enable Docker Content Trust
export DOCKER_CONTENT_TRUST=1
# Pushing requires signing key
docker push myregistry.azurecr.io/myapp:v1.0
Minimize Attack Surface
- Use minimal base images (Alpine, Distroless)
- Remove build tools from production images
- Keep base images updated
- Scan regularly for vulnerabilities
Common Pitfalls
- Using
latesttag in production - Use specific version tags for reproducibility - Storing credentials in images - Use environment variables or secret management
- Pushing unscanned images - Always scan for vulnerabilities before production
- Forgetting to authenticate - Configure registry credentials in CI/CD pipelines
- Not cleaning up old images - Implement image retention policies
Key Takeaways
- Registries centralize image storage and distribution; Docker Hub is public, private registries are secure
- Semantic versioning with multiple tags (v1.2.3, v1.2, v1, latest) enables flexible deployment strategies
- Image authentication, scanning, and signing are critical security practices for production deployments
- CI/CD pipelines automate image building, tagging, and pushing to registries on code changes
- Image cleanup and lifecycle management prevent storage bloat and cost overruns
- Private registries provide security and control; self-hosted or cloud-managed options exist
- Always authenticate before pushing/pulling from private registries
Next Steps: Implement image scanning in CI/CD pipelines, establish semantic versioning strategy for images, configure private registry authentication, and audit existing images for vulnerabilities.