avatar
Octoping Blog
커밋될 때마다 Spring Boot 프로젝트를 ECR에 배포하기
도커 + 배포 자동화
Spring배포backendAWSECSDocker
Aug 8
·
8 min read

들어가기 앞서

최근 Docker로 어플리케이션을 배포하는 것이 큰 유행이 됨에 따라, Spring Boot 프로젝트도 도커화하여 서버를 배포하는 요구가 늘어나고 있다.

Spring Boot에서 자체적으로 스프링 어플리케이션을 이미지로 만들어주는 bootBuildImage라는 gradle task를 지원하지만, 이것만으로는 CI/CD를 구축하는 것을 완성할 수 없다.

도커 애플리케이션을 배포하려면 보통 Dockerhub를 사용하지만.. private한 서버 애플리케이션을 공개적인 Dockerhub에 올릴 수는 또 없는 노릇이다. 따라서 AWS에서 제공하는 ECR (Elastic Container Registry)에 업로드해야 한다.

한번 Spring Boot 프로젝트를 bootBuildImage를 사용해서 도커 이미지화한 뒤, 이를 AWS ECR에 등록하는 파이프라인을 구축해보자.

TLDR;

내가 작성한 yaml 파일 전문은 다음과 같다.

name: Deploy to AWS ECR

on:
  push:
    branches:
      - main

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Set up JDK
        uses: actions/setup-java@v3
        with:
          distribution: 'adopt'
          java-version: 자바버전을적으세요

      - name: Grant execute permission for gradlew
        run: chmod +x ./gradlew

      - name: Build Docker image
        run: ./gradlew bootBuildImage

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-2

      - name: Login to Amazon ECR
        id: ecr-login
        uses: aws-actions/amazon-ecr-login@v2

      - name: Build, tag, and push image to ECR
        env:
          ECR_REGISTRY: ${{ steps.ecr-login.outputs.registry }}
          ECR_REPOSITORY: ECR레포지토리이름을적으세요
          IMAGE_TAG: ${{ github.sha }}
        run: |
          docker tag 도커이미지이름을적으세요:latest $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
          docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG

      - name: Logout from Amazon ECR
        run: docker logout ${{ steps.ecr-login.outputs.registry }}

Github Secret에 Access Key 등록하기

Github Action을 통해 파이프라인을 구축할 계획이고, 이를 위해서는 AWS의 Access Key가 필요하다.

다음과 같이 Github Repository의 Settings - Secrets and Variable - Actions에 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY를 등록해주자. (꼭 네이밍을 똑같이 할 필요는 없으나, 뒤의 예제에서 이름이 동일하도록 맞춰주어야 한다)

until-1190

AWS ECR 레포지토리 생성하기

until-1193

또한, ECR에 배포하기 위해서는 AWS ECR 레포지토리가 존재해야 한다. 없다면 만들고 옵시다.

Github Actions 작성하기

Github Actions 스크립트를 작성하기 위해 프로젝트 최상단에 .github 폴더를 생성하고, deploy-ecr.yml이라는 파일을 만들었다. (yaml 파일 이름은 당연히 원하는 대로 지정 가능하다)

파이프라인이 언제 작동할지 지정하기

until-1191
on:
  push:
    branches:
      - main

나는 Git Flow 브랜치 전략를 약간 수정하여 사용하고 있다. release 브랜치 대신 main 브랜치를 사용하고 있고, 따라서 main 브랜치에 push될 때마다 해당 파이프라인이 동작하여 ECR에 등록되도록 구현하려고 한다.

bootBuildImage로 이미지화하기

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Set up JDK
        uses: actions/setup-java@v3
        with:
          distribution: 'adopt'
          java-version: '17'

      - name: Grant execute permission for gradlew
        run: chmod +x ./gradlew

      - name: Build Docker image
        run: ./gradlew bootBuildImage

우리 코드를 체크아웃 받은 후, 자바 17 환경에서 작동할 수 있도록 버전을 명시해준다. 자바 버전을 다르게 하고 싶다면 따로 수정하면 된다.

그 후에는 ./gradlew bootBuildImage를 실행할 수 있도록 gradlew를 '실행 가능하도록' 권한을 수정해준 후 bootBuildImage 명령을 실행시킨다.

AWS ECR에 로그인하기

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-2

      - name: Login to Amazon ECR
        id: ecr-login
        uses: aws-actions/amazon-ecr-login@v2

ECR에 배포하기 위해서는 ECR에 로그인해야 하는데, 이는 aws-actions/configure-aws-credentials를 이용하려고 한다.

v1 버전이 현재 (24년 8월) 기준 최신은 아니지만 (v4가 최신), accessKey로 로그인하고 싶었기 때문에 v1을 사용하였다.

만약 본인의 리전이 ap-northeast-2가 아니면 이 부분도 바꿔주도록 하자.

AWS ECR에 푸시 후 로그아웃하기

      - name: Build, tag, and push image to ECR
        env:
          ECR_REGISTRY: ${{ steps.ecr-login.outputs.registry }}
          ECR_REPOSITORY: ECR레포지토리이름
          IMAGE_TAG: ${{ github.sha }}
        run: |
          docker tag 도커이미지이름:latest $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
          docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG

      - name: Logout from Amazon ECR
        run: docker logout ${{ steps.ecr-login.outputs.registry }}

ECR 레포지토리에 푸시할 차례다. ECR_REPOSITORY 환경변수 부분과 run 부분에 자신의 레포지토리 이름과 도커 이미지 이름을 적어주자.

총정리

name: Deploy to AWS ECR

on:
  push:
    branches:
      - main

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Set up JDK
        uses: actions/setup-java@v3
        with:
          distribution: 'adopt'
          java-version: 자바버전을적으세요

      - name: Grant execute permission for gradlew
        run: chmod +x ./gradlew

      - name: Build Docker image
        run: ./gradlew bootBuildImage

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ap-northeast-2

      - name: Login to Amazon ECR
        id: ecr-login
        uses: aws-actions/amazon-ecr-login@v2

      - name: Build, tag, and push image to ECR
        env:
          ECR_REGISTRY: ${{ steps.ecr-login.outputs.registry }}
          ECR_REPOSITORY: ECR레포지토리이름을적으세요
          IMAGE_TAG: ${{ github.sha }}
        run: |
          docker tag 도커이미지이름을적으세요:latest $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
          docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG

      - name: Logout from Amazon ECR
        run: docker logout ${{ steps.ecr-login.outputs.registry }}

끝났다! 이로써 main 브랜치에 커밋될 때마다 AWS ECR에 이미지를 푸시하는 파이프라인이 완성되었다.

마무리하며

이렇게 작업한 이후에는 ECR에 올라가있는 이미지를 이용해서 서버를 실행시키는 작업도 추가해야 할 것이다. (EC2로 실행할지, ECR로 실행할지 등에 따라 이 동작의 구현법도 달라질 것이다)


- 컬렉션 아티클







반갑습니다 :)