setup-container-registry
GitHub Container Registry(ghcr.io)、Docker Hub、Harborなど複数のコンテナイメージレジストリを設定でき、自動スキャン、タグ付け戦略、保持ポリシー、CI/CD統合によって安全なイメージ配布を実現します。プライベートレジストリの構築、Docker Hubから自社ホスト型レジストリへの移行、CI/CDパイプラインへの脆弱性スキャン導入、マルチアーキテクチャイメージの管理、イメージ署名の強制、自動クリーンアップと保持ポリシーの設定が必要な場合に活用できます。
description の原文を見る
Configure container image registries including GitHub Container Registry (ghcr.io), Docker Hub, and Harbor with automated image scanning, tagging strategies, retention policies, and CI/CD integration for secure image distribution. Use when setting up a private container registry, migrating from Docker Hub to self-hosted registries, implementing vulnerability scanning in CI/CD pipelines, managing multi-architecture images, enforcing image signing, or configuring automatic cleanup and retention policies.
SKILL.md 本文
コンテナレジストリの設定
セキュリティスキャン、アクセス制御、自動 CI/CD インテグレーションを備えた本番環境対応のコンテナレジストリを設定します。
使用するタイミング
- 組織用のプライベートコンテナレジストリを設定する
- Docker Hub から自己ホスト型またはその他のレジストリに移行する
- CI/CD パイプラインにイメージ脆弱性スキャンを実装する
- マニフェストを使用してマルチアーキテクチャイメージ (amd64、arm64) を管理する
- イメージ署名とプロヴェナンス検証を強制する
- 自動イメージクリーンアップと保持ポリシーを設定する
入力
- 必須: Docker または Podman がローカルにインストールされている
- 必須: レジストリ認証情報 (個人用アクセストークン、サービスアカウント)
- オプション: Harbor デプロイ用の自己ホスト型インフラストラクチャ
- オプション: レジストリインテグレーション用の Kubernetes クラスタ
- オプション: イメージ署名用の Cosign/Notary
- オプション: 脆弱性スキャン用の Trivy または Clair
手順
完全な設定ファイルとテンプレートについては、拡張例を参照してください。
ステップ 1: GitHub Container Registry (ghcr.io) を設定する
GitHub Container Registry を個人用アクセストークンと CI/CD インテグレーションで設定します。
# 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
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
想定結果: GitHub トークンがパッケージ権限を持つ。Docker ログインが成功する。イメージが適切なタグ付けで ghcr.io にプッシュされる。GitHub Actions ワークフローが自動タグ付けでマルチアーキテクチャイメージをビルドする。パッケージの可視性が正しく設定される。
失敗時: 認証エラーの場合、トークンが write:packages スコープを持ち、期限切れでないことを確認してください。プッシュエラーの場合、リポジトリ名がイメージ名と一致すること (大文字小文字を区別) を確認してください。ワークフロー失敗の場合、permissions: packages: write が設定されていることを確認してください。公開パッケージにアクセスできない場合、可視性変更の反映に最大 10 分待機してください。
ステップ 2: Docker Hub を自動ビルド機能で設定する
Docker Hub リポジトリをアクセストークンと脆弱性スキャンで設定します。
# 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
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\"}"
想定結果: Docker Hub アクセストークンが読み取り/書き込み権限で作成される。マルチアーキテクチャサポート付きのイメージが正常にプッシュされる。脆弱性スキャンが自動実行される (有効な場合)。README が GitHub から同期される。ウェブフックはイメージプッシュ時にトリガーされる。
失敗時: レート制限エラーの場合、Pro プランにアップグレードするか、プルスルーキャッシュを実装してください。スキャン失敗の場合、スキャンを含むプランを確認してください (無料プランでは利用不可)。マルチアーキテクチャビルド失敗の場合、docker run --privileged --rm tonistiigi/binfmt --install all を使用して QEMU がインストールされていることを確認してください。ウェブフック失敗の場合、エンドポイントがパブリックにアクセス可能で 200 OK を返すことを確認してください。
ステップ 3: Harbor 自己ホスト型レジストリをデプロイする
Helm を使用して RBAC とレプリケーション機能を備えたエンタープライズレジストリ Harbor をインストールします。
# 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"
想定結果: Harbor が PostgreSQL と Redis を使用して Kubernetes にデプロイされる。TLS で Ingress が設定される。管理者 UI にアクセス可能。脆弱性スキャン有効でプロジェクト作成。ロボットアカウントが CI/CD 認証を提供。Trivy がプッシュ時にイメージをスキャン。
失敗時: データベース接続エラーの場合、kubectl logs -n harbor harbor-database-0 で PostgreSQL ポッドログを確認してください。Ingress 問題の場合、DNS が LoadBalancer を指し、cert-manager が証明書を発行したことを確認してください。Trivy 失敗の場合、脆弱性データベースが正常にダウンロードされたかを確認してください。ストレージ問題の場合、kubectl get pvc -n harbor で PVC がバインドされていることを確認してください。
ステップ 4: イメージタグ付け戦略と保持ポリシーを実装する
セマンティックバージョニング、イミュータブルタグ、自動クリーンアップを設定します。
# 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)
想定結果: イメージがセマンティックバージョン、コミット SHA、環境ラベルでタグ付けされる。保持ポリシーが経過時間、プル活動、カウント制限に基づいて古いイメージを自動クリーンアップ。本番タグ (v* パターン) は開発ブランチより長く保持。タグなしイメージはストレージ節約のため削除。
失敗時: 保持ポリシーがトリガーされない場合、cron スケジュール構文と Harbor タイムゾーン設定を確認してください。本番イメージの誤削除の場合、Harbor タグイミュータビリティルールでイミュータブルタグを実装してください。ストレージが引き続き増加する場合、保持ルールが Helm チャートと他の OCI アーティファクトを含むことを確認してください。ポリシー競合の場合、保持ルールが or アルゴリズムを使用し、互いに矛盾しないことを確認してください。
ステップ 5: Kubernetes イメージプルシークレットを設定する
Kubernetes クラスタのレジストリ認証をセットアップします。
# Create Docker registry secret
kubectl create secret docker-registry ghcr-secret \
--docker-server=ghcr.io \
--docker-username=USERNAME \
--docker-password=$GITHUB_TOKEN \
--docker-email=user@example.com \
# ... (see EXAMPLES.md for complete configuration)
想定結果: イメージプルシークレットがターゲットネームスペースで作成される。ポッドがプライベートレジストリからイメージを正常にプル。サービスアカウントが imagePullSecrets を含む。ImagePullBackOff エラーなし。
失敗時: 認証エラーの場合、手動で docker login により認証情報を確認してください。シークレットが見つからない場合、ネームスペースがポッドネームスペースと一致することを確認してください。それでも失敗する場合、kubectl get secret ghcr-secret -o jsonpath='{.data.\.dockerconfigjson}' | base64 -d | jq でシークレットをデコードして JSON 構造を確認してください。トークン期限切れの場合、認証情報をローテーションしてシークレットを更新してください。
ステップ 6: 脆弱性スキャンとイメージ署名を有効にする
Trivy スキャンと Cosign によるイメージプロヴェナンスを統合します。
# 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)
想定結果: Trivy が重大度評価付きの脆弱性を検出。SARIF 結果が GitHub Security タブにアップロード。重大な脆弱性が CI/CD ビルドに失敗。Cosign がキーペアまたはキーレス (Fulcio) でイメージに署名。署名付きイメージの検証が成功。Kyverno が Kubernetes の未署名イメージをブロック。
失敗時: Trivy データベースダウンロード失敗の場合、trivy image --download-db-only を実行してください。誤検知の場合、CVE ID と正当理由を含む .trivyignore ファイルを作成してください。Cosign 署名失敗の場合、イメージダイジェストが変更されていないことを確認してください (署名は特定のダイジェストに適用され、タグには適用されません)。Kyverno ポリシー失敗の場合、イメージ参照パターンが実際のイメージ名と一致することを確認してください。キーレス署名の場合、OIDC トークンに十分な権限があることを確認してください。
検証
- レジストリが Docker CLI ログイン経由でアクセス可能
- イメージが正しい認証でプッシュおよびプル成功
- マルチアーキテクチャイメージがビルドされ、マニフェスト作成
- 脆弱性スキャンがイメージプッシュ時に自動実行
- 保持ポリシーがスケジュール時に古いイメージをクリーンアップ
- Kubernetes クラスタが imagePullSecrets でイメージをプル可能
- イメージ署名がデプロイ前に検証
- ウェブフック通知がイメージ更新時にトリガー
- レジストリ UI がスキャン結果とアーティファクトメタデータを表示
よくある落とし穴
-
デフォルトでパブリック: GitHub パッケージはデフォルトプライベート、Docker Hub はパブリック。可視性設定がセキュリティ要件と一致することを確認してください。
-
トークン期限切れ: 個人用アクセストークンの期限切れが CI/CD を中断。自動化にはトークン無期限を使用するか、ローテーション実装してください。
-
タグなしイメージ蓄積: ビルドプロセスがストレージを消費するタグなしイメージを作成。タグなしアーティファクト自動クリーンアップを有効にしてください。
-
マルチアーキテクチャサポート欠落: amd64 のみビルドで ARM インスタンスで失敗。クロスプラットフォームビルドに
docker buildxと--platformフラグを使用してください。 -
レート制限対策なし: 無料 Docker Hub アカウントは 6 時間で 100 プルに制限。プルスルーキャッシュを実装するか、プランをアップグレードしてください。
-
ミュータブルタグ:
latestタグの上書きが再現性を破壊。本番環境にはイミュータブルタグ (コミット SHA、セマンティックバージョン) を使用してください。 -
セキュアでないレジストリ通信: TLS なしの自己ホスト型レジストリ。常に有効な証明書で HTTPS を使用してください。
-
アクセス制御なし: チーム間で共有される単一認証情報。プロジェクト固有のロボットアカウントで RBAC を実装してください。
関連スキル
create-r-dockerfile- レジストリ用コンテナイメージビルドoptimize-docker-build-cache- レジストリプッシュ用の効率的なイメージビルドbuild-ci-cd-pipeline- CI/CD 内の自動レジストリプッシュdeploy-to-kubernetes- レジストリからイメージをプルimplement-gitops-workflow- レジストリ間イメージプロモーション
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- pjt222
- リポジトリ
- pjt222/agent-almanac
- ライセンス
- MIT
- 最終更新
- 2026/5/11
Source: https://github.com/pjt222/agent-almanac / ライセンス: MIT