무중단 배포를 구축해 보자 - Back End 구성 편
Server안녕하세요 Lovefield입니다.
이전 글 “무중단 배포를 구축해 보자 - 환경 편”에 이어서 이번 글에서는 백엔드 서버를 무중단 배포하기 위한 설정을 서술하려 합니다. 백엔드 프레임 워크로는 Spring Boot를 사용했습니다. 구동 환경은 Java를 사용했습니다. 우선적으로 빌드를 해야하므로, Git Action을 이용해 빌드와 업로드 기능을 작성해 주겠습니다.
Git Action을 작성하기 이전에 업로드에 필요한 secrets값을 지정합니다.
- HOST_DIR : 서버에서 사용할 기본 디렉토리 위치입니다.
- HOST_IP : 서버 주소입니다.
- HOST_RUN_DIR : 서버에서 스크립트를 실행하는 디렉토리 위치입니다.
- HOST_USER : 서버 유저 이름입니다.
- PEM_VALUE : 서버에 접근하기위한 PEM키의 값입니다.
prod-deploy.yml
YAML
name: Deploy
on:
push: # 브런치에 PUSH가 될 경우 실행
branches:
- main
workflow_dispatch: # GitHub action 페이지에서 수동으로 실행
name:
description: "print name"
jobs:
buildAndDeploy:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v4
with:
distribution: "temurin"
java-version: "21"
- name: Build
run: ./gradlew build
- name: Upload file
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.HOST_IP }}
username: ${{ secrets.HOST_USER }}
key: ${{ secrets.PEM_VALUE }}
port: 22
source: "./build/libs/dico-4.0.jar"
target: ${{ secrets.HOST_DIR }}/
- name: Run Deploy Script
uses: appleboy/ssh-action@v1.1.0
env:
HOST_DIR: ${{ secrets.HOST_DIR }}
HOST_RUN_DIR: ${{ secrets.HOST_RUN_DIR }}
with:
host: ${{ secrets.HOST_IP }}
username: ${{ secrets.HOST_USER }}
key: ${{ secrets.PEM_VALUE }}
envs: HOST_DIR,HOST_RUN_DIR
port: 22
script: |
mv $HOST_DIR/build/libs/dico-4.0.jar $HOST_RUN_DIR/back/dico-4.0.jar
cd $HOST_RUN_DIR
sudo sh $HOST_RUN_DIR/deploy-backend.sh
GitHub Action을 이용해 빌드 및 업로드를 진행한 후, 서버에 있는 deploy-backend.sh 를 실행하도록 구성했는데요. 이 deploy-backend.sh를 통해서 Blue, Green 컨테이너를 업데이트 해줍니다.
deploy-backend.sh
Bash
#!/bin/bash
# 실행중인 blue가 있는지
EXIST_BLUE=$(sudo docker compose ps -a | grep "backend-blue")
target="blue";
target_port="9002"
TIMESTAMP=`date +%Y%m`
LOGFILE="./logs/backend-$TIMESTAMP.log"
func_reload()
{
echo "[$(date +%Y-%m-%d\ %H\:%M\:%S)] $1 Container down" >> $LOGFILE
sudo docker compose down backend-$1
echo "[$(date +%Y-%m-%d\ %H\:%M\:%S)] $1 Container up" >> $LOGFILE
sudo docker compose up backend-$1 -d
sleep 1.5
while true; do
RESPONSE=$(curl -I http://localhost:$2/health-check | grep "200" | awk '{print $2}')
echo "[$(date +%Y-%m-%d\ %H\:%M\:%S)] $1 Container Health Check" >> $LOGFILE
if [ "$RESPONSE" -eq "200" ]; then
break;
fi
sleep 2
done
}
touch $LOGFILE
echo "[$(date +%Y-%m-%d\ %H\:%M\:%S)] >>> 백엔드 배포 스크립트 시작 <<<" >> $LOGFILE
# Blue가 실행중이라면
if [ "$EXIST_BLUE" ]; then
target="green";
target_port="9001"
else
target="blue";
target_port="9002"
fi
func_reload $target $target_port
if [ "$target" -eq "blue" ]; then
func_reload "green" "9001"
else
func_reload "blue" "9002"
fi
echo "[$(date +%Y-%m-%d\ %H\:%M\:%S)] >>> 백엔드 배포 스크립트 종료 <<<" >> $LOGFILE
위와 같이 작성 후 Git Push를 통해서나 직접 Action을 생성해서든 실행이 된다면 다음과 같은 순서대로 진행이 됩니다.
Git Action에서 main 브런치를 기준으로 빌드합니다.
Git Action에서 빌드된 파일을 서버에 전송합니다.
Git Action에서 서버에 있는 배포 스크립트를 실행합니다.
배포 스크립트에서 전달받은 압축파일을 풀고 Blue, Green 컨테이너를 각각 업데이트 합니다.
전부 진행이 되었다면 logs 폴더에 다음과 같은 log 파일이 생성됩니다.
Plain Text
[2024-11-15 07:29:06] >>> 백엔드 배포 스크립트 시작 <<<
[2024-11-15 07:29:06] green Container down
[2024-11-15 07:29:06] green Container up
[2024-11-15 07:29:09] green Container Health Check
[2024-11-15 07:29:11] green Container Health Check
[2024-11-15 07:29:13] green Container Health Check
[2024-11-15 07:29:15] green Container Health Check
[2024-11-15 07:29:17] green Container Health Check
[2024-11-15 07:29:19] green Container Health Check
[2024-11-15 07:29:19] blue Container down
[2024-11-15 07:29:20] blue Container up
[2024-11-15 07:29:22] blue Container Health Check
[2024-11-15 07:29:24] blue Container Health Check
[2024-11-15 07:29:26] blue Container Health Check
[2024-11-15 07:29:28] blue Container Health Check
[2024-11-15 07:29:30] blue Container Health Check
[2024-11-15 07:29:30] >>> 백엔드 배포 스크립트 종료 <<<
이렇게 해서 백엔드 배포 구성이 완료되었습니다.