0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Docker + GitHub ActionsでECRにイメージをpush — ビルドからプッシュまで自動化

0
Posted at

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に自動デプロイする構成を解説します。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?