🐳

GitHub Actionsで本番環境と検証環境に異なるコンテナをpushする方法

に公開

🎯 この記事の目的

GitHub Actions を使ってコンテナを AWS Elastic Container Registry (ECR) に push する際、本番環境と検証環境で異なるコンテナを利用したい! と思ったことはありませんか?

特に ECS Fargate で運用している場合、環境ごとに適切なタグを付けることが重要です。

本記事では、GitHub Actions で環境ごとに異なるコンテナを push する方法 を解説します。

🚀 環境ごとに異なるコンテナを push する方法

本番環境と検証環境で異なるコンテナをデプロイするには、ブランチごとにタグを分ける のが一般的です。

✅ タグのルールを決める

ブランチ名 環境 イメージタグ
main 本番環境 my-image:prod
develop 検証環境 my-image:staging
feature/* 開発環境 my-image:dev

GitHub Actions では GITHUB_REF という環境変数を使い、どのブランチで実行されているか を取得できます。

例えば、以下のような方法でブランチ名を取得できます。

- name: ブランチ名を取得
  run: echo "BRANCH_NAME=${GITHUB_REF#refs/heads/}" >> $GITHUB_ENV

この BRANCH_NAME を使って、ECR に push するタグを動的に決めます。

📜 GitHub Actions のワークフロー

以下は GitHub Actions を使って環境ごとに異なるコンテナを push するワークフローの例 です。

name: Build and Push Docker Image

on:
  push:
    branches:
      - main
      - develop
      - "feature/*"

env:
  AWS_REGION: ap-northeast-1
  ECR_REPOSITORY: my-container-repo

jobs:
  build-and-push:
    runs-on: ubuntu-latest

    steps:
      - name: コードをチェックアウト
        uses: actions/checkout@v3

      - name: AWS CLI を設定
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ env.AWS_REGION }}

      - name: ECR にログイン
        run: |
          aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin <AWS_ACCOUNT_ID>.dkr.ecr.$AWS_REGION.amazonaws.com

      - name: ブランチ名を取得
        run: echo "BRANCH_NAME=${GITHUB_REF#refs/heads/}" >> $GITHUB_ENV

      - name: イメージタグを決定
        run: |
          if [[ "$BRANCH_NAME" == "main" ]]; then
            echo "IMAGE_TAG=prod" >> $GITHUB_ENV
          elif [[ "$BRANCH_NAME" == "develop" ]]; then
            echo "IMAGE_TAG=staging" >> $GITHUB_ENV
          else
            echo "IMAGE_TAG=dev" >> $GITHUB_ENV
          fi

      - name: Docker イメージをビルド
        run: |
          docker build -t $ECR_REPOSITORY:$IMAGE_TAG .

      - name: ECR に push
        run: |
          docker tag $ECR_REPOSITORY:$IMAGE_TAG <AWS_ACCOUNT_ID>.dkr.ecr.$AWS_REGION.amazonaws.com/$ECR_REPOSITORY:$IMAGE_TAG
          docker push <AWS_ACCOUNT_ID>.dkr.ecr.$AWS_REGION.amazonaws.com/$ECR_REPOSITORY:$IMAGE_TAG

🛠️ Fargate でのデプロイ時のポイント

1️⃣ ECS タスク定義を環境ごとに更新する

ECS Fargate では task-definition.json を使ってコンテナ設定を更新できます。

環境ごとに適切なタグを適用するには、GitHub Actions でタスク定義を更新しましょう。

- name: タスク定義の更新
  run: |
    aws ecs update-service --cluster my-cluster \
      --service my-service \
      --force-new-deployment

💡 force-new-deployment を指定することで、新しいコンテナを確実に適用!

🛠️ task-definition.json に変数を埋め込む方法

1. task-definition.json をテンプレート化
環境変数を使うため、{{IMAGE_TAG}} のようなプレースホルダーを入れます。

{
  "family": "my-task",
  "containerDefinitions": [
    {
      "name": "my-app",
      "image": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my-container-repo:{{IMAGE_TAG}}",
      "memory": 512,
      "cpu": 256,
      "essential": true
    }
  ]
}

2. GitHub Actions で IMAGE_TAG を埋め込む
YAML の sed コマンドを使って、プレースホルダーを実際の値に置き換え ます。

- name: `task-definition.json` に環境変数を埋め込む
  run: |
    sed -i 's/{{IMAGE_TAG}}/'"$IMAGE_TAG"'/g' task-definition.json

💡 これで task-definition.json 内の {{IMAGE_TAG}}prod, staging, dev に自動で変わる!

🎯 まとめ

GitHub Actions で本番環境・検証環境ごとに 異なるコンテナを push する方法 を解説しました。

ブランチごとにタグを分ける (prod, staging, dev)
GitHub Actions でブランチを判定して自動 push
task-definition.json に環境変数を埋め込む
Fargate の force-new-deployment を活用して確実に反映

これを使えば、環境ごとに適切なコンテナ管理ができ、デプロイの柔軟性が向上します!
ぜひ試してみてください!🚀

Discussion