MCP HubMCP Hub
스킬 목록으로 돌아가기

setup-container-registry

pjt222
업데이트됨 5 days ago
10 조회
17
2
17
GitHub에서 보기
문서aiautomation

정보

이 스킬은 Docker Hub, GHCR, Harbor와 같은 컨테이너 레지스트리를 안전한 이미지 배포를 위해 구성합니다. 취약점 스캔, 이미지 태깅, 보존 정책, CI/CD 통합 설정을 자동화합니다. 개인 레지스트리 구축, Docker Hub에서 마이그레이션, 또는 파이프라인에 보안 스캔을 도입할 때 사용하세요.

빠른 설치

Claude Code

추천
기본
npx skills add pjt222/agent-almanac -a claude-code
플러그인 명령대체
/plugin add https://github.com/pjt222/agent-almanac
Git 클론대체
git clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/setup-container-registry

Claude Code에서 이 명령을 복사하여 붙여넣어 스킬을 설치하세요

문서

Setup Container Registry

Configure production-ready container registries with security scanning, access control, and automated CI/CD integration.

When to Use

  • Setting up private container registry for organization
  • Migrating from Docker Hub to self-hosted or alternative registries
  • Implementing image vulnerability scanning in CI/CD pipelines
  • Managing multi-architecture images (amd64, arm64) with manifests
  • Enforcing image signing and provenance verification
  • Configuring automatic image cleanup and retention policies

Inputs

  • Required: Docker or Podman installed locally
  • Required: Registry credentials (personal access tokens, service accounts)
  • Optional: Self-hosted infrastructure for Harbor deployment
  • Optional: Kubernetes cluster for registry integration
  • Optional: Cosign/Notary for image signing
  • Optional: Trivy or Clair for vulnerability scanning

Procedure

See Extended Examples for complete configuration files and templates.

Step 1: Configure GitHub Container Registry (ghcr.io)

Set up GitHub Container Registry with personal access tokens and CI/CD integration.

# Create GitHub Personal Access Token
# Go to: Settings → Developer settings → Personal access tokens → Tokens (classic)
# Required scopes: write:packages, read:packages, delete:packages

# Login to ghcr.io
echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin

# Verify login
docker info | grep -A 5 "Registry:"

# Tag image for ghcr.io
docker tag myapp:latest ghcr.io/USERNAME/myapp:latest
docker tag myapp:latest ghcr.io/USERNAME/myapp:v1.0.0

# Push image
docker push ghcr.io/USERNAME/myapp:latest
docker push ghcr.io/USERNAME/myapp:v1.0.0

# Configure in GitHub Actions
cat > .github/workflows/docker-build.yml <<'EOF'
name: Build and Push Docker Image
locale: wenyan-lite
source_locale: en
source_commit: 82c77053
translator: "Julius Brussee homage — caveman"
translation_date: "2026-04-19"

on:
  push:
    branches: [main]
    tags: ['v*']

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Log in to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=ref,event=branch
            type=ref,event=pr
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}
            type=sha,prefix={{branch}}-

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          platforms: linux/amd64,linux/arm64
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max
EOF

# Make package public (default is private)
# Go to: github.com/USERNAME?tab=packages → Select package → Package settings → Change visibility

# Pull image (public packages don't require authentication)
docker pull ghcr.io/USERNAME/myapp:latest

Expected: GitHub token has package permissions. Docker login succeeds. Images push to ghcr.io with proper tagging. GitHub Actions workflow builds multi-architecture images with automated tagging. Package visibility configured correctly.

On failure: For authentication errors, verify token has write:packages scope and hasn't expired. For push failures, check repository name matches image name (case-sensitive). For workflow failures, verify permissions: packages: write is set. For public packages not accessible, wait up to 10 minutes for visibility change to propagate.

Step 2: Configure Docker Hub with Automated Builds

Set up Docker Hub repository with access tokens and vulnerability scanning.

# Create Docker Hub access token
# Go to: hub.docker.com → Account Settings → Security → New Access Token

# Login to Docker Hub
echo $DOCKERHUB_TOKEN | docker login -u USERNAME --password-stdin

