[Github Actions CI/CD] AWS EC2 + Docker 배포하기

sy·2023년 8월 15일
2

Github Actions CI/CD

목록 보기
1/2

💡 현재 상황
1. 직접 build 하여 git push
2. EC2에 직접 접근하여 Docker pull, 컨테이너 생성하여 배포

💡 목표
main 으로 push 할 경우 자동으로 build, docker pull, 컨테이너 실행

CI/CD

지속적 통합 (Continuous Integration, CI)

  • CI는 코드 변경사항을 메인 브랜치에 통합하는 프로세스
  • 코드가 통합될 때마다 자동으로 빌드 및 테스트가 수행되어, 오류나 문제점을 빠르게 발견하고 해결할 수 있음

지속적 배포 (Continuous Delivery/Deployment, CD)

  • CI의 다음 단계. 코드 변경 사항을 프로덕션 환경에 자동 배포

Github Actions

CI (Continuous Integration)

깃허브에서 자동으로 추천을 해준다.

나는 Java, Gradle, Spring Boot 프로젝트이므로 Java with Gradle으로 등록한다.

자동으로 gradle.yml 파일을 만들어주므로 따로 변경하지 않고 Commit changes를 해준다.

커밋이 후 build 상태로 변경된다.

실패했다.

Java with Gradle 했을 때 11 버전으로 되어있었는데 17로 변경해주자

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

다시 build

build 완료

나는 버전 외에도 작성해둔 Test 에서 에러가 났었는데 모두 수정하여 build Success 가 나왔다.

CD (Continuous Deployment)

EC2에 직접 접근하여 docker 컨테이너를 띄우는 방법에서 GitHub Actions를 사용하여 자동화 배포를 하려고 한다.

내가 만들 배포 과정

현재 CI 부분인 push -> Build & Test 까지만 완료가 되어있다. 지금부터 AWS를 연결하여 배포 자동화를 할 예정이다.

1. AWS EC2에 Docker 설치하기

sudo amazon-linux-extras install docker
sudo systemctl start docker
sudo systemctl enable docker
sudo usermod -a -G docker $USER

또는

sudo yum install docker
sudo service docker start
sudo usermod -a -G docker ec2-user

버전 확인

docker --version

2. SSH 키 등록

EC2를 생성할 때 받았던 pem가 있을 것이다.

cat ~/.ssh/해당.pem

을 하여 찾은 후 New repository secret 등록을 해준다.

3. Docker hub Access Token 발급 받기

Account Settings > Security 로 들어가서 Access Token 을 발급 받는다.

4. DOCKER_USERNAME, DOCKER_HUB_TOKEN 등록

EC2_SSH_PRIVATE_KEY를 등록했던 것처럼 DOCKER_USERNAME, DOCKER_HUB_TOKEN 도 등록해준다.

5. application.properties 등록

나는 application-secret.properties로 민감 정보를 관리하고 있다. (예: DB 정보 등) gitignore에 등록되어 있기 때문에 push 후에 yml에서 build를 할 때 정보가 누락되므로 올바르게 빌드를 할 수가 없다. 이것 또한 New repository secret에 등록해준다.

6. yml 파일 설정

먼저 Dockerfile이 작성되어있어야한다.
Dockerfile

FROM amazoncorretto:17
# FROM openjdk:17-jdk
ARG JAR_FILE=build/libs/*.jar

COPY ${JAR_FILE} my-project.jar
# COPY build/libs/*.jar my-project.jar
ENTRYPOINT ["java","-jar","/my-project.jar"]

RUN ln -snf /usr/share/zoneinfo/Asia/Seoul /etc/localtime

배포를 위한 aws.yml

name: Deploy to AWS EC2 using Docker

on:
  push:
    branches:
      - main

env:
  DOCKER_IMAGE_NAME: 
  EC2_HOST: 
  EC2_SSH_USER: ec2-user
  PRIVATE_KEY: ${{ secrets.EC2_SSH_PRIVATE_KEY }}

jobs:
  build-and-push-docker:

    runs-on: ubuntu-latest

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

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

    - name: Set up application.properties
      run: echo "${{ secrets.APPLICATION }}" > ./src/main/resources/application.properties

    - name: Build with Gradle
      run: ./gradlew build

    - name: Build the Docker image
      run: docker build . --file Dockerfile --tag ${{ env.DOCKER_IMAGE_NAME }}:latest

    - name: Login to Docker Hub using Access Token
      run: echo "${{ secrets.DOCKER_HUB_TOKEN }}" | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin

    - name: Push the Docker image
      run: docker push ${{ env.DOCKER_IMAGE_NAME }}:latest


  deploy-to-ec2:

    needs: build-and-push-docker
    runs-on: ubuntu-latest

    steps:
    - name: Deploy to EC2
      uses: appleboy/ssh-action@master
      with:
        host: ${{ env.EC2_HOST }}
        username: ${{ env.EC2_SSH_USER }}
        key: ${{ env.PRIVATE_KEY }}
        script: |
          CONTAINER_ID=$(sudo docker ps -q --filter "publish=80-8080")

          if [ ! -z "$CONTAINER_ID" ]; then
            sudo docker stop $CONTAINER_ID
            sudo docker rm $CONTAINER_ID
          fi

          sudo docker pull ${{ env.DOCKER_HUB }}
          sudo docker run --name ${{ env.CONTAINER_NAME }} -d -p 80:8080 -e TZ=Asia/Seoul ${{ env.DOCKER_HUB }}

여기까지 하면 백엔드 프로젝트 배포 완료!

0개의 댓글