-
Notifications
You must be signed in to change notification settings - Fork 4
백엔드 CI CD 파이프라인
시원 edited this page Jul 25, 2025
·
4 revisions
우리가 서버를 배포하기 위해서는, 변경된 코드를 빌드해야하고, 정상 동작하는지 알기 위해 테스트를 수행하는 과정을 거쳐야 한다. 그 과정을 자동화해주는 것이 CI 이고, 코드를 통합할 때마다 배포하기 위한 준비 단계(빌드, 테스트)를 수행한다.
-
버그 조기 발견
- 급하게 PR을 올리려다가 테스트 실패한지도 모르는 경우를 대비할 수 있다.
-
효율성 증가
- 수동으로 빌드, 테스트 하지 않아도 된다.
수동 승인 없이 자동으로 배포하는 것을 의미한다. CI를 통해 빌드 및 테스트에 성공하면, 그 내용을 자동으로 배포할 수 있다.
-
효율성 증가
- 변경사항 있을 때마다 서버에 접속해서 실행 명령어를 수행하는 것은 번거롭다.
- Github에서 자체적으로 제공하는 Github Actions를 통해 CI/CD 파이프라인을 구축한다. Github Actions를 선택한 이유는 아래와 같다.
- 코드 저장소를 github으로 선택했기에, github actions를 통해 워크플로우를 쉽게 설정할 수 있다. 또한 github repository에서 push, merge 등 다양한 상황을 트리거로 삼아 워크플로우를 수행할 수 있다.
- .github 디렉터리에 워크플로우를 작성해서 넣어주면, Github에서 가상 머신 등을 제공해주기 때문에, 간편하게 이용할 수 있다.
- CI/CD 워크플로우는 아래의 링크를 통해 확인할 수 있다.
on:
push:
branches: [ develop ] # push 될 때 CI, CD
paths:
- 'backend/**' # backend 디렉터리의 변경에 대해 실행하도록 함
pull_request:
branches: [ develop ] # PR 날릴 때 CI
paths:
- 'backend/**'- develop 브랜치에 PR을 보낼 때, push될 때 CI 워크플로우가 수행된다. backend 디렉터리의 변경에 대해서만 수행된다.
jobs:
build_and_test: # CI 과정
runs-on: ubuntu-latest # github가 관리하는 가상 머신에서 CI 실행- CI 과정은 github가 제공해주는 가상 머신에서 수행한다.
steps:
- name: Checkout code
uses: actions/checkout@v4 # 현재 이 워크플로우가 실행되는 가상 머신에 repository 코드를 clone 받도록 함
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v3
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
cache: 'gradle'
- name: Build with Gradle # 빌드 없이 테스트
run: ./gradlew clean build -x test
- name: Run Unit Tests # 테스트
run: ./gradlew test
- name: Upload Jar # GitHub Actions 아티팩트 저장소에 실행 가능한 jar파일 업로드
uses: actions/upload-artifact@v4
with:
name: turip
path: backend/build/libs/*SNAPSHOT.jar- 가상 머신에서 레포지토리 코드를 clone받고, 빌드와 테스트를 위한 gradle, jdk 세팅을 한 후, 빌드와 테스트를 한다.
- 빌드 결과로 얻은 실행 가능한 jar파일을 GitHub Actions 아티팩트 저장소에 업로드한다.
deploy: # CD 과정
needs: build_and_test # build_and_test(CI) 과정이 끝난 이후 실행
runs-on: self-hosted # EC2에 설치된 github runners가 실행
if: github.event_name == 'push' # PR 날릴 때 말고, merge 될 때만 실행- CD 과정은 PR이 merge되는 경우에만 수행된다.
- 빌드 과정과 달리, Github가 띄워주는 가상 머신을 이용하지 않고, 우리 서버에서 직접 실행한다. 이를 위해 서버에 github runners 환경을 설정해줘야 한다.
- 이유는, 우리는 서버를 ec2에 띄우려 하는데, 생성한 ec2의 네트워크 보안 설정 상 github 가상 머신에서 ec2 서버에 접속할 수 없었다.(ec2에서 서버를 실행하는 명령어를 수행할 수 없었다.) 따라서 애초부터 ec2에서 CD과정을 수행하도록 한다.
steps:
- name: Download artifact from CI workflow
uses: actions/download-artifact@v4 # 스냅샷 Jar 올렸던 GitHub Actions 아티팩트 저장소
with:
name: turip
path: ./downloaded-artifact
- name: Get JAR file name # Jar 파일명 구하기
id: get_jar_name
run: |
JAR_FILE=$(find ./downloaded-artifact -name "*.jar" | head -n 1)
if [ -z "$JAR_FILE" ]; then # 원하는 Jar파일 없으면 에러
echo "Error: JAR file not found in downloaded-artifact directory."
exit 1
fi
echo "JAR_NAME=$(basename $JAR_FILE)" >> $GITHUB_OUTPUT
echo "JAR file located at: $JAR_FILE"
- name: Kill Existing Server On Port 80 # 기존 80포트에 돌아가던 서버 내리기
run: |
PID=$(sudo lsof -t -i :80 || true)
if [ -n "$PID" ]; then
echo "Killing existing process: $PID"
sudo kill -9 $PID
fi
- name: Run App On Port 80 # 80포트로 서버 올리기
run: |
JAR_NAME="${{ steps.get_jar_name.outputs.JAR_NAME }}"
DOWNLOADED_JAR="./downloaded-artifact/$JAR_NAME"
TARGET_JAR="/home/ubuntu/app/$JAR_NAME"
echo "Moving new JAR to $TARGET_JAR"
mv "$DOWNLOADED_JAR" "$TARGET_JAR"
chmod +x "$TARGET_JAR"
echo "Starting application..."
sudo nohup java -jar "$TARGET_JAR" --server.port=80 > /dev/null 2>&1 &- CI 과정에서 올렸던 jar 파일을 다운로드하고, 기존 80포트에서 돌고 있던 서버를 내리고, jar 파일을 실행시켜 서버를 다시 80포트에 띄운다.