
Github Actionsでコンテナイメージを作成してECRへPushしてみる
はじめに
データアナリティクス事業本部の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
に設定しているものとします。この内容については下記エントリを参考に以下のポリシーを付与します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "GetAuthorizationToken",
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken"
],
"Resource": "*"
},
{
"Sid": "PushImageOnly",
"Effect": "Allow",
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"ecr:PutImage",
"ecr:BatchGetImage"
],
"Resource": "arn:aws:ecr:ap-northeast-1:<AWSアカウントID>:repository/<リポジトリ名>"
}
]
}
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を行ってくれます。
<a href="https://devio2023-media.developers.io/wp-content/uploads/2024/01/aaa.png"><img src="https://devio2023-media.developers.io/wp-content/uploads/2024/01/aaa-640x551.png" alt="" width="640" height="551" class="aligncenter size-medium wp-image-1211593" /></a>
ビルド対象となるリポジトリ構成 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
を使ってみました。単純なリポ構成でも使えましたが、モノリポ構成でも問題なく使えたので積極的に使っていきたいと思います。
最後まで読んで頂いてありがとうございました。