무중단 배포를 구축해 보자 - Back End 구성 편

Server

Language :

안녕하세요 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] >>> 백엔드 배포 스크립트 종료 <<<

이렇게 해서 백엔드 배포 구성이 완료되었습니다.

Lovefield

Web Front-End developer

하고싶은게 많고, 나만의 서비스를 만들고 싶은 변태스러운 개발자입니다.