1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Rails APIのFargateデプロイメント:GitHub Actionsによる自動CI/CDパイプライン構築 [ 備忘録 ]

1
Last updated at Posted at 2025-05-30

前回のQiita

リポジトリ

解説

こちらにも記載しています。
https://github.com/oyne2561/aws_deploy_rails7.2.2/blob/main/READ_GITHUB_ACTIONS.md

Github ActionsのSercetsを作成

image.png

  1. AWS_ACCESS_KEY_ID
    image.png

  2. AWS_SECRET_ACCESS_KEY
    image.png

実際の.github/workflows/cicd.yml

# ワークフローの名前を設定
name: CI/CD Pipeline

# このワークフローがいつ実行されるかを定義
on: 
  push:
    branches: [ main, develop ]  # mainまたはdevelopブランチにプッシュされた時

# 環境変数の定義(全てのジョブで使用可能)
env:
  AWS_REGION: ap-northeast-1                 # AWSリージョン(東京)
  ECR_REPOSITORY: todo-app-api               # ECR(Docker画像保存場所)のリポジトリ名
  ECS_SERVICE: todo-app-api-service          # ECS(コンテナ実行環境)のサービス名
  ECS_CLUSTER: todo-app-api-cluster          # ECSクラスター名
  ECS_TASK_DEFINITION: todo-app-api-task     # ECSタスク定義名

# ジョブの定義(並列または順次実行される処理の単位)
jobs:
  # 1つ目のジョブ:テスト実行
  test:
    runs-on: ubuntu-latest  # Ubuntu最新版の仮想マシンで実行

    # ステップの定義(順次実行される処理)
    steps:
    # Step 1: ソースコードをチェックアウト(取得)
    - name: Checkout code
      uses: actions/checkout@v4

    # Step 2: Ruby環境のセットアップ
    - name: Set up Ruby
      uses: ruby/setup-ruby@v1
      with:
        ruby-version: 3.2.0    # Ruby 3.2.0を使用
        bundler-cache: true   # キャッシュを無効化して手動でbundle install

    # Step 3: コード品質チェック(RuboCop)
    - name: Run RuboCop (Lint)
      run: bundle exec rubocop

  # 2つ目のジョブ:デプロイ実行
  deploy:
    needs: test  # testジョブが成功した場合のみ実行
    runs-on: ubuntu-latest
    # mainブランチへのプッシュの場合のみ実行
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'

    steps:
    # Step 1: ソースコードをチェックアウト
    - name: Checkout code
      uses: actions/checkout@v4

    # Step 2: AWS認証情報の設定
    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v4
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}     
        aws-region: ${{ env.AWS_REGION }}

    # Step 3: Amazon ECRにログイン
    - name: Login to Amazon ECR
      id: login-ecr
      uses: aws-actions/amazon-ecr-login@v2

    # Step 4: Docker ImageをビルドしてECRにプッシュ
    - name: Build, tag, and push image to Amazon ECR
      id: build-image
      env:
        ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
        IMAGE_TAG: ${{ github.sha }}  # GitコミットのSHAをタグとして使用
      run: |
        # Docker画像をビルドしてECRにプッシュ
        docker build -f Dockerfile.prod -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
        docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
        # latestタグも付けてプッシュ
        docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:latest
        docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest
        # 次のステップで使用するため、画像URIを出力
        echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT

    # Step 5: 現在のECSタスク定義をダウンロード
    - name: Download task definition
      run: |
        aws ecs describe-task-definition --task-definition $ECS_TASK_DEFINITION \
          --query taskDefinition > task-definition.json
    
    # Step 5.5: タスク定義のアーキテクチャをX86_64に修正
    - name: Fix task definition architecture
      run: |
        # JSONファイルでcpuArchitectureをX86_64に変更
        jq '.runtimePlatform.cpuArchitecture = "X86_64"' task-definition.json > task-definition-fixed.json
        # 修正されたファイルに置き換え
        mv task-definition-fixed.json task-definition.json
        
        # 確認のため修正内容を表示
        echo "=== 修正されたruntimePlatform ==="
        jq '.runtimePlatform' task-definition.json

    # Step 6: タスク定義に新しいDocker Imageを設定
    - name: Fill in the new image ID in the Amazon ECS task definition
      id: task-def
      uses: aws-actions/amazon-ecs-render-task-definition@v1
      with:
        task-definition: task-definition.json
        container-name: todo-app-api
        image: ${{ steps.build-image.outputs.image }}

    # Step 7: ECSサービスに新しいタスク定義をデプロイ
    - name: Deploy Amazon ECS task definition
      uses: aws-actions/amazon-ecs-deploy-task-definition@v1
      with:
        task-definition: ${{ steps.task-def.outputs.task-definition }}
        service: ${{ env.ECS_SERVICE }}
        cluster: ${{ env.ECS_CLUSTER }}
        wait-for-service-stability: true  # サービスが安定するまで待機

