GitHub Actions でコンテナをビルドする
GitHub Actions で Docker イメージをビルドして GHCR にプッシュするまでの最小構成と、実務で押さえるべき主要ポイント。
全体像
GitHub Actions でコンテナをビルドする最小構成は次の 4 ステップです。
- リポジトリをチェックアウト(
actions/checkout) - Buildx をセットアップ(
docker/setup-buildx-action。マルチアーキとキャッシュのため必須) - レジストリにログイン(
docker/login-action) - ビルド + プッシュ(
docker/build-push-action)
新規で組むときは「まずデフォルトブランチで docker/build-push-action が動くところまで」→「タグ戦略とキャッシュを足す」→「脆弱性スキャンを足す」の順で拡張するのが安全です。
最小構成のワークフロー
main ブランチへのプッシュで GHCR にイメージを push する例。
GITHUB_TOKEN だけで GHCR にアクセスできるので追加のシークレット設定は不要です。
# .github/workflows/build.yml
name: build
on:
push:
branches: [main]
permissions:
contents: read
packages: write
jobs:
docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ghcr.io/${{ github.repository }}:${{ github.sha }}metadata-action でタグを自動生成する
docker/metadata-action を使うと、ブランチ名・タグ名・SHA・セマンティックバージョンを組み合わせたタグとラベルを自動生成してくれます。
手書きで if github.ref == を並べるより保守性が高く、標準的な org.opencontainers.image.* ラベルも自動で付きます。
- id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha,prefix=sha-,format=short
type=raw,value=latest,enable={{is_default_branch}}
- uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}PR ではプッシュしない運用
PR に対しては「ビルドが通るか」と「スキャン結果」だけを確認し、レジストリには載せない運用が無難です。
push: ${{ github.event_name != 'pull_request' }} のように条件化するか、PR 用に別ワークフローを組みます。
Fork PR の場合、GITHUB_TOKEN に packages:write が付かないので、そもそもプッシュしようとすると失敗します。
pull_request_target を使う手はありますが、fork からの悪意あるコード混入リスク があるため、よく理解した上で使ってください。
実務で最低限入れたいもの
最小構成にプラスして、以下はほぼ必須です。
詳細は続くガイドで順に扱います。
- ビルドキャッシュ: GHA キャッシュまたはレジストリキャッシュ(
cicd-buildx-cache-strategy) - マルチアーキビルド: amd64 / arm64 両対応(
cicd-multi-arch-build) - 脆弱性スキャン: Trivy / Grype と Dockerfile の lint(
cicd-security-scan) - 安全なレジストリ認証: ECR などは長期キーを避けて OIDC(
cicd-registry-push-practice) - タグ戦略の明文化:
latestを本番で参照しない、デプロイ対象はshaかsemver固定 - Concurrency 制限:
concurrency: { group: build-${{ github.ref }}, cancel-in-progress: true }で古い PR ビルドを自動キャンセル