# Create repository
# Go to: hub.docker.com → Repositories → Create Repository
# Select: public or private, enable vulnerability scanning (Pro/Team plan)

# Tag 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

# Configure automated builds (legacy feature, deprecated)
# Modern approach: Use GitHub Actions with Docker Hub

cat > .github/workflows/dockerhub.yml <<'EOF'
name: Docker Hub Push
locale: wenyan-lite
source_locale: en
source_commit: 82c77053
translator: "Julius Brussee homage — caveman"
translation_date: "2026-04-19"

on:
  push:
    branches: [main]
    tags: ['v*']

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - 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,linux/arm/v7
          push: true
          tags: |
            ${{ secrets.DOCKERHUB_USERNAME }}/myapp:latest
            ${{ secrets.DOCKERHUB_USERNAME }}/myapp:${{ github.ref_name }}
          build-args: |
            BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
            VCS_REF=${{ github.sha }}

      - name: Update Docker Hub description
        uses: peter-evans/dockerhub-description@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
          repository: ${{ secrets.DOCKERHUB_USERNAME }}/myapp
          readme-filepath: ./README.md
EOF

# View vulnerability scan results
# Go to: hub.docker.com → Repository → Tags → View scan results

# Configure webhook for automated triggers
# Go to: Repository → Webhooks → Add webhook
WEBHOOK_URL="https://example.com/webhook"
curl -X POST https://hub.docker.com/api/content/v1/repositories/USERNAME/myapp/webhooks \
  -H "Authorization: Bearer $DOCKERHUB_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"name\":\"CI Trigger\",\"webhook_url\":\"$WEBHOOK_URL\"}"

Expected: Docker Hub access token created with read/write permissions. Images push successfully with multi-architecture support. Vulnerability scans run automatically (if enabled). README syncs from GitHub. Webhooks trigger on image push.

On failure: For rate limit errors, upgrade to Pro plan or implement pull-through cache. For scan failures, verify plan includes scanning (not available on free tier). For multi-arch build failures, ensure QEMU installed with docker run --privileged --rm tonistiigi/binfmt --install all. For webhook failures, verify endpoint is publicly accessible and returns 200 OK.

Step 3: Deploy Harbor Self-Hosted Registry

Install Harbor with Helm for enterprise registry with RBAC and replication.

# Add Harbor Helm repository
helm repo add harbor https://helm.gopharbor.io
helm repo update

# Create namespace
kubectl create namespace harbor

# Create values file
cat > harbor-values.yaml <<EOF
expose:
  type: ingress
  tls:
    enabled: true
    certSource: secret
    secret:
      secretName: harbor-tls
  ingress:
    hosts:
      core: harbor.example.com
    className: nginx
    annotations:
      cert-manager.io/cluster-issuer: letsencrypt-prod

externalURL: https://harbor.example.com

persistence:
  enabled: true
  persistentVolumeClaim:
    registry:
      size: 200Gi
      storageClass: gp3
    database:
      size: 10Gi
      storageClass: gp3

harborAdminPassword: "ChangeMe123!"

database:
  type: internal  # Use external: postgres for production

redis:
  type: internal  # Use external: redis for production

trivy:
  enabled: true
  skipUpdate: false

notary:
  enabled: true  # Image signing

chartmuseum:
  enabled: true  # Helm chart storage
EOF

# Install Harbor
helm install harbor harbor/harbor \
  --namespace harbor \
  --values harbor-values.yaml \
  --timeout 10m

# Wait for pods to be ready
kubectl get pods -n harbor -w

# Get admin password
kubectl get secret -n harbor harbor-core -o jsonpath='{.data.HARBOR_ADMIN_PASSWORD}' | base64 -d

# Access Harbor UI
echo "Harbor UI: https://harbor.example.com"
echo "Username: admin"

# Login via Docker CLI
docker login harbor.example.com
# Username: admin
# Password: (from above)

