Docker Registry Documentation
A local Docker registry for storing custom container images in your Kubernetes homelab cluster.
Overview
This deployment provides a simple, persistent Docker registry running on Kubernetes. It uses the official registry:2 image and is configured with persistent storage, image deletion enabled, and MetalLB LoadBalancer integration.
Key Features
- Persistent Storage: 50Gi PVC using local-path storage class
- Image Deletion: Enabled for registry cleanup
- Health Checks: Configured for pod health monitoring
- LoadBalancer: MetalLB assigns external IP automatically
- Insecure Registry: Configured for local development use
Architecture
The Docker registry deployment consists of:
┌─────────────────────────────────────────────┐
│ Docker Registry Deployment │
├─────────────────────────────────────────────┤
│ Namespace: docker-registry │
│ │
│ ┌──────────────────────────────────────┐ │
│ │ Deployment │ │
│ │ - Image: registry:2 │ │
│ │ - Replicas: 1 │ │
│ │ - Port: 5000 │ │
│ └──────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────┐ │
│ │ Service (LoadBalancer) │ │
│ │ - Type: LoadBalancer │ │
│ │ - External IP: MetalLB assigned │ │
│ └──────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────┐ │
│ │ Persistent Volume │ │
│ │ - Size: 50Gi │ │
│ │ - Storage Class: local-path │ │
│ └──────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
Quick Start
Deploy the Registry
Verify Deployment
# Check pod status
kubectl get pods -n docker-registry
# Check service and external IP
kubectl get svc -n docker-registry
# Get the registry IP
export REGISTRY_IP=$(kubectl get svc docker-registry -n docker-registry \
-o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "Registry IP: $REGISTRY_IP"
Configure Docker
Configure Docker on your local machine to use the insecure registry:
Restart Docker:
Usage Examples
Push Images
# Tag your image
docker tag custom-ci:latest $REGISTRY_IP:5000/custom-ci:latest
# Push to registry
docker push $REGISTRY_IP:5000/custom-ci:latest
Pull Images
Use in Kubernetes Pods
Pods in the cluster can access the registry using the service DNS:
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
image: docker-registry.docker-registry.svc.cluster.local:5000/custom-ci:latest
Use in GitLab CI
Update .gitlab-ci.yml to use custom images:
security-scan:
stage: security
image: docker-registry.docker-registry.svc.cluster.local:5000/custom-ci:latest
script:
- detect-secrets scan --baseline || true
tags:
- local-k8-runner
Maintenance
View Registry Contents
# List all repositories
curl $REGISTRY_IP:5000/v2/_catalog
# List tags for a repository
curl $REGISTRY_IP:5000/v2/custom-ci/tags/list
Monitor Registry Health
# View registry logs
kubectl logs -f deployment/docker-registry -n docker-registry
# Check pod events
kubectl describe pod -n docker-registry -l app=docker-registry
Backup Registry Data
# Create backup
kubectl exec -n docker-registry deployment/docker-registry -- \
tar -czf - -C /var/lib/registry . | \
gzip > registry-backup-$(date +%Y%m%d).tar.gz
# Restore from backup
tar -xzf registry-backup-*.tar.gz | \
kubectl exec -i -n docker-registry deployment/docker-registry -- \
tar -xzf - -C /var/lib/registry
Configuration
Storage
The registry uses a 50Gi persistent volume with the local-path storage class. To increase storage:
# Delete PVC (data will be lost)
kubectl delete pvc registry-data -n docker-registry
# Edit pvc.yaml to increase size
# Then redeploy
kubectl apply -k .
Registry Settings
Registry configuration is managed via ConfigMap:
# ConfigMap settings
- Storage: filesystem with in-memory cache
- Deletion: enabled for cleanup
- Health checks: enabled
- Headers: X-Content-Type-Options set to nosniff
Security Considerations
⚠️ Important: This registry is configured as an insecure registry for local development.
Current Configuration: - ❌ No TLS/HTTPS encryption - ❌ No authentication required - ✅ Insecure registry mode - ✅ Local/trusted network use only
Production Recommendations: - Use Harbor for feature-rich enterprise registry - Set up TLS certificates with cert-manager - Implement authentication with Harbor or GitLab Container Registry - Use proper RBAC and network policies - Enable vulnerability scanning
Troubleshooting
Registry Not Starting
# Check pod events
kubectl describe pod -n docker-registry -l app=docker-registry
# Check PVC status
kubectl get pvc -n docker-registry
# Verify storage class exists
kubectl get storageclass
Can't Push to Registry
- Verify Docker daemon configuration:
/etc/docker/daemon.json - Restart Docker after configuration changes
- Verify registry IP is correct:
kubectl get svc -n docker-registry - Check registry logs:
kubectl logs -n docker-registry deployment/docker-registry
No External IP Assigned
# Check MetalLB status
kubectl get pods -n metallb-system
# Verify IP pool
kubectl get ipaddresspool -n metallb-system
# Check L2 advertisement
kubectl get l2advertisement -n metallb-system
Integration with CI/CD
Custom CI Images
Build and push custom CI images to optimize GitLab CI job execution:
# Build custom CI image
cd /custom-ci-image
docker build -t $REGISTRY_IP:5000/custom-ci:latest .
# Push to registry
docker push $REGISTRY_IP:5000/custom-ci:latest
Automated Builds
Consider setting up automated image builds with: - Kaniko: Build images in Kubernetes without Docker daemon - BuildKit: Advanced build capabilities - GitHub Actions: CI/CD workflows for image builds - ArgoCD: GitOps-based image deployment