Docker + GitHub ActionsでECRにイメージをpush — ビルドからプッシュまで自動化
はじめに
前回はSpring BootのテストをGitHub Actionsで自動実行する構成を紹介しました。
今回はその先のステップ、DockerイメージをビルドしてAWS ECRにpushするCI/CDパイプラインを構築します。mainへのpushで自動的にイメージが更新されます。
全体の流れ
git push → GitHub Actions起動
↓
1. チェックアウト
2. AWSクレデンシャル設定
3. ECRにログイン
4. Dockerイメージをビルド
5. ECRにpush
事前準備
1. ECRリポジトリを作成
aws ecr create-repository \
--repository-name my-spring-app \
--region ap-northeast-1
2. IAMユーザーを作成してポリシーを付与
GitHub ActionsからECRに接続するIAMユーザーに以下のポリシーが必要です。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:PutImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload"
],
"Resource": "*"
}
]
}
3. GitHub SecretsにAWSクレデンシャルを登録
リポジトリ Settings → Secrets and variables → Actions に追加します。
| シークレット名 | 値 |
|---|---|
AWS_ACCESS_KEY_ID |
IAMユーザーのアクセスキーID |
AWS_SECRET_ACCESS_KEY |
IAMユーザーのシークレットアクセスキー |
AWS_REGION |
ap-northeast-1 |
ECR_REPOSITORY |
my-spring-app |
Dockerfile(Spring Boot)
FROM eclipse-temurin:17-jdk-alpine AS builder
WORKDIR /app
COPY . .
RUN ./mvnw clean package -DskipTests
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
GitHub Actionsワークフロー
# .github/workflows/build-push-ecr.yml
name: Build and Push to ECR
on:
push:
branches: [main]
env:
AWS_REGION: ${{ secrets.AWS_REGION }}
ECR_REPOSITORY: ${{ secrets.ECR_REPOSITORY }}
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- 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 }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Build, tag, and push image to ECR
env:
REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: ${{ github.sha }}
run: |
docker build -t $REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker tag $REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG \
$REGISTRY/$ECR_REPOSITORY:latest
docker push $REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
docker push $REGISTRY/$ECR_REPOSITORY:latest
echo "image=$REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT
github.sha(コミットハッシュ)をタグに使うことで、どのコミットから作られたイメージかがECR上で追跡できます。
ビルドキャッシュで高速化
Dockerレイヤーキャッシュを使うと2回目以降のビルドが大幅に短縮されます。
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build, tag, and push image to ECR
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:${{ github.sha }}
${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:latest
cache-from: type=gha
cache-to: type=gha,mode=max
cache-from: type=gha でGitHub Actionsのキャッシュストレージを活用します。
テストとビルドを組み合わせた完全版
name: CI/CD
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: maven
- run: ./mvnw test
build-and-push:
runs-on: ubuntu-latest
needs: test # testが成功した場合のみ実行
if: github.ref == 'refs/heads/main' # mainへのpushのみ
steps:
- uses: actions/checkout@v4
- 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: ${{ secrets.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Build and push
env:
REGISTRY: ${{ steps.login-ecr.outputs.registry }}
run: |
docker build -t $REGISTRY/${{ secrets.ECR_REPOSITORY }}:${{ github.sha }} .
docker push $REGISTRY/${{ secrets.ECR_REPOSITORY }}:${{ github.sha }}
needs: test でテストが通ったときだけECRにpushされる構成になります。PRではテストのみ実行し、mainマージ後にビルド&pushが走ります。
ECR上でイメージを確認
aws ecr describe-images \
--repository-name my-spring-app \
--region ap-northeast-1 \
--query 'sort_by(imageDetails, &imagePushedAt)[-3:].{tag:imageTags[0],pushed:imagePushedAt}'
まとめ
| ステップ | 使うもの |
|---|---|
| AWSクレデンシャル設定 |
configure-aws-credentials アクション |
| ECRログイン |
amazon-ecr-login アクション |
| イメージタグ |
github.sha(コミットハッシュ)で追跡可能に |
| ビルドキャッシュ |
docker/build-push-action + cache-from: type=gha
|
| テスト通過後のみpush |
needs: test + if: github.ref == 'refs/heads/main'
|
次回はECRのイメージをECS Fargateに自動デプロイする構成を解説します。