「ビルドした成果物を共有フォルダにZIPで置いて手動連絡……そんな運用に疲れていませんか?」
前回のDay 42では、GitHub Actionsを使ってDockerイメージを自動ビルドし、コンテナ内で dotnet test を完結させるCIパイプラインを構築しました。
しかし、テストに合格したコンテナイメージは、クラウドランナーが終了すると同時に破棄されてしまいます。
「じゃあ、合格したコンテナイメージはどこに保管して、どうやって本番環境や社内メンバーに届けるの?」
その答えこそが、本日のテーマである「コンテナレジストリ(Container Registry)」です!
今回は、GitHub公式のGitHub Container Registry(ghcr.io)を活用し、テスト済みC#イメージをセキュアかつ完全に自動でプッシュ・保管・組織配布する極意を徹底解説します!
📋 本講義のカリキュラム目次
- 第1章: 手動ZIP配布の終焉 〜なぜ「コンテナレジストリ」が必要なのか?〜
- 第2章: GitHub Actions × GHCR 自動プッシュの全体像(3ステップフロー)
- 第3章: 【セキュリティ最前線】
GITHUB_TOKENによる安全認証と最小権限設計 - 第4章: 【実践コード】
.github/workflows/push-ghcr.ymlの完全実装 - 第5章: 【C#組織開発】社内共通ベースイメージ・APIコンテナのプライベート配布
- 第6章: 本日のまとめと次回予告(Day 44:Docker Compose による複数サービス連携CI)
第1章:手動ZIP配布の終焉 〜なぜ「コンテナレジストリ」が必要なのか?〜
30年以上の現場経験を持つエンジニアの方なら、かつてビルド成果物をどのように配布・展開していたか鮮明に覚えているはずです。
Visual Studioで発行(Publish)したASP.NETのDLLや構成ファイルをZIP圧縮し、社内LANのファイルサーバー(\\fileserver\release\MyApp_20261108_final_fix2.zip)にコピー。運用チームへ「最新版を置いたので解凍してIISのフォルダに上書きしてください」とメールで連絡する……。
この旧来の運用には、数え切れないほどの落とし穴がありました。
Dockerにおける「コンテナレジストリ(Container Registry)」とは、ビルドされたコンテナイメージを安全に保管し、バージョン管理された状態でチームや本番サーバーへ配信するための専用クラウドストレージです。
世界中で利用されている代表的なレジストリには以下のものがあります:
- GitHub Container Registry(ghcr.io): GitHub Packagesの一部。GitHubリポジトリと完全に統合され、追加の認証情報管理が不要で最も現代的。
- Docker Hub(docker.io): Docker公式の老舗レジストリ。公式ベースイメージの取得元として有名(無料枠のレート制限に注意)。
- クラウド専用レジストリ(Azure ACR / AWS ECR / GCP GCR): クラウド本番環境とのPrivate VPC接続や専用IAM連携に特化。
今回は、C#開発チームにおいてGitHub Actionsと最もシームレスに連携できる「GitHub Container Registry(GHCR)」を中心に解説を進めます!
第2章:GitHub Actions × GHCR 自動プッシュの全体像(3ステップフロー)
開発者がメインブランチにコードをマージ(またはリリース用Gitタグを発行)した瞬間から、GHCRに新しいイメージが登録されるまでの全自動連携フローを見てみましょう。
🚀 GHCR自動プッシュの3ステップ実行フロー
- 【ステップ①:CIテスト合格の確認】
PRがマージされmainブランチに反映された後、マルチステージビルド内でdotnet testを実行。100%合格したこと(またはCIジョブ成功)を前提に製品用イメージをビルドします。 - 【ステップ②:GITHUB_TOKEN による安全な認証】
GitHub Actionsのランナー環境に標準で自動供給されるGITHUB_TOKENを利用し、docker/login-action経由でghcr.ioにパスワードレスでログインします。 - 【ステップ③:メタデータ付与&高速プッシュ】
docker/metadata-actionがGitコミットSHA(例:sha-a1b2c3d)やリリースバージョン(例:v1.2.0)を自動タグ付けし、変更レイヤーのみをGHCRへ差分プッシュ完了します。
第3章:【セキュリティ最前線】GITHUB_TOKEN による安全認証と最小権限設計
CI/CDパイプラインを構築する際、ベテランエンジニアが最も懸念するのが「セキュリティと認証情報の管理」です。
Docker Hubや外部レジストリを利用する場合、管理者のユーザー名とAPIトークン(またはパスワード)をGitHub Secrets(環境変数)に登録し、それを使ってログインするのが従来の一般的な手法でした。
しかし、個人アカウントに紐付いた永続トークンは、「退職者の権限残存」や「漏洩時の広範な影響」という深刻なセキュリティリスクを孕んでいます。
そこでGHCRの最大の強みとなるのが、GitHub Actionsがジョブ実行ごとに使い捨てで自動発行するsecrets.GITHUB_TOKENです!
🔑 GITHUB_TOKEN が究極にセキュアである3つの理由
- 完全自動ローテーション: ワークフローが起動した瞬間に生成され、ジョブ終了時に即座に失効します。パスワード漏洩の心配が根本的にゼロになります。
- リポジトリスコープの限定: そのリポジトリ(および同一Organizationの関連パッケージ)のみにアクセスが制限され、他のリポジトリへ横展開される危険がありません。
- YAML内での最小権限(Least Privilege)宣言: デフォルトは読み取り専用であり、プッシュに必要な権限(
packages: write)だけを明示的に指定します。
ワークフローファイルの冒頭で、以下のように最小権限を宣言します:
permissions: contents: read # ソースコードのチェックアウト用(読み取りのみ) packages: write # GHCRへのコンテナイメージ書き込み権限
第4章:【実践コード】.github/workflows/push-ghcr.yml の完全実装
それでは、C# Web API(.NET 8/9)のプロジェクトをGHCRへ自動プッシュする本番レベルのGitHub Actionsワークフロー完全版を見ていきましょう。
このYAMLファイルは、Docker公式の標準Action(setup-buildx-action, login-action, metadata-action, build-push-action)を採用しており、業界のデファクトスタンダード構成です。
# .github/workflows/push-ghcr.yml
name: Build and Push Docker Image to GHCR
on:
push:
branches:
- main # mainブランチ反映時に自動実行
tags:
- 'v*.*.*' # v1.0.0 などのリリースタグプッシュ時に実行
env:
REGISTRY: ghcr.io
# イメージ名: ghcr.io/オーナー名/リポジトリ名 (小文字必須)
IMAGE_NAME: ${ github.repository }
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
# 1. リポジトリのソースコードを取得
- name: Checkout repository
uses: actions/checkout@v4
# 2. 高度なビルド機能(BuildKit)を有効化
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# 3. GitHub Container Registry への安全ログイン
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ${ env.REGISTRY }
username: ${ github.actor }
password: ${ secrets.GITHUB_TOKEN }
# 4. Gitコミットやタグに基づきイメージメタデータ(タグ・ラベル)を自動抽出
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${ env.REGISTRY }/${ env.IMAGE_NAME }
tags: |
type=ref,event=branch
type=semver,pattern={version}
type=sha,format=short,prefix=sha-
# 5. マルチステージビルド(テスト実行含む)& GHCR への自動プッシュ
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
push: true
tags: ${ steps.meta.outputs.tags }
labels: ${ steps.meta.outputs.labels }
cache-from: type=gha
cache-to: type=gha,mode=max
💡 C#エンジニアが押さえておくべき重要Tips
① GHCRのイメージ名は「完全小文字」が必須: GitHubのアカウント名やリポジトリ名に大文字が含まれている場合(例: MyCompany/OrderApi)、Dockerのタグ仕様によりエラーになります。docker/metadata-action は自動的に小文字変換を行ってくれるため安心です。
② cache-to: type=gha,mode=max の威力: 最終的なRuntimeイメージだけでなく、中間のSDKビルドレイヤーやNuGet復元キャッシュもGitHub Actionsのキャッシュストレージに保存されます。2回目以降のビルド時間が劇的に短縮されます。
第5章:【C#組織開発】社内共通ベースイメージ・APIコンテナのプライベート配布
企業内でのC#開発において、GHCRの真価が発揮されるのが「社内標準ベースイメージ」や「マイクロサービスコンテナ」の組織内共有です。
多くのエンタープライズ現場では、各開発チームがそれぞれ独自にDockerfileを作成し、バラバラなバージョンの.NET SDKを使っていたり、社内ルート証明書や共通ロギングライブラリの導入が後手後手になっていたりします。
🏢 社内共通ベースイメージの配信フロー
インフラ基盤チームが社内標準ルールを満たしたC#ベースイメージをGHCRにプッシュしておきます。
一般の開発チームは、Dockerfileの先頭でそのイメージを指定するだけで、社内セキュリティ基準を100%満たしたコンテナを即座に利用できます!
# 各業務開発チームのDockerfile # 社内GHCRで事前配布されている標準ランタイムイメージを継承 FROM ghcr.io/my-company/dotnet-secure-base:8.0-alpine WORKDIR /app COPY ./publish/ . ENTRYPOINT ["dotnet", "OrderMicroservice.dll"]
ローカルPCや開発者がGHCRからイメージをプルする手順
プライベートリポジトリとしてGHCRに保管されたコンテナイメージを、手元のWindows PCや開発環境でプルして動かすには、一度だけPersonal Access Token(PAT)を使ってログインします:
# 1. GitHubのPAT(read:packages 権限付き)でGHCRにログイン echo "YOUR_GITHUB_PAT" | docker login ghcr.io -u YOUR_GITHUB_USERNAME --password-stdin # 2. 社内プライベートイメージをローカルにプル docker pull ghcr.io/my-company/order-api:sha-a1b2c3d # 3. ローカルで即座に起動・動作確認 docker run -d -p 8080:8080 --name test-api ghcr.io/my-company/order-api:sha-a1b2c3d
これで、ファイルサーバーから巨大なZIPファイルを落として手動展開していた時代とは比べ物にならない、安全・迅速・正確なデリバリー体制が完成しました!
第6章:本日のまとめと次回予告
✓ 本講義で習得した最重要ポイント
- コンテナレジストリの本質: 手動ZIP共有の混沌を脱し、不変性(Immutable)とGit権限連携を備えたクラウド保管庫を活用する。
- GitHub Container Registry(GHCR): GitHubリポジトリと完全統合され、外部クレデンシャル不要で最もクリーンに運用できる。
- GITHUB_TOKEN の安全性: 実行時に最小権限(
packages: write)で自動発行・即時破棄されるため、パスワード漏洩リスクがゼロ。 - docker/metadata-action の活用: GitコミットSHAやSemVerタグを自動抽出し、人的ミスによるタグ付け事故を防止する。
- 組織内でのベースイメージ共有: 社内標準のC#イメージを集中配布することで、エンタープライズ全体のセキュリティと生産性を底上げする。
📣 次回予告:Day 44
「Docker Compose を使った複数コンテナ連携CI 〜ASP.NET Core と SQL Server / Redis を丸ごと立ち上げて実行する本番同等インテグレーションテスト〜」
単体テストだけでなく、データベース(SQL Server)やキャッシュ(Redis)と実際に通信する「統合テスト(Integration Test)」をCI上で自動実行したい!
次回は、docker compose をGitHub Actionsクラウドランナー内で一括起動し、本番環境と寸分違わぬ実環境テストを自動で完結させる高度なCIテクニックを伝授します。お楽しみに!
コメント
コメントを投稿