スキップしてメイン コンテンツに移動

【Day 43】GitHub Packages (GHCR) / Docker Hub への自動プッシュ 〜テスト済みコンテナをクラウドレジストリへ安全・高速に自動保管・配布する本番CI/CD〜

Day 43 アイキャッチ
▲ Day 43: GitHub Packages (GHCR) / Docker Hub への自動プッシュ 〜テスト済みコンテナをクラウドレジストリへ安全・高速に自動保管・配布する本番CI/CD〜
🐳

「ビルドした成果物を共有フォルダに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のフォルダに上書きしてください」とメールで連絡する……。

この旧来の運用には、数え切れないほどの落とし穴がありました。

ファイルサーバー手動共有 vs コンテナレジストリ
▲ 【図解①】社内ファイルサーバーの手動ZIP配布による混沌から、タグ付き・権限管理されたGHCRコンテナレジストリへの進化
比較項目 旧来:ファイルサーバー手動ZIP配布 現代:コンテナレジストリ(GHCR)
バージョニング ファイル名頼み(_v2_fix等の混沌) GitコミットSHA・SemVerタグによる厳格管理
改ざん防止・完全性 誰でも上書き可能・壊れたZIPのリスク SHA256ダイジェストによる不変(Immutable)保証
アクセス権限管理 共有フォルダのACL任せで権限が曖昧 GitHubリポジトリ・Organizationのロールと完全連動
転送・配布効率 毎回数百MBの全体ファイルを丸ごと転送 Dockerレイヤー差分転送により数MBで爆速完了

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に新しいイメージが登録されるまでの全自動連携フローを見てみましょう。

イメージ自動プッシュの3ステップ
▲ 【図解②】テスト合格 ➔ GITHUB_TOKENによる安全認証 ➔ バージョンタグ付きレジストリ保管に至る全自動パイプライン

🚀 GHCR自動プッシュの3ステップ実行フロー

  1. 【ステップ①:CIテスト合格の確認】
    PRがマージされmainブランチに反映された後、マルチステージビルド内で dotnet test を実行。100%合格したこと(またはCIジョブ成功)を前提に製品用イメージをビルドします。
  2. 【ステップ②:GITHUB_TOKEN による安全な認証】
    GitHub Actionsのランナー環境に標準で自動供給される GITHUB_TOKEN を利用し、docker/login-action 経由で ghcr.io にパスワードレスでログインします。
  3. 【ステップ③:メタデータ付与&高速プッシュ】
    docker/metadata-action がGitコミットSHA(例: sha-a1b2c3d)やリリースバージョン(例: v1.2.0)を自動タグ付けし、変更レイヤーのみをGHCRへ差分プッシュ完了します。

第3章:【セキュリティ最前線】GITHUB_TOKEN による安全認証と最小権限設計

CI/CDパイプラインを構築する際、ベテランエンジニアが最も懸念するのが「セキュリティと認証情報の管理」です。

Docker Hubや外部レジストリを利用する場合、管理者のユーザー名とAPIトークン(またはパスワード)をGitHub Secrets(環境変数)に登録し、それを使ってログインするのが従来の一般的な手法でした。

しかし、個人アカウントに紐付いた永続トークンは、「退職者の権限残存」や「漏洩時の広範な影響」という深刻なセキュリティリスクを孕んでいます。

GITHUB_TOKEN によるセキュア認証
▲ 【図解③】漏洩リスクの高い個人パスワード直書き運用 vs 実行時のみ最小権限で自動ローテーションされるGITHUB_TOKENの安全性

そこで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の真価が発揮されるのが「社内標準ベースイメージ」や「マイクロサービスコンテナ」の組織内共有です。

社内共通C#イメージの組織配布
▲ 【図解④】各チームがバラバラに構築する非効率から、社内標準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テクニックを伝授します。お楽しみに!

コメント

このブログの人気の投稿

【Perfume】Perfume 3rd Tour 「JPN」さいたまスーパーアリーナに行って参りました~

Perfume 3rd Tour 「JPN」1月28日、29日の2daysで参戦して参りました。 ファンクラブ会員の選考抽選会に28日、29日の両日で申し込んでいたんですが、両方とも当選していたという嬉しい誤算。 仕事だぁ、なんだかんだと紆余曲折ありまして28日の参戦は危ぶまれていたのですが、なんとかかんとか28日は40分遅刻しながらも参戦、29日はフル参戦する事が出来ました(∩´∀`)∩

Perfume、2025年末で“コールドスリープ(活動休止)”へ──東京ドーム2daysの記録と、公式・各界・ファンの声

  1) 公式発表・基本情報 活動休止(コールドスリープ)を正式発表 2025年9月21日、公式サイト「 Perfumeより 」で、2026年から一度コールドスリープに入ると発表。再始動の意思(“新しいPerfume”として戻る)も明記。 Perfume Official Site 今後の運用告知(配信・上映など) 同21日付の「 今後のPerfumeに関して 」で、9/23(火・祝)東京ドーム公演の LIVESHIP全世界生配信 および 全国ディレイビューイング 決定を案内。特設サイトも併記。 Perfume Official Site +1 公式グッズ **「Perfume Calendar 2026」**発売決定(B2壁掛け/表紙+2カ月1枚×6枚+ポスター)。テーマは“フルーツ”。 Perfume Official Site 2) 東京ドーム2days(9/22・23)要点 公演タイトル: ZO/Z5 Anniversary “ネビュラロマンス” Episode TOKYO DOME 。日程・開場/開演・会場・物販等の実務情報は特設で公開。 Perfume Official Site 9/23公演を世界配信(LIVESHIP) /ディレイビューイング実施。 Perfume Official Site 海外向け報道(英語)も「 indefinite hiatus 」として広く配信。 The Times of India 国内英字メディアも速報。 朝日新聞 3) 現地レポ( メリ爺 )から見える空気 あなたの現地記録(9/24公開)を、ファクトと現場情景の両面で反映: 両日参戦 。22日は アリーナ 、23日は 1階席から俯瞰 。前日の発表を受け、開演前のザワつき→MC後に“いつもの一体感”へ。開演は22日 18:45 頃。オープニングは**P³ツアー東京ドーム(2020/2)**と同趣向で“回収”の演出。 メリ爺のゲーム万歳 MC所感 :解散ではなく前向きな休止で不安を和らげる内容。 かしゆか の涙、 のっち の気丈さ、 あ〜ちゃん の思い出語り──3人の結束と「 また戻る 」約束が強く刻まれた。 メリ爺のゲーム万歳 体感時間 : “3時間弱”級のボリューム ながら“過去一...

ニンテンドースイッチでオンラインゲームを遊ぶには?

モンスターハンターライズが発売になって、家族でモンハン楽しみたい人が増えたみたいですね。 某ブログの検索キーワードを調べると、モンハンを家族でやるにはどうしたらいいのか?を調べている人が沢山いるのがわかります。 ※これでも一部  家族で協力するにはSwitch2台、ソフトも2つ購入する必要があります。 1台のスイッチでは遊べませんし、ソフト1つでも遊べません。 でも、1台のスイッチで別々アカウントがあれば交代で遊ぶこともできますよ。セーブデータもしっかり分かれます。 Switchのオンラインゲームを家族で遊ぶ方法については以下の記事にまとめてますのでよろしければ参考にしてみてくださいね。 家族でモンスターハンターライズDL版のオンラインプレーを楽しむ方法