From b6f875ebab44f50ba0e67f94b1341ba93a148362 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=AF=E1=86=AB=E1=84=8C=E1=85=A1=E1=86=BC?= =?UTF-8?q?=E1=84=89=E1=85=AE=E1=86=AB?= Date: Thu, 3 Jul 2025 12:35:55 +0900 Subject: [PATCH] =?UTF-8?q?refactor(cd):=20=EB=AC=B4=EC=A4=91=EB=8B=A8=20?= =?UTF-8?q?=EB=B0=B0=ED=8F=AC=20=EC=8A=A4=ED=81=AC=EB=A6=BD=ED=8A=B8=20?= =?UTF-8?q?=EC=95=88=EC=A0=95=EC=84=B1=20=EA=B0=95=ED=99=94=20=EB=B0=8F=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=B2=98=EB=A6=AC=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/DOCKER-CD-STAGING.yml | 54 ++++++++++++++++--------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/.github/workflows/DOCKER-CD-STAGING.yml b/.github/workflows/DOCKER-CD-STAGING.yml index 2d595ff..b27ee66 100644 --- a/.github/workflows/DOCKER-CD-STAGING.yml +++ b/.github/workflows/DOCKER-CD-STAGING.yml @@ -64,29 +64,41 @@ jobs: username: ${{ secrets.STAGING_SERVER_USER }} key: ${{ secrets.STAGING_SERVER_KEY }} script: | - # -- 변수 설정 -- + set -e + APP_NAME="terning2025-staging" IMAGE_NAME="terningpoint/terning2025-staging" NGINX_CONFIG_PATH="/etc/nginx" SERVICE_URL_INC_PATH="${NGINX_CONFIG_PATH}/conf.d/service-url-staging.inc" - + echo "### 1. 최신 Docker 이미지를 pull합니다." docker pull ${IMAGE_NAME}:latest - + echo "### 2. 현재 실행 중인 포트(Blue)와 새로 실행할 포트(Green)를 결정합니다." - RUNNING_PORT=$(docker ps --filter "name=${APP_NAME}" --format "{{.Ports}}" | grep -o '[0-9]\{4\}->8080' | awk -F'->' '{print $1}') + IS_BLUE_RUNNING=$(docker ps -q --filter "name=${APP_NAME}" --filter "publish=8080") - if [ "${RUNNING_PORT}" == "8080" ]; then + if [ -n "$IS_BLUE_RUNNING" ]; then + RUNNING_PORT=8080 NEW_PORT=8081 + OLD_CONTAINER_NAME="${APP_NAME}-8080" else + RUNNING_PORT=8081 NEW_PORT=8080 + OLD_CONTAINER_NAME="${APP_NAME}-8081" fi - - echo " > 현재 서비스 포트(Blue): ${RUNNING_PORT:-없음}" - echo " > 새로 실행할 포트(Green): ${NEW_PORT}" - + + # 최초 배포인지 확인 + if [ -z "$IS_BLUE_RUNNING" ] && [ -z "$(docker ps -q --filter "name=${APP_NAME}" --filter "publish=8081")" ]; then + echo " > 현재 실행중인 서비스가 없습니다. 최초 배포를 시작합니다." + echo " > 새로 실행할 포트(Green): ${NEW_PORT}" + else + echo " > 현재 서비스 포트(Blue): ${RUNNING_PORT}" + echo " > 새로 실행할 포트(Green): ${NEW_PORT}" + fi + echo "### 3. 새로운 버전의 애플리케이션(Green)을 실행합니다." - docker run -d --name ${APP_NAME}-${NEW_PORT} --restart always \ + NEW_CONTAINER_NAME="${APP_NAME}-${NEW_PORT}" + docker run -d --name ${NEW_CONTAINER_NAME} --restart always \ -p ${NEW_PORT}:8080 \ -e SPRING_PROFILES_ACTIVE=staging \ -e SPRING_DATASOURCE_URL='${{ secrets.DB_URL }}' \ @@ -103,36 +115,40 @@ jobs: -e TZ=Asia/Seoul \ -v /home/ubuntu:/home/ubuntu/dev-logs \ ${IMAGE_NAME}:latest - + echo "### 4. 헬스 체크를 시작합니다." sleep 10 for retry_count in {1..10}; do echo " > [${retry_count}/10] 서버 상태 체크 중..." response=$(curl -s http://localhost:${NEW_PORT}/actuator/health) - up_count=$(echo "$response" | grep -c 'UP') - + up_count=$(echo "$response" | grep -c '"status":"UP"') + if [ $up_count -ge 1 ]; then echo " > ✅ 서버 실행 성공 (포트: ${NEW_PORT})" break fi if [ $retry_count -eq 10 ]; then echo " > ❌ 서버 헬스체크 실패. 배포를 중단하고 새 컨테이너를 종료합니다." - docker rm -f ${APP_NAME}-${NEW_PORT} + docker rm -f ${NEW_CONTAINER_NAME} exit 1 fi sleep 5 done - + echo "### 5. Nginx 설정을 변경하여 트래픽을 새 포트(Green)로 전환합니다." echo "set \$service_url http://127.0.0.1:${NEW_PORT};" | sudo tee ${SERVICE_URL_INC_PATH} sudo nginx -s reload - + echo "### 6. 이전 버전의 컨테이너(Blue)를 종료 및 삭제합니다." - if [ -n "${RUNNING_PORT}" ]; then - docker rm -f ${APP_NAME}-${RUNNING_PORT} + EXISTING_OLD_CONTAINER_ID=$(docker ps -aq --filter "name=${OLD_CONTAINER_NAME}") + if [ -n "$EXISTING_OLD_CONTAINER_ID" ]; then + echo " > 이전 컨테이너(${OLD_CONTAINER_NAME})를 중지하고 삭제합니다." + docker rm -f ${OLD_CONTAINER_NAME} + else + echo " > 이전에 실행되던 컨테이너가 없어 삭제를 건너뜁니다." fi echo "### 7. 사용하지 않는 Docker 이미지를 정리합니다." docker image prune -af - + echo "✅ Staging 배포가 성공적으로 완료되었습니다. 현재 서비스 포트: ${NEW_PORT}"