기술적 고민/Side Match

[SW마에스트로] CI/CD 구축 (Github Action, SCP)

생선묵김치찌개 2024. 7. 12. 00:36

개요

현재 개발자 사이드 프로젝트 팀 매칭 플랫폼을 리뉴얼 하고 있으며 SW 마에스트로의 금전 지원이 끊긴 지금 AWS 비용 을 최적화 해야 했다.

 

 

Github Action 선정 이유

작년 SW 마에스트로의 지원이 빵빵 할때는 Jenkins를 이용하여 팀원분께서 CI/CD를 구축 하셨었다.하지만 지원이 없는 지금 Jenkins는 EC2 한대를 더 올려야 사용이 가능했기 때문에 이 가격을 줄이고자 나는 다른 CI/CD 툴을 찾아 나섰다.CI/CD 툴에는 여러가지가 있었다.

  • Github Actions
  • Jenkins
  • Circle CI
  • Travis CI
  • 등등

난 이중에서도 현업에서 많이 사용하고, 무료로 사용할 수 있고, 빌드용 서버가 따로 필요없는 Github Actions를 활용하기로 결정하였다.

 

프로젝트 파일의 최상단인 .github/workflows/deploy.yml을 만들고 다음과 같이 작성 하였다.

name: EC2로 배포

on:
  push:
    branches:
      - master

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: SSH로 EC2에 접속
        uses: appleboy/ssh-action@v1.0.3
        env:
          APPLICATION_YML: ${{ secrets.APPLICATION_YML }}
          APPLICATION_DB_YML: ${{ secrets.APPLICATION_DB_YML }}
          APPLICATION_OAUTH_YML: ${{ secrets.APPLICATION_OAUTH_YML }}
        with:
          host: ${{ secrets.EC2_HOST }}
          username: ${{ secrets.EC2_USERNAME }}
          key: ${{ secrets.EC2_PRIVATE_KEY }}
          script_stop: true
          script: |
            cd /home/ubuntu/sidematch
            rm -rf src/main/resources/application.yml
            rm -rf src/main/resources/application-db.yml
            rm -rf src/main/resources/application-oauth.yml
            git pull origin master
            echo "$APPLICATION_YML" > src/main/resources/application.yml
            echo "$APPLICATION_DB_YML" > src/main/resources/application-db.yml
            echo "$APPLICATION_OAUTH_YML" > src/main/resources/application-oauth.yml
            ./gradlew clean build
            sudo fuser -k -n tcp 8080 || true 
            nohup java -jar build/libs/*SNAPSHOT.jar > ./output.log 2>&1 &

 

위 코드를 간단 하게 설명 하자면 내 프로젝트의 master 브랜치에 코드가 푸시될 때 자동으로 실행되어

1. appleboy/ssh-action을 이용하여 AWS EC2에 접속 

2. 기존의 yml 파일을 깃허브에 비밀로 설정해둔 새로운 yml 파일로 바꾸고

3. EC2에서 build 하고

4. 현재 8080 포트에서 실행 중인 서버를 종료 하고

5. 새로 빌드 된 jar 파일을 실행 한다. (실행하면서 생긴 log는 output.log에 저장)

 

 

 

SCP로 EC2에선 jar 파일만 실행

하지만 문제가 발생하였다. 나의 EC2 스펙은 작고 귀여웠기 때문에 빌드만 했을 뿐인데 서버가 뻗어 버렸다.

내가 미안해

 

그래서 난 Github Action도 하나의 컴퓨터로 볼 수 있기 때문에 Github Action에서 빌드를 하고 나온 jar 파일만 EC2로 보내서 실행하면 서버에 부하를 덜 줄 것이라 생각했고, SCP 명령어로 EC2에 빌드된 파일만 전송하는 방식을 고려하였다.

 

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Github Repository 파일 불러오기
        uses: actions/checkout@v4

      - name: JDK 17버전 설치
        uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: 17

      - name: yml 파일들 만들기
        run: |
          echo "${{ secrets.APPLICATION_YML }}" > ./src/main/resources/application.yml
          echo "${{ secrets.APPLICATION_DB_YML }}" > ./src/main/resources/application-db.yml
          echo "${{ secrets.APPLICATION_OAUTH_YML }}" > ./src/main/resources/application-oauth.yml

      - name: 테스트 및 빌드하기
        run: ./gradlew clean build -x test

      - name: 빌드된 파일 이름 변경하기
        run: mv ./build/libs/*SNAPSHOT.jar ./sidematch.jar

      - name: SCP로 EC2에 빌드된 파일 전송하기
        uses: appleboy/scp-action@v0.1.7
        with:
            host: ${{ secrets.EC2_HOST }}
            username: ${{ secrets.EC2_USERNAME }}
            key: ${{ secrets.EC2_PRIVATE_KEY }}
            source: sidematch.jar
            target: /home/ubuntu/Match-Up-Backend/tobe

      - name: SSH로 EC2에 접속하기
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.EC2_HOST }}
          username: ${{ secrets.EC2_USERNAME }}
          key: ${{ secrets.EC2_PRIVATE_KEY }}
          script_stop: true
          script: |
            rm -rf /home/ubuntu/Match-Up-Backend/current
            mkdir /home/ubuntu/Match-Up-Backend/current
            mv /home/ubuntu/Match-Up-Backend/tobe/sidematch.jar /home/ubuntu/Match-Up-Backend/current/sidematch.jar
            cd /home/ubuntu/Match-Up-Backend/current
            sudo fuser -k -n tcp 8080 || true
            nohup java -jar sidematch.jar > ./output.log 2>&1 & 
            rm -rf /home/ubuntu/Match-Up-Backend/tobe

 

그리하여 deploy.yml을 다음과 같이 작성하였고 플로우를 간단하게 정리하면 다음과 같다.

1. Github Action에서 깃허브에 비밀로 설정해둔 새로운 yml 파일들을 만들고 빌드한다.

2. 빌드된 파일 이름을 알아보기 쉽게 변경한다.

3. 빌드 파일을 SCP를 이용해 EC2로 전송한다. (appleboy/scp-action를 사용했다.)

4. SSH로 EC2에 접속 하여 기존의 jar 파일을 지우고 방금 전송한 jar 파일을 실행한다. (실행하면서 생긴 log는 output.log에 저장)

 

 

서버에서 빌드를 하지 않고 빌드 된 jar 파일만 서버에서 실행하니 훨씬 서버가 안정된 것을 확인 할수 있다.