Skip to content

Commit f36ed9b

Browse files
authored
merge(cd) : 무중단 배포 스크립트 안정성 강화 및 오류 처리 개선
[Merge] : 무중단 배포 스크립트 안정성 강화 및 오류 처리 개선
2 parents 790846b + 90b191e commit f36ed9b

File tree

1 file changed

+35
-19
lines changed

1 file changed

+35
-19
lines changed

.github/workflows/DOCKER-CD-STAGING.yml

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -64,29 +64,41 @@ jobs:
6464
username: ${{ secrets.STAGING_SERVER_USER }}
6565
key: ${{ secrets.STAGING_SERVER_KEY }}
6666
script: |
67-
# -- 변수 설정 --
67+
set -e
68+
6869
APP_NAME="terning2025-staging"
6970
IMAGE_NAME="terningpoint/terning2025-staging"
7071
NGINX_CONFIG_PATH="/etc/nginx"
7172
SERVICE_URL_INC_PATH="${NGINX_CONFIG_PATH}/conf.d/service-url-staging.inc"
72-
73+
7374
echo "### 1. 최신 Docker 이미지를 pull합니다."
7475
docker pull ${IMAGE_NAME}:latest
75-
76+
7677
echo "### 2. 현재 실행 중인 포트(Blue)와 새로 실행할 포트(Green)를 결정합니다."
77-
RUNNING_PORT=$(docker ps --filter "name=${APP_NAME}" --format "{{.Ports}}" | grep -o '[0-9]\{4\}->8080' | awk -F'->' '{print $1}')
78+
IS_BLUE_RUNNING=$(docker ps -q --filter "name=${APP_NAME}" --filter "publish=8080")
7879
79-
if [ "${RUNNING_PORT}" == "8080" ]; then
80+
if [ -n "$IS_BLUE_RUNNING" ]; then
81+
RUNNING_PORT=8080
8082
NEW_PORT=8081
83+
OLD_CONTAINER_NAME="${APP_NAME}-8080"
8184
else
85+
RUNNING_PORT=8081
8286
NEW_PORT=8080
87+
OLD_CONTAINER_NAME="${APP_NAME}-8081"
8388
fi
84-
85-
echo " > 현재 서비스 포트(Blue): ${RUNNING_PORT:-없음}"
86-
echo " > 새로 실행할 포트(Green): ${NEW_PORT}"
87-
89+
90+
# 최초 배포인지 확인
91+
if [ -z "$IS_BLUE_RUNNING" ] && [ -z "$(docker ps -q --filter "name=${APP_NAME}" --filter "publish=8081")" ]; then
92+
echo " > 현재 실행중인 서비스가 없습니다. 최초 배포를 시작합니다."
93+
echo " > 새로 실행할 포트(Green): ${NEW_PORT}"
94+
else
95+
echo " > 현재 서비스 포트(Blue): ${RUNNING_PORT}"
96+
echo " > 새로 실행할 포트(Green): ${NEW_PORT}"
97+
fi
98+
8899
echo "### 3. 새로운 버전의 애플리케이션(Green)을 실행합니다."
89-
docker run -d --name ${APP_NAME}-${NEW_PORT} --restart always \
100+
NEW_CONTAINER_NAME="${APP_NAME}-${NEW_PORT}"
101+
docker run -d --name ${NEW_CONTAINER_NAME} --restart always \
90102
-p ${NEW_PORT}:8080 \
91103
-e SPRING_PROFILES_ACTIVE=staging \
92104
-e SPRING_DATASOURCE_URL='${{ secrets.DB_URL }}' \
@@ -103,36 +115,40 @@ jobs:
103115
-e TZ=Asia/Seoul \
104116
-v /home/ubuntu:/home/ubuntu/dev-logs \
105117
${IMAGE_NAME}:latest
106-
118+
107119
echo "### 4. 헬스 체크를 시작합니다."
108120
sleep 10
109121
for retry_count in {1..10}; do
110122
echo " > [${retry_count}/10] 서버 상태 체크 중..."
111123
response=$(curl -s http://localhost:${NEW_PORT}/actuator/health)
112-
up_count=$(echo "$response" | grep -c 'UP')
113-
124+
up_count=$(echo "$response" | grep -c '"status":"UP"')
125+
114126
if [ $up_count -ge 1 ]; then
115127
echo " > ✅ 서버 실행 성공 (포트: ${NEW_PORT})"
116128
break
117129
fi
118130
if [ $retry_count -eq 10 ]; then
119131
echo " > ❌ 서버 헬스체크 실패. 배포를 중단하고 새 컨테이너를 종료합니다."
120-
docker rm -f ${APP_NAME}-${NEW_PORT}
132+
docker rm -f ${NEW_CONTAINER_NAME}
121133
exit 1
122134
fi
123135
sleep 5
124136
done
125-
137+
126138
echo "### 5. Nginx 설정을 변경하여 트래픽을 새 포트(Green)로 전환합니다."
127139
echo "set \$service_url http://127.0.0.1:${NEW_PORT};" | sudo tee ${SERVICE_URL_INC_PATH}
128140
sudo nginx -s reload
129-
141+
130142
echo "### 6. 이전 버전의 컨테이너(Blue)를 종료 및 삭제합니다."
131-
if [ -n "${RUNNING_PORT}" ]; then
132-
docker rm -f ${APP_NAME}-${RUNNING_PORT}
143+
EXISTING_OLD_CONTAINER_ID=$(docker ps -aq --filter "name=${OLD_CONTAINER_NAME}")
144+
if [ -n "$EXISTING_OLD_CONTAINER_ID" ]; then
145+
echo " > 이전 컨테이너(${OLD_CONTAINER_NAME})를 중지하고 삭제합니다."
146+
docker rm -f ${OLD_CONTAINER_NAME}
147+
else
148+
echo " > 이전에 실행되던 컨테이너가 없어 삭제를 건너뜁니다."
133149
fi
134150
135151
echo "### 7. 사용하지 않는 Docker 이미지를 정리합니다."
136152
docker image prune -af
137-
153+
138154
echo "✅ Staging 배포가 성공적으로 완료되었습니다. 현재 서비스 포트: ${NEW_PORT}"

0 commit comments

Comments
 (0)