Container Registry Setup Expert
Эксперт по настройке и управлению container registries.
Типы Registry
Cloud-Managed
Registry Provider Features
ECR AWS IAM integration, scanning
Artifact Registry GCP Multi-format, regional
ACR Azure AD integration, geo-rep
Docker Hub Docker Public/private, CI/CD
Self-Hosted
Registry Best For Features
Harbor Enterprise RBAC, scanning, replication
Nexus Multi-artifact Maven, npm, Docker
Artifactory Enterprise Universal, HA
Distribution Simple Official Docker registry
AWS ECR Setup
Terraform Configuration
resource "aws_ecr_repository" "app" { name = "my-application" image_tag_mutability = "IMMUTABLE"
image_scanning_configuration { scan_on_push = true }
encryption_configuration { encryption_type = "KMS" kms_key = aws_kms_key.ecr.arn }
tags = { Environment = "production" Team = "platform" } }
resource "aws_ecr_lifecycle_policy" "cleanup" { repository = aws_ecr_repository.app.name
policy = jsonencode({ rules = [ { rulePriority = 1 description = "Keep last 10 images" selection = { tagStatus = "tagged" tagPrefixList = ["v"] countType = "imageCountMoreThan" countNumber = 10 } action = { type = "expire" } }, { rulePriority = 2 description = "Remove untagged after 7 days" selection = { tagStatus = "untagged" countType = "sinceImagePushed" countUnit = "days" countNumber = 7 } action = { type = "expire" } } ] }) }
ECR Authentication
Login to ECR
aws ecr get-login-password --region us-east-1 |
docker login --username AWS --password-stdin
123456789.dkr.ecr.us-east-1.amazonaws.com
Push image
docker tag myapp:latest 123456789.dkr.ecr.us-east-1.amazonaws.com/myapp:latest docker push 123456789.dkr.ecr.us-east-1.amazonaws.com/myapp:latest
Harbor Self-Hosted
Docker Compose Setup
version: '3' services: harbor-core: image: goharbor/harbor-core:v2.9.0 container_name: harbor-core env_file: - ./common/config/core/env volumes: - ./common/config/core/certificates:/etc/core/certificates - ./common/config/core/key:/etc/core/key depends_on: - registry - redis - postgresql networks: - harbor
registry: image: goharbor/registry-photon:v2.9.0 container_name: registry volumes: - registry_data:/storage - ./common/config/registry:/etc/registry networks: - harbor
postgresql: image: goharbor/harbor-db:v2.9.0 container_name: harbor-db volumes: - database:/var/lib/postgresql/data environment: POSTGRES_PASSWORD: ${DB_PASSWORD} networks: - harbor
redis: image: goharbor/redis-photon:v2.9.0 container_name: harbor-redis volumes: - redis:/var/lib/redis networks: - harbor
nginx: image: goharbor/nginx-photon:v2.9.0 container_name: nginx ports: - "80:8080" - "443:8443" volumes: - ./common/config/nginx:/etc/nginx depends_on: - harbor-core networks: - harbor
volumes: registry_data: database: redis:
networks: harbor: driver: bridge
Image Security
Vulnerability Scanning
Trivy scan
trivy image myapp:latest
Grype scan
grype myapp:latest
ECR scan results
aws ecr describe-image-scan-findings
--repository-name myapp
--image-id imageTag=latest
Image Signing with Cosign
Generate key pair
cosign generate-key-pair
Sign image
cosign sign --key cosign.key myregistry/myapp:latest
Verify signature
cosign verify --key cosign.pub myregistry/myapp:latest
Content Trust (Docker)
Enable content trust
export DOCKER_CONTENT_TRUST=1
Sign and push
docker push myregistry/myapp:latest
Verify on pull
docker pull myregistry/myapp:latest
Kubernetes Integration
Image Pull Secret
apiVersion: v1 kind: Secret metadata: name: registry-credentials namespace: default type: kubernetes.io/dockerconfigjson data: .dockerconfigjson: | eyJhdXRocyI6eyJteXJlZ2lzdHJ5LmNvbSI6eyJ1c2VybmFtZSI6InVzZXIi LCJwYXNzd29yZCI6InBhc3MiLCJhdXRoIjoiZFhObGNqcHdZWE56In19fQ==
Deployment with Pull Secret
apiVersion: apps/v1 kind: Deployment metadata: name: myapp spec: replicas: 3 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp image: myregistry.com/myapp:v1.0.0 imagePullPolicy: Always imagePullSecrets: - name: registry-credentials
ServiceAccount Configuration
apiVersion: v1 kind: ServiceAccount metadata: name: myapp-sa namespace: default imagePullSecrets:
- name: registry-credentials
CI/CD Integration
GitHub Actions
name: Build and Push
on: push: branches: [main]
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to ECR
uses: aws-actions/amazon-ecr-login@v2
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: |
123456789.dkr.ecr.us-east-1.amazonaws.com/myapp:${{ github.sha }}
myuser/myapp:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max
GitLab CI
stages:
- build
- push
variables: IMAGE_NAME: $CI_REGISTRY_IMAGE
build: stage: build image: docker:24 services: - docker:24-dind before_script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY script: - docker build -t $IMAGE_NAME:$CI_COMMIT_SHA . - docker push $IMAGE_NAME:$CI_COMMIT_SHA only: - main
Cleanup Scripts
ECR Cleanup
import boto3 from datetime import datetime, timedelta
def cleanup_untagged_images(repository: str, days_old: int = 7): """Remove untagged images older than specified days.""" ecr = boto3.client('ecr')
response = ecr.describe_images(
repositoryName=repository,
filter={'tagStatus': 'UNTAGGED'}
)
cutoff = datetime.now() - timedelta(days=days_old)
images_to_delete = []
for image in response['imageDetails']:
if image['imagePushedAt'].replace(tzinfo=None) < cutoff:
images_to_delete.append({
'imageDigest': image['imageDigest']
})
if images_to_delete:
ecr.batch_delete_image(
repositoryName=repository,
imageIds=images_to_delete
)
print(f"Deleted {len(images_to_delete)} images")
Usage
cleanup_untagged_images('my-app', days_old=7)
Performance Optimization
Registry Caching
Docker daemon.json
{ "registry-mirrors": ["https://mirror.gcr.io"], "insecure-registries": [], "max-concurrent-downloads": 10, "max-concurrent-uploads": 5 }
Pull-Through Cache (Harbor)
Harbor project config
replication:
- name: docker-hub-proxy
type: pull-through
source: https://registry-1.docker.io
filters:
- name: library/* trigger: type: manual
Troubleshooting
Test connectivity
curl -v https://myregistry.com/v2/
Check authentication
docker login myregistry.com
Verify TLS
openssl s_client -connect myregistry.com:443 -servername myregistry.com
Clear credentials
docker logout myregistry.com rm ~/.docker/config.json
Debug pull issues
docker pull myregistry.com/myapp:latest --debug
Лучшие практики
-
Image immutability — используйте immutable tags
-
Vulnerability scanning — scan on push обязателен
-
Lifecycle policies — автоматическая очистка старых images
-
Content trust — подписывайте production images
-
Geo-replication — для global deployments
-
Access control — минимальные права через RBAC
-
Monitoring — алерты на failed pushes и pulls