Github Actionsでコンテナイメージを作成してECRへPushしてみる

2024.01.29

はじめに

データアナリティクス事業本部のkobayashiです。

Github ActionsでCI/CDのワークフローを実行しているのですがその中のアクションでリポジトリのコードからコンテナイメージをビルドしてECRへpushするといった作業があります。コンテナイメージをビルドからpushまで行ってくれるGithub Actionが非常に便利だったのでその内容をまとめます。

Build and push Docker images · Actions · GitHub Marketplace

Build & ECR pushをしてみる

GithubワークフローでGithub上のリポジトリにあるコードを元にコンテナイメージのビルドを行いECRへPushするためにGithubのMarketplaceを探していた所、非常に評価の高いGithub Actionがありました。

Build and push Docker images · Actions · GitHub Marketplace

このActionはBuildKitによる拡張ビルド機能のための Docker CLI プラグインであるBuildx を使用してコンテナイメージをビルドします。そのあと指定したコンテナレジストリへ作成したコンテナイメージをPushすることもできます。

では早速2つのパターンでビルド&プッシュを試してみたいと思います。

ビルド対象となるリポジトリ構成 1

リポジトリ直下にはコンテナイメージの元になるappディレクトリとコンテナイメージを作成するための手順を記したDockerfileがある状態です。

.
├── app # ソースコード
├── Dockerfile
└── readme.md

この場合は公式の手順 にあるWorkflowをベースにします。そのWorkflowへECRに作成したコンテナイメージをPushするためAWSの認証情報が必要になるのでaws-actions/configure-aws-credentialsのステップを付け加えるだけです。

なお、aws-actions/configure-aws-credentialsに必要なAWS_IAM_ROLE_ARNは予めリポジトリのActions secrets and variablesに設定しているものとします。この内容については下記エントリを参考にしてください。

name: Build And Push

on:
  workflow_call:

env:
  AWS_REGION: ap-northeast-1
  ECR_REGISTRY: {アカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com
jobs:
  build:
    name: Build And Push
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_IAM_ROLE_ARN }}
          aws-region: ${{ env.AWS_REGION }}
      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          registry: ${{ env.ECR_REGISTRY }}
      - name: Build and push API
        uses: docker/build-push-action@v5
        with:
          push: true
          provenance: false
          tags: ${{ env.ECR_REGISTRY }}/sample-image-ecr:latest

あとはこれを実行すると以下のようにGithubワークフロー中でコンテナイメージを作成した後にECRへPushを行ってくれます。

ビルド対象となるリポジトリ構成 2 (モノリポ)

次にリポジトリはモノリポ構成で一つのリポジトリ内にコンテナイメージ作成用のコードが複数含まれているようなリポジトリ構成になっている場合にビルド&プッシュを行ってみます。

.
├── api # イメージ1
│   ├── app # ソースコード
│   └── Dockerfile
├── api2 # イメージ2
│   ├── app # ソースコード
│   └── Dockerfile
└── readme.md

この場合には先程のワークフローで使用したdocker/build-push-action@v5でcontextの指定の仕方をPath contextに変更します。

Path contextを使う際にはactions/checkoutでチェックアウトをおこなってからビルドに使用するDockerfileを指定して使います。

- name: Build and push API
  uses: docker/build-push-action@v5
  with:
    context: . # <- path contextを指定
    push: true
    provenance: false
    file: api/Dockerfile # Dockerfileを指定
    tags: ${{ env.ECR_REGISTRY }}/sample1-image-ecr:latest

ワークフロー全体

name: Build And Push

on:
  workflow_call:

env:
  AWS_REGION: ap-northeast-1
  ECR_REGISTRY: {アカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com
jobs:
  build:
    name: Build And Push
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - uses: actions/checkout@v4
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_IAM_ROLE_ARN }}
          aws-region: ${{ env.AWS_REGION }}
      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          registry: ${{ env.ECR_REGISTRY }}
      - name: Build and push API
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          provenance: false
          file: api/Dockerfile
          tags: ${{ env.ECR_REGISTRY }}/sample1-image-ecr:latest
      - name: Build and push API 2
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          provenance: false
          file: api2/Dockerfile
          tags: ${{ env.ECR_REGISTRY }}/sample2-image-ecr:latest

このワークフローを実行するとapi配下のDockerfileでビルドしたコンテナイメージが{アカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/sample1-image-ecrにプッシュされ、api2配下のDockerfileでビルドしたコンテナイメージが{アカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/sample2-image-ecrにプッシュされます。

まとめ

Githubのワークフローでコンテナイメージを作成してからそのイメージをECRへプッシュするdocker/build-push-actioを使ってみました。単純なリポ構成でも使えましたが、モノリポ構成でも問題なく使えたので積極的に使っていきたいと思います。

最後まで読んで頂いてありがとうございました。