@@ -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