# Create project via API
curl -u "admin:$HARBOR_PASSWORD" -X POST \
  https://harbor.example.com/api/v2.0/projects \
  -H "Content-Type: application/json" \
  -d '{
    "project_name": "myapp",
    "public": false,
    "metadata": {
      "auto_scan": "true",
      "severity": "high",
      "enable_content_trust": "true"
    }
  }'

# Tag and push to Harbor
docker tag myapp:latest harbor.example.com/myapp/app:latest
docker push harbor.example.com/myapp/app:latest

# Configure robot account for CI/CD
# UI: Administration → Robot Accounts → New Robot Account
# Permissions: Pull, Push to specific projects

# Use robot account in CI/CD
docker login harbor.example.com -u 'robot$myapp-ci' -p "$ROBOT_TOKEN"

Expected: Harbor deploys to Kubernetes with PostgreSQL and Redis. Ingress configured with TLS. Admin UI accessible. Projects created with vulnerability scanning enabled. Robot accounts provide CI/CD authentication. Trivy scans images on push.

On failure: For database connection errors, check PostgreSQL pod logs with kubectl logs -n harbor harbor-database-0. For Ingress issues, verify DNS points to LoadBalancer and cert-manager issued certificate. For Trivy failures, check if vulnerability database downloaded successfully. For storage issues, verify PVCs bound with kubectl get pvc -n harbor.

Step 4: Implement Image Tagging Strategy and Retention Policies

Configure semantic versioning, immutable tags, and automatic cleanup.

# Tagging best practices
# 1. Semantic versioning
docker tag myapp:latest harbor.example.com/myapp/app:v1.2.3
docker tag myapp:latest harbor.example.com/myapp/app:v1.2
docker tag myapp:latest harbor.example.com/myapp/app:v1
docker tag myapp:latest harbor.example.com/myapp/app:latest
# ... (see EXAMPLES.md for complete configuration)

Expected: Images tagged with semantic versions, commit SHAs, and environment labels. Retention policies automatically clean old images based on age, pull activity, or count limits. Production tags (v* pattern) retained longer than development branches. Untagged images deleted to save storage.

On failure: For retention not triggering, verify cron schedule syntax and Harbor timezone settings. For accidental deletion of production images, implement immutable tags with Harbor tag immutability rules. For storage still growing, check artifact retention includes Helm charts and other OCI artifacts. For policy conflicts, ensure retention rules use or algorithm and don't contradict each other.

Step 5: Configure Kubernetes Image Pull Secrets

Set up registry authentication for Kubernetes clusters.

# Create Docker registry secret
kubectl create secret docker-registry ghcr-secret \
  --docker-server=ghcr.io \
  --docker-username=USERNAME \
  --docker-password=$GITHUB_TOKEN \
  [email protected] \
# ... (see EXAMPLES.md for complete configuration)

Expected: Image pull secrets created in target namespaces. Pods successfully pull images from private registries. Service accounts include imagePullSecrets. No ImagePullBackOff errors.

On failure: For authentication errors, verify credentials with docker login manually. For secret not found, check namespace matches Pod namespace. For still failing, decode secret and verify JSON structure with kubectl get secret ghcr-secret -o jsonpath='{.data.\.dockerconfigjson}' | base64 -d | jq. For token expiration, rotate credentials and update secrets.

Step 6: Enable Vulnerability Scanning and Image Signing

Integrate Trivy scanning and Cosign for image provenance.

# Install Trivy CLI
wget https://github.com/aquasecurity/trivy/releases/latest/download/trivy_0.47.0_Linux-64bit.tar.gz
tar zxvf trivy_0.47.0_Linux-64bit.tar.gz
sudo mv trivy /usr/local/bin/

# Scan local image
# ... (see EXAMPLES.md for complete configuration)

Expected: Trivy scans detect vulnerabilities with severity ratings. SARIF results upload to GitHub Security tab. Critical vulnerabilities fail CI/CD builds. Cosign signs images with keypair or keyless (Fulcio). Verification succeeds for signed images. Kyverno blocks unsigned images in Kubernetes.

