Claude-skill-registry container-registry-setup
Эксперт по container registry. Используй для настройки ECR, Harbor, Docker Hub, image security и CI/CD интеграции.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/container-registry-setup" ~/.claude/skills/majiayu000-claude-skill-registry-container-registry-setup && rm -rf "$T"
manifest:
skills/data/container-registry-setup/SKILL.mdsource content
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