GitHub Actions × DockerでCI/CD環境を構築するベストプラクティス

GitHub ActionsとDockerを組み合わせると、コードのビルドから本番デプロイまでを一貫して自動化でき、開発速度と信頼性が大幅に向上します。
初心者の方にも分かりやすいよう、CI/CDの基本から応用テクニックまでを段階的に解説いたします。
GitHub ActionsとDocker連携
GitHub ActionsはGitHubリポジトリに直接組み込まれたCI/CDツールです。
Dockerと組み合わせることで、ビルド環境の再現性とポータビリティを担保しつつ、ワークフローを柔軟に構築できます。
ワークフロー全体像
以下のステップを順に実行し、コード変更から本番環境への反映までを自動化します。
ステップ | 処理内容 |
---|---|
① Push/PR検知 | mainブランチへのpushやプルリクエストをトリガー |
② イメージビルド | Dockerfile でアプリケーションをビルド |
③ コンテナテスト | コンテナ内でユニットテストや静的解析を実行 |
④ レジストリPush | Docker HubまたはGHCRへpush |
⑤ デプロイ | SSHやWebhookを介して任意の環境にデプロイ |
ワークフロー定義方法
ワークフローはリポジトリの .github/workflows/ci-cd.yml
にYAML形式で記述します。
各ジョブやステップは独立して定義でき、必要に応じて並列実行や条件分岐も設定可能です。
yamlname: CI/CD Pipeline
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
公式参照:Workflow syntax for GitHub Actions
ビルド&テスト工程
Docker Buildxを利用すれば、クロスプラットフォーム対応のビルドも容易です。
ビルド後は必ずコンテナ内で動作検証を行い、不具合を早期に発見しましょう。
yaml - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build Docker image
run: docker build -t myapp:latest .
- name: Run tests in container
run: docker run --rm myapp:latest yarn test
シークレット管理
シークレット機能を使うと、APIキーや認証情報を安全に扱えます。
SecretsはGitHub上で暗号化され、ワークフロー外には露出しません。
yaml - name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
公式参照:docker/login-action
イメージタグ付けとプッシュ
ビルドごとにユニークなタグを自動生成し、過去のビルドと混同しない運用を実現します。
タイムスタンプベースのタグは一貫性があり、デバッグ時にも参照しやすくなります。
yaml - name: Generate image tag
id: tag
run: echo "tag=$(date +%Y%m%d%H%M%S)" >> $GITHUB_OUTPUT
- name: Build and push
run: |
docker build -t myapp:${{ steps.tag.outputs.tag }} .
docker push myapp:${{ steps.tag.outputs.tag }}
GitHub Container Registry利用
GitHubネイティブのパッケージレジストリ「GHCR」を活用すると、組織単位でのアクセス制御やスキャンも容易です。
パブリック/プライベートリポジトリいずれにも対応し、GitHubエコシステムとシームレスに統合できます。
yaml - name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Push to GHCR
run: |
docker tag myapp:${{ steps.tag.outputs.tag }} ghcr.io/${{ github.repository_owner }}/myapp:${{ steps.tag.outputs.tag }}
docker push ghcr.io/${{ github.repository_owner }}/myapp:${{ steps.tag.outputs.tag }}
公式参照:Publishing Docker images - GitHub Docs
キャッシュ最適化
Actionsのキャッシュ機能とBuildxのローカルキャッシュを組み合わせると、再ビルド時間を大幅に短縮できます。
依存ファイルや中間レイヤーをキャッシュし、差分のみを再構築する設計が鍵です。
yaml - name: Cache Docker layers
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-docker
restore-keys: |
${{ runner.os }}-docker
- name: Build with cache
uses: docker/build-push-action@v5
with:
context: .
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
push: false
公式参照:build-push-action with cache
自動デプロイ
サーバへのSSH実行や外部サービスのWebhookにより、デプロイを自動化できます。
任意のデプロイ手順をスクリプト化し、ボタン一つで最新環境へ反映可能です。
yaml - name: Deploy via SSH
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.REMOTE_HOST }}
username: ${{ secrets.REMOTE_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
docker pull myapp:latest
docker stop myapp || true
docker rm myapp || true
docker run -d --name myapp -p 80:3000 myapp:latest
- name: Notify via Webhook
run: curl -X POST https://example.com/webhook -H "Authorization: Bearer ${{ secrets.DEPLOY_TOKEN }}"
マトリクスビルド
マトリクス戦略を使うと、複数バージョンやOSで同時にテスト・ビルドが可能となります。
これにより互換性を担保しつつ、CI時間を短縮できます。
yamlstrategy:
matrix:
node-version: [16, 18, 20]
steps:
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- run: yarn install && yarn test
公式参照:Matrix strategy
通知設定
ビルド成功・失敗をSlackやメールで通知し、チームへの情報共有を迅速化します。
通知対象やフォーマットは柔軟にカスタマイズ可能です。
yaml - name: Notify Slack
uses: slackapi/slack-github-action@v1
with:
payload: '{"text":"✅ デプロイ成功: ${{ github.sha }}"}'
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
Slack通知公式:slackapi/slack-github-action
条件分岐設定
ブランチやファイルパスに応じたジョブ実行制御を設定し、不必要な実行を防ぎます。
また、手動トリガー(workflow_dispatch)で環境を指定して実行することも可能です。
yamlon:
push:
branches: [ main ]
paths:
- 'backend/**'
workflow_dispatch:
inputs:
env:
description: 'デプロイ先環境'
required: true
default: 'staging'
よくあるエラーと対処法
代表的なエラーとその解決策をまとめ、トラブルシュートを容易にします。
エラー内容 | 原因 | 対処 |
---|---|---|
permission denied on SSH | 鍵の権限不足やホスト情報不一致 | chmod 600 で鍵の権限を修正 |
no space left on device | ビルド環境のディスク不足 | キャッシュクリアまたは別ランナーを使用 |
image not found | タグ名ミスやpush漏れ | docker images で存在確認 |
docker: command not found | Docker未インストール環境 | runs-on: ubuntu-latest を指定 |
まとめ
- 連携全体像:Push検知からデプロイまでの自動化ワークフロー
- 基本構造:
.github/workflows
配下にYAMLで定義 - ビルド&テスト:Buildxとコンテナ内検証
- シークレット管理:安全な認証情報の運用
- タグ&プッシュ:ユニークタグ生成とレジストリ連携
- キャッシュ活用:ビルド高速化の鍵
- 自動デプロイ:SSH/Webhookで反映
- マトリクスビルド:並列テストで互換性担保
- 通知設定:Slack通知でチーム共有迅速化
- 条件分岐:実行範囲を最小化
- エラー対処:代表的障害と解決法
これらを組み合わせ、柔軟かつ信頼性の高いCI/CDパイプラインを構築してください。
公式ドキュメント
Dockerの記事Docker
- article
Mac Apple Silicon(M1/M2/M3/M4)でDockerを快適に動かすためのTips集
- article
GitHub Actions × DockerでCI/CD環境を構築するベストプラクティス
- article
Dockerのマルチステージビルドとは?これらを活用し本番用イメージをスリムに保つやり方を紹介
- article
Dockerイメージを軽量化するベストプラクティス集を紹介
- article
Dockerネットワークの仕組みと使い方:bridge / host / overlayの違いとは?
- article
Dockerのデータ永続化の基礎と応用!ボリューム・マウントの正しい使い方を紹介