On failure: For Trivy database download failures, run trivy image --download-db-only. For false positives, create .trivyignore file with CVE IDs and justifications. For Cosign signature failures, verify image digest hasn't changed (signatures apply to specific digest, not tags). For Kyverno policy failures, check image reference pattern matches actual image names. For keyless signing, verify OIDC token has sufficient permissions.

Validation

  • Registry accessible via Docker CLI login
  • Images push and pull successfully with proper authentication
  • Multi-architecture images build and manifest created
  • Vulnerability scanning runs automatically on image push
  • Retention policies clean old images on schedule
  • Kubernetes clusters can pull images via imagePullSecrets
  • Image signatures verified before deployment
  • Webhook notifications trigger on image updates
  • Registry UI shows scan results and artifact metadata

Common Pitfalls

  • Public images by default: GitHub packages are private by default, Docker Hub public. Verify visibility settings match security requirements.

  • Token expiration: Personal access tokens expire, breaking CI/CD. Use non-expiring tokens for automation or implement rotation.

  • Untagged image accumulation: Build process creates untagged images consuming storage. Enable automatic cleanup of untagged artifacts.

  • Missing multi-arch support: Builds only amd64, fails on ARM instances. Use docker buildx with --platform flag for cross-platform builds.

  • No rate limit protection: Free Docker Hub accounts limited to 100 pulls/6h. Implement pull-through cache or upgrade plan.

  • Mutable tags: latest tag overwritten breaks reproducibility. Use immutable tags (commit SHA, semantic version) for production.

  • Insecure registry communication: Self-hosted registry without TLS. Always use HTTPS with valid certificates.

  • No access control: Single credential shared across teams. Implement RBAC with project-specific robot accounts.

Related Skills

  • create-r-dockerfile - Building container images for registry
  • optimize-docker-build-cache - Efficient image builds for registry push
  • build-ci-cd-pipeline - Automated registry push in CI/CD
  • deploy-to-kubernetes - Pulling images from registry
  • implement-gitops-workflow - Image promotion between registries

GitHub 저장소

pjt222/agent-almanac
경로: i18n/wenyan-lite/skills/setup-container-registry
0
agentsagentskillsai-assisted-developmentclaude-codeskillsteams

연관 스킬

railway-docs

문서

이 스킬은 Railway의 기능, 작동 방식 또는 특정 문서 URL에 대한 질문에 답하기 위해 최신 Railway 문서를 가져옵니다. 개발자들이 Railway의 공식 소스로부터 정확하고 최신 정보를 직접 받을 수 있도록 보장합니다. 사용자가 Railway의 작동 방식을 묻거나 Railway 문서를 참조할 때 사용하세요.

스킬 보기

n8n-code-python

문서

이 Claude Skill은 n8n의 Code 노드에서 Python 코드를 작성할 때 전문적인 지침을 제공하며, 특히 Python 표준 라이브러리 사용과 n8n의 특수 구문인 `_input`, `_json`, `_node` 작업에 중점을 둡니다. 이는 개발자가 n8n 내에서 Python의 제한 사항을 이해하도록 돕고, 대부분의 워크플로에는 JavaScript 사용을 권장하면서도 특정 데이터 변환 요구사항에 대한 Python 솔루션을 제안합니다.

스킬 보기

archon

문서

Archon 스킬은 REST API를 통해 RAG 기반 시맨틱 검색과 프로젝트 관리를 제공합니다. 이 스킬을 사용하여 문서 검색, 계층적 프로젝트/태스크 관리, 문서 업로드 기능을 갖춘 지식 검색을 수행할 수 있습니다. 외부 문서를 검색할 때는 다른 소스를 사용하기 전에 항상 Archon을 최우선으로 활용하세요.

스킬 보기

n8n-code-javascript

문서

이 Claude Skill은 n8n의 Code 노드에서 JavaScript 코드 작성에 대한 전문적인 지침을 제공합니다. `$input`/`$json` 변수, HTTP 헬퍼, DateTime 처리와 같은 필수적인 n8n 특정 구문을 다루며 일반적인 오류를 해결합니다. Code 노드에서 사용자 정의 JavaScript 처리가 필요한 n8n 워크플로우를 개발할 때 활용하세요.

스킬 보기