GitHub Actionsを実装時に遭遇したエラーの解決

問題の概要

GitHub Actions での Docker デプロイ時に、ローカル開発環境(Apple Silicon/ARM64)とデプロイ先(Intel/AMD x86_64)のアーキテクチャが異なることで発生するエラーについて解説します。

エラーの原因

GitHub Actions のランナーや ECS などのクラウド環境は通常 x86_64 アーキテクチャを使用しますが、ローカルの Apple Silicon Mac では ARM64(aarch64)アーキテクチャを使用します。この不整合により、以下のような問題が発生します:

  • Bundle install 時のプラットフォーム不整合
  • Docker イメージの実行時エラー
  • ECS タスクの起動失敗

解決手順

1. Gemfile.lock のプラットフォーム追加

まず、ローカル環境で Gemfile.lock に x86_64-linux プラットフォームを追加します。

bundle lock --add-platform x86_64-linux

実行後の Gemfile.lock

PLATFORMS
  aarch64-linux   # ARM64(既存)
  x86_64-linux    # Intel/AMD 64bit(新規追加)

2. Dockerfile の修正

Docker ビルド時の bundle コマンドの順序が重要です。deployment モードを有効にする前にプラットフォームを追加する必要があります。

# ❌ 間違った順序(deploymentモードが先だとlockファイル変更不可)
RUN bundle config set --local deployment 'true' && \
    bundle lock --add-platform x86_64-linux  # エラー!

# ✅ 正しい順序
RUN bundle config set --local without 'development test' && \
    bundle lock --add-platform x86_64-linux && \  # 先にプラットフォーム追加
    bundle config set --local deployment 'true' && \  # 後でdeploymentモード
    bundle install --jobs 4

重要なポイント:

  • deployment モードではロックファイルの変更が禁止される
  • プラットフォーム追加は deployment モードを有効にする前に実行する
  • without オプションで不要な gem グループを除外してビルド時間を短縮

3. ECS タスク定義のアーキテクチャ修正

GitHub Actions の CI/CD パイプラインで、ECS タスク定義のアーキテクチャを動的に修正します。

# cicd.yml の一部
- name: Fix task definition architecture
  run: |
    # JSONファイルでcpuArchitectureをX86_64に変更
    jq '.runtimePlatform.cpuArchitecture = "X86_64"' task-definition.json > task-definition-fixed.json
    # 修正されたファイルに置き換え
    mv task-definition-fixed.json task-definition.json
    
    # 確認のため修正内容を表示
    echo "=== 修正されたruntimePlatform ==="
    jq '.runtimePlatform' task-definition.json

注意点

  • ローカルでの bundle lock --add-platform 実行後は、必ず Gemfile.lock をコミットする
  • ECS 以外のデプロイ先でも同様のアーキテクチャ指定が必要な場合がある
  • Docker のマルチプラットフォームビルドを使用する場合は、別途 docker buildx の設定が必要

まとめ

Apple Silicon Mac での開発が一般的になった現在、アーキテクチャ不整合は頻繁に発生する問題です。適切な順序でのプラットフォーム設定と、CI/CD パイプラインでの動的な修正により、スムーズなデプロイが実現できます。

証跡

image.png

image.png

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?