From 9f5015d4da383681bedd9a9110f2bb8a6f23898c Mon Sep 17 00:00:00 2001 From: Hexeong <123macanic@naver.com> Date: Sat, 13 Jun 2026 18:17:04 +0900 Subject: [PATCH 1/4] =?UTF-8?q?refactor:=20prod/stage=20=ED=99=98=EA=B2=BD?= =?UTF-8?q?=20nginx=20=EB=B8=94=EB=A3=A8/=EA=B7=B8=EB=A6=B0=20=EB=B0=B0?= =?UTF-8?q?=ED=8F=AC=20=EB=B0=A9=EC=8B=9D=20=EB=8F=84=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/dev-cd.yml | 35 +++++++++++++++++------------------ .github/workflows/prod-cd.yml | 17 +++++++++-------- docker-compose.dev.yml | 1 - docker-compose.prod.yml | 1 - 4 files changed, 26 insertions(+), 28 deletions(-) diff --git a/.github/workflows/dev-cd.yml b/.github/workflows/dev-cd.yml index b75d2a18d..a97fd48e8 100644 --- a/.github/workflows/dev-cd.yml +++ b/.github/workflows/dev-cd.yml @@ -122,41 +122,40 @@ jobs: # 1. Active 슬롯 확인 (upstream.conf 기준) UPSTREAM_PORT=$(grep -oE "server 127\.0\.0\.1:[0-9]+" /etc/nginx/conf.d/upstream.conf 2>/dev/null | grep -oE "[0-9]+$" || echo "8081") if [ "$UPSTREAM_PORT" = "8080" ]; then - ACTIVE_SLOT="blue"; ACTIVE_PORT=8080; NEW_SLOT="green"; NEW_PORT=8081; MANAGEMENT_PORT=9081 + ACTIVE_SLOT="blue"; ACTIVE_PORT=8080; NEW_SLOT="green"; NEW_PORT=8081 else - ACTIVE_SLOT="green"; ACTIVE_PORT=8081; NEW_SLOT="blue"; NEW_PORT=8080; MANAGEMENT_PORT=9080 + ACTIVE_SLOT="green"; ACTIVE_PORT=8081; NEW_SLOT="blue"; NEW_PORT=8080 fi - echo "Active: ${ACTIVE_SLOT}(${ACTIVE_PORT}) → Deploy: ${NEW_SLOT}(${NEW_PORT}), management: ${MANAGEMENT_PORT}" + echo "Active: ${ACTIVE_SLOT}(${ACTIVE_PORT}) → Deploy: ${NEW_SLOT}(${NEW_PORT})" - # 2. 작업 디렉토리 이동 (이후 모든 compose 명령 기준) - cd "${WORK_DIR}" - - # 3. MySQL 기동 확인 (블루/그린 전환 대상 아님) + # 2. MySQL 기동 확인 (블루/그린 전환 대상 아님) docker compose -f docker-compose.dev.yml up -d mysql 2>/dev/null || true - # 4. Pull 전 디스크 정리 (태그 이미지 최근 2개 유지) + # 3. Pull 전 디스크 정리 (태그 이미지 최근 2개 유지) docker images "${IMAGE_NAME_BASE}" --format "{{.Tag}}" | \ grep -v buildcache | sort -r | tail -n +3 | \ xargs -I {} docker rmi "${IMAGE_NAME_BASE}:{}" 2>/dev/null || true docker image prune -f - # 5. GHCR 로그인 & Pull + # 4. GHCR 로그인 & Pull echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin docker pull "${FULL_IMAGE_NAME}" - # 6. 새 슬롯 잔여 컨테이너 정리 + # 5. 새 슬롯 잔여 컨테이너 정리 docker stop "${CONTAINER_BASE}-${NEW_SLOT}" 2>/dev/null || true docker rm "${CONTAINER_BASE}-${NEW_SLOT}" 2>/dev/null || true - # 7. 새 컨테이너 시작 - SLOT="${NEW_SLOT}" APP_PORT="${NEW_PORT}" MANAGEMENT_PORT="${MANAGEMENT_PORT}" OWNER_LOWERCASE="${OWNER_LOWERCASE}" IMAGE_TAG="${IMAGE_TAG_ONLY}" \ + # 6. 새 컨테이너 시작 + cd "${WORK_DIR}" + SLOT="${NEW_SLOT}" APP_PORT="${NEW_PORT}" OWNER_LOWERCASE="${OWNER_LOWERCASE}" IMAGE_TAG="${IMAGE_TAG_ONLY}" \ docker compose -p "${CONTAINER_BASE}-${NEW_SLOT}" -f docker-compose.dev.yml up -d solid-connection-dev - # 8. 헬스 체크 (앱 기동 대기, 최대 150초) - echo "Waiting for app on management port ${MANAGEMENT_PORT}..." + # 7. 헬스 체크 (앱 기동 대기, 최대 150초) + # /actuator/health 미노출로 포트 응답 여부로 확인 (HTTP 000 = 연결 불가) + echo "Waiting for app on port ${NEW_PORT}..." for i in $(seq 1 30); do - STATUS=$(curl -s --connect-timeout 2 "http://localhost:${MANAGEMENT_PORT}/actuator/health" | grep -o '"status":"UP"' || true) - [ "$STATUS" = '"status":"UP"' ] && { echo "App healthy (attempt ${i})"; break; } + HTTP=$(curl -s --connect-timeout 2 -o /dev/null -w "%{http_code}" "http://localhost:${NEW_PORT}/" || true) + [ "$HTTP" != "000" ] && { echo "App responding (HTTP ${HTTP}, attempt ${i})"; break; } [ "$i" = "30" ] && { echo "Health check timed out after 150s" >&2 docker stop "${CONTAINER_BASE}-${NEW_SLOT}" 2>/dev/null || true @@ -166,12 +165,12 @@ jobs: sleep 5 done - # 9. Nginx upstream 전환 (무중단) + # 8. Nginx upstream 전환 (무중단) sudo sed -i "s|server 127.0.0.1:[0-9]*;|server 127.0.0.1:${NEW_PORT};|" /etc/nginx/conf.d/upstream.conf sudo nginx -s reload echo "Traffic switched → ${NEW_SLOT}(${NEW_PORT})" - # 10. 구 컨테이너 종료 + # 9. 구 컨테이너 종료 docker compose -p "${CONTAINER_BASE}-${ACTIVE_SLOT}" -f docker-compose.dev.yml down 2>/dev/null || true echo "Deployment complete. Active: ${NEW_SLOT}(${NEW_PORT})" diff --git a/.github/workflows/prod-cd.yml b/.github/workflows/prod-cd.yml index bb31d5b7d..820ec3c67 100644 --- a/.github/workflows/prod-cd.yml +++ b/.github/workflows/prod-cd.yml @@ -138,11 +138,11 @@ jobs: # 1. Active 슬롯 확인 (upstream.conf 기준) UPSTREAM_PORT=$(grep -oE "server 127\.0\.0\.1:[0-9]+" /etc/nginx/conf.d/upstream.conf 2>/dev/null | grep -oE "[0-9]+$" || echo "8081") if [ "$UPSTREAM_PORT" = "8080" ]; then - ACTIVE_SLOT="blue"; ACTIVE_PORT=8080; NEW_SLOT="green"; NEW_PORT=8081; MANAGEMENT_PORT=9081 + ACTIVE_SLOT="blue"; ACTIVE_PORT=8080; NEW_SLOT="green"; NEW_PORT=8081 else - ACTIVE_SLOT="green"; ACTIVE_PORT=8081; NEW_SLOT="blue"; NEW_PORT=8080; MANAGEMENT_PORT=9080 + ACTIVE_SLOT="green"; ACTIVE_PORT=8081; NEW_SLOT="blue"; NEW_PORT=8080 fi - echo "Active: ${ACTIVE_SLOT}(${ACTIVE_PORT}) → Deploy: ${NEW_SLOT}(${NEW_PORT}), management: ${MANAGEMENT_PORT}" + echo "Active: ${ACTIVE_SLOT}(${ACTIVE_PORT}) → Deploy: ${NEW_SLOT}(${NEW_PORT})" # 2. Pull 전 디스크 정리 (태그 이미지 최근 2개 유지) docker images "${IMAGE_NAME_BASE}" --format "{{.Tag}}" | \ @@ -160,14 +160,15 @@ jobs: # 5. 새 컨테이너 시작 cd "${WORK_DIR}" - SLOT="${NEW_SLOT}" APP_PORT="${NEW_PORT}" MANAGEMENT_PORT="${MANAGEMENT_PORT}" OWNER_LOWERCASE="${OWNER_LOWERCASE}" IMAGE_TAG="${IMAGE_TAG_ONLY}" \ - docker compose -p "${CONTAINER_BASE}-${NEW_SLOT}" -f docker-compose.prod.yml up -d solid-connection-server + SLOT="${NEW_SLOT}" APP_PORT="${NEW_PORT}" OWNER_LOWERCASE="${OWNER_LOWERCASE}" IMAGE_TAG="${IMAGE_TAG_ONLY}" \ + docker compose -p "${CONTAINER_BASE}-${NEW_SLOT}" -f docker-compose.prod.yml up -d # 6. 헬스 체크 (앱 기동 대기, 최대 150초) - echo "Waiting for app on management port ${MANAGEMENT_PORT}..." + # /actuator/health 미노출로 포트 응답 여부로 확인 (HTTP 000 = 연결 불가) + echo "Waiting for app on port ${NEW_PORT}..." for i in $(seq 1 30); do - STATUS=$(curl -s --connect-timeout 2 "http://localhost:${MANAGEMENT_PORT}/actuator/health" | grep -o '"status":"UP"' || true) - [ "$STATUS" = '"status":"UP"' ] && { echo "App healthy (attempt ${i})"; break; } + HTTP=$(curl -s --connect-timeout 2 -o /dev/null -w "%{http_code}" "http://localhost:${NEW_PORT}/" || true) + [ "$HTTP" != "000" ] && { echo "App responding (HTTP ${HTTP}, attempt ${i})"; break; } [ "$i" = "30" ] && { echo "Health check timed out after 150s" >&2 docker stop "${CONTAINER_BASE}-${NEW_SLOT}" 2>/dev/null || true diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index f2cd9b9e5..3052c196f 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -8,7 +8,6 @@ services: environment: - SPRING_PROFILES_ACTIVE=dev - SERVER_PORT=${APP_PORT:-8080} - - MANAGEMENT_SERVER_PORT=${MANAGEMENT_PORT:-9080} - AWS_REGION=ap-northeast-2 - SPRING_DATA_REDIS_HOST=127.0.0.1 - SPRING_DATA_REDIS_PORT=6379 diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 57363231b..f352adeb2 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -8,7 +8,6 @@ services: environment: - SPRING_PROFILES_ACTIVE=prod - SERVER_PORT=${APP_PORT:-8080} - - MANAGEMENT_SERVER_PORT=${MANAGEMENT_PORT:-9080} - AWS_REGION=ap-northeast-2 - SPRING_DATA_REDIS_HOST=127.0.0.1 - SPRING_DATA_REDIS_PORT=6379 From 032355a88411d5121327c96b8ca59d52a800659c Mon Sep 17 00:00:00 2001 From: Hexeong <123macanic@naver.com> Date: Sat, 13 Jun 2026 18:46:57 +0900 Subject: [PATCH 2/4] =?UTF-8?q?fix:=20=EB=A6=AC=EB=B7=B0=20=EB=B0=98?= =?UTF-8?q?=EC=98=81(management=20port=20=EC=B6=A9=EB=8F=8C=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0,=20MySQL=20=EA=B2=BD=EB=A1=9C=20?= =?UTF-8?q?=EB=B2=84=EA=B7=B8=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/dev-cd.yml | 28 +++++++++++++++------------- .github/workflows/prod-cd.yml | 8 ++++---- docker-compose.dev.yml | 1 + docker-compose.prod.yml | 1 + 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/.github/workflows/dev-cd.yml b/.github/workflows/dev-cd.yml index a97fd48e8..16f89e680 100644 --- a/.github/workflows/dev-cd.yml +++ b/.github/workflows/dev-cd.yml @@ -122,35 +122,37 @@ jobs: # 1. Active 슬롯 확인 (upstream.conf 기준) UPSTREAM_PORT=$(grep -oE "server 127\.0\.0\.1:[0-9]+" /etc/nginx/conf.d/upstream.conf 2>/dev/null | grep -oE "[0-9]+$" || echo "8081") if [ "$UPSTREAM_PORT" = "8080" ]; then - ACTIVE_SLOT="blue"; ACTIVE_PORT=8080; NEW_SLOT="green"; NEW_PORT=8081 + ACTIVE_SLOT="blue"; ACTIVE_PORT=8080; NEW_SLOT="green"; NEW_PORT=8081; MANAGEMENT_PORT=9081 else - ACTIVE_SLOT="green"; ACTIVE_PORT=8081; NEW_SLOT="blue"; NEW_PORT=8080 + ACTIVE_SLOT="green"; ACTIVE_PORT=8081; NEW_SLOT="blue"; NEW_PORT=8080; MANAGEMENT_PORT=9080 fi - echo "Active: ${ACTIVE_SLOT}(${ACTIVE_PORT}) → Deploy: ${NEW_SLOT}(${NEW_PORT})" + echo "Active: ${ACTIVE_SLOT}(${ACTIVE_PORT}) → Deploy: ${NEW_SLOT}(${NEW_PORT}), management: ${MANAGEMENT_PORT}" - # 2. MySQL 기동 확인 (블루/그린 전환 대상 아님) + # 2. 작업 디렉토리 이동 (이후 모든 compose 명령 기준) + cd "${WORK_DIR}" + + # 3. MySQL 기동 확인 (블루/그린 전환 대상 아님) docker compose -f docker-compose.dev.yml up -d mysql 2>/dev/null || true - # 3. Pull 전 디스크 정리 (태그 이미지 최근 2개 유지) + # 4. Pull 전 디스크 정리 (태그 이미지 최근 2개 유지) docker images "${IMAGE_NAME_BASE}" --format "{{.Tag}}" | \ grep -v buildcache | sort -r | tail -n +3 | \ xargs -I {} docker rmi "${IMAGE_NAME_BASE}:{}" 2>/dev/null || true docker image prune -f - # 4. GHCR 로그인 & Pull + # 5. GHCR 로그인 & Pull echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin docker pull "${FULL_IMAGE_NAME}" - # 5. 새 슬롯 잔여 컨테이너 정리 + # 6. 새 슬롯 잔여 컨테이너 정리 docker stop "${CONTAINER_BASE}-${NEW_SLOT}" 2>/dev/null || true docker rm "${CONTAINER_BASE}-${NEW_SLOT}" 2>/dev/null || true - # 6. 새 컨테이너 시작 - cd "${WORK_DIR}" - SLOT="${NEW_SLOT}" APP_PORT="${NEW_PORT}" OWNER_LOWERCASE="${OWNER_LOWERCASE}" IMAGE_TAG="${IMAGE_TAG_ONLY}" \ + # 7. 새 컨테이너 시작 + SLOT="${NEW_SLOT}" APP_PORT="${NEW_PORT}" MANAGEMENT_PORT="${MANAGEMENT_PORT}" OWNER_LOWERCASE="${OWNER_LOWERCASE}" IMAGE_TAG="${IMAGE_TAG_ONLY}" \ docker compose -p "${CONTAINER_BASE}-${NEW_SLOT}" -f docker-compose.dev.yml up -d solid-connection-dev - # 7. 헬스 체크 (앱 기동 대기, 최대 150초) + # 8. 헬스 체크 (앱 기동 대기, 최대 150초) # /actuator/health 미노출로 포트 응답 여부로 확인 (HTTP 000 = 연결 불가) echo "Waiting for app on port ${NEW_PORT}..." for i in $(seq 1 30); do @@ -165,12 +167,12 @@ jobs: sleep 5 done - # 8. Nginx upstream 전환 (무중단) + # 9. Nginx upstream 전환 (무중단) sudo sed -i "s|server 127.0.0.1:[0-9]*;|server 127.0.0.1:${NEW_PORT};|" /etc/nginx/conf.d/upstream.conf sudo nginx -s reload echo "Traffic switched → ${NEW_SLOT}(${NEW_PORT})" - # 9. 구 컨테이너 종료 + # 10. 구 컨테이너 종료 docker compose -p "${CONTAINER_BASE}-${ACTIVE_SLOT}" -f docker-compose.dev.yml down 2>/dev/null || true echo "Deployment complete. Active: ${NEW_SLOT}(${NEW_PORT})" diff --git a/.github/workflows/prod-cd.yml b/.github/workflows/prod-cd.yml index 820ec3c67..1407ff6c4 100644 --- a/.github/workflows/prod-cd.yml +++ b/.github/workflows/prod-cd.yml @@ -138,11 +138,11 @@ jobs: # 1. Active 슬롯 확인 (upstream.conf 기준) UPSTREAM_PORT=$(grep -oE "server 127\.0\.0\.1:[0-9]+" /etc/nginx/conf.d/upstream.conf 2>/dev/null | grep -oE "[0-9]+$" || echo "8081") if [ "$UPSTREAM_PORT" = "8080" ]; then - ACTIVE_SLOT="blue"; ACTIVE_PORT=8080; NEW_SLOT="green"; NEW_PORT=8081 + ACTIVE_SLOT="blue"; ACTIVE_PORT=8080; NEW_SLOT="green"; NEW_PORT=8081; MANAGEMENT_PORT=9081 else - ACTIVE_SLOT="green"; ACTIVE_PORT=8081; NEW_SLOT="blue"; NEW_PORT=8080 + ACTIVE_SLOT="green"; ACTIVE_PORT=8081; NEW_SLOT="blue"; NEW_PORT=8080; MANAGEMENT_PORT=9080 fi - echo "Active: ${ACTIVE_SLOT}(${ACTIVE_PORT}) → Deploy: ${NEW_SLOT}(${NEW_PORT})" + echo "Active: ${ACTIVE_SLOT}(${ACTIVE_PORT}) → Deploy: ${NEW_SLOT}(${NEW_PORT}), management: ${MANAGEMENT_PORT}" # 2. Pull 전 디스크 정리 (태그 이미지 최근 2개 유지) docker images "${IMAGE_NAME_BASE}" --format "{{.Tag}}" | \ @@ -160,7 +160,7 @@ jobs: # 5. 새 컨테이너 시작 cd "${WORK_DIR}" - SLOT="${NEW_SLOT}" APP_PORT="${NEW_PORT}" OWNER_LOWERCASE="${OWNER_LOWERCASE}" IMAGE_TAG="${IMAGE_TAG_ONLY}" \ + SLOT="${NEW_SLOT}" APP_PORT="${NEW_PORT}" MANAGEMENT_PORT="${MANAGEMENT_PORT}" OWNER_LOWERCASE="${OWNER_LOWERCASE}" IMAGE_TAG="${IMAGE_TAG_ONLY}" \ docker compose -p "${CONTAINER_BASE}-${NEW_SLOT}" -f docker-compose.prod.yml up -d # 6. 헬스 체크 (앱 기동 대기, 최대 150초) diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 3052c196f..f2cd9b9e5 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -8,6 +8,7 @@ services: environment: - SPRING_PROFILES_ACTIVE=dev - SERVER_PORT=${APP_PORT:-8080} + - MANAGEMENT_SERVER_PORT=${MANAGEMENT_PORT:-9080} - AWS_REGION=ap-northeast-2 - SPRING_DATA_REDIS_HOST=127.0.0.1 - SPRING_DATA_REDIS_PORT=6379 diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index f352adeb2..57363231b 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -8,6 +8,7 @@ services: environment: - SPRING_PROFILES_ACTIVE=prod - SERVER_PORT=${APP_PORT:-8080} + - MANAGEMENT_SERVER_PORT=${MANAGEMENT_PORT:-9080} - AWS_REGION=ap-northeast-2 - SPRING_DATA_REDIS_HOST=127.0.0.1 - SPRING_DATA_REDIS_PORT=6379 From 85bec256a60306478b14e694c941e8ae3697e3f5 Mon Sep 17 00:00:00 2001 From: Hexeong <123macanic@naver.com> Date: Mon, 15 Jun 2026 13:25:13 +0900 Subject: [PATCH 3/4] =?UTF-8?q?fix:=20=EC=95=A1=EC=B8=84=EC=97=90=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EB=85=B8=EC=B6=9C=20&=20dev/prod=20=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A6=BD=ED=8A=B8=20=EC=9D=BC=EC=B9=98=20=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/dev-cd.yml | 7 +++---- .github/workflows/prod-cd.yml | 9 ++++----- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/.github/workflows/dev-cd.yml b/.github/workflows/dev-cd.yml index 16f89e680..b75d2a18d 100644 --- a/.github/workflows/dev-cd.yml +++ b/.github/workflows/dev-cd.yml @@ -153,11 +153,10 @@ jobs: docker compose -p "${CONTAINER_BASE}-${NEW_SLOT}" -f docker-compose.dev.yml up -d solid-connection-dev # 8. 헬스 체크 (앱 기동 대기, 최대 150초) - # /actuator/health 미노출로 포트 응답 여부로 확인 (HTTP 000 = 연결 불가) - echo "Waiting for app on port ${NEW_PORT}..." + echo "Waiting for app on management port ${MANAGEMENT_PORT}..." for i in $(seq 1 30); do - HTTP=$(curl -s --connect-timeout 2 -o /dev/null -w "%{http_code}" "http://localhost:${NEW_PORT}/" || true) - [ "$HTTP" != "000" ] && { echo "App responding (HTTP ${HTTP}, attempt ${i})"; break; } + STATUS=$(curl -s --connect-timeout 2 "http://localhost:${MANAGEMENT_PORT}/actuator/health" | grep -o '"status":"UP"' || true) + [ "$STATUS" = '"status":"UP"' ] && { echo "App healthy (attempt ${i})"; break; } [ "$i" = "30" ] && { echo "Health check timed out after 150s" >&2 docker stop "${CONTAINER_BASE}-${NEW_SLOT}" 2>/dev/null || true diff --git a/.github/workflows/prod-cd.yml b/.github/workflows/prod-cd.yml index 1407ff6c4..bb31d5b7d 100644 --- a/.github/workflows/prod-cd.yml +++ b/.github/workflows/prod-cd.yml @@ -161,14 +161,13 @@ jobs: # 5. 새 컨테이너 시작 cd "${WORK_DIR}" SLOT="${NEW_SLOT}" APP_PORT="${NEW_PORT}" MANAGEMENT_PORT="${MANAGEMENT_PORT}" OWNER_LOWERCASE="${OWNER_LOWERCASE}" IMAGE_TAG="${IMAGE_TAG_ONLY}" \ - docker compose -p "${CONTAINER_BASE}-${NEW_SLOT}" -f docker-compose.prod.yml up -d + docker compose -p "${CONTAINER_BASE}-${NEW_SLOT}" -f docker-compose.prod.yml up -d solid-connection-server # 6. 헬스 체크 (앱 기동 대기, 최대 150초) - # /actuator/health 미노출로 포트 응답 여부로 확인 (HTTP 000 = 연결 불가) - echo "Waiting for app on port ${NEW_PORT}..." + echo "Waiting for app on management port ${MANAGEMENT_PORT}..." for i in $(seq 1 30); do - HTTP=$(curl -s --connect-timeout 2 -o /dev/null -w "%{http_code}" "http://localhost:${NEW_PORT}/" || true) - [ "$HTTP" != "000" ] && { echo "App responding (HTTP ${HTTP}, attempt ${i})"; break; } + STATUS=$(curl -s --connect-timeout 2 "http://localhost:${MANAGEMENT_PORT}/actuator/health" | grep -o '"status":"UP"' || true) + [ "$STATUS" = '"status":"UP"' ] && { echo "App healthy (attempt ${i})"; break; } [ "$i" = "30" ] && { echo "Health check timed out after 150s" >&2 docker stop "${CONTAINER_BASE}-${NEW_SLOT}" 2>/dev/null || true From 3934f4145ed52c628a5a1f5af689c75c912fa911 Mon Sep 17 00:00:00 2001 From: Hexeong <123macanic@naver.com> Date: Mon, 15 Jun 2026 19:37:28 +0900 Subject: [PATCH 4/4] =?UTF-8?q?fix:=20=EB=A0=88=EA=B1=B0=EC=8B=9C=20?= =?UTF-8?q?=EC=95=A1=EC=B6=94=EC=97=90=EC=9D=B4=ED=84=B0=20=EB=85=B8?= =?UTF-8?q?=EC=B6=9C=20=ED=8F=AC=ED=8A=B8=EC=99=80=20=EC=9D=BC=EC=B9=98?= =?UTF-8?q?=EC=8B=9C=ED=82=A4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/dev-cd.yml | 4 ++-- .github/workflows/prod-cd.yml | 4 ++-- docker-compose.dev.yml | 2 +- docker-compose.prod.yml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/dev-cd.yml b/.github/workflows/dev-cd.yml index b75d2a18d..60ef98b42 100644 --- a/.github/workflows/dev-cd.yml +++ b/.github/workflows/dev-cd.yml @@ -122,9 +122,9 @@ jobs: # 1. Active 슬롯 확인 (upstream.conf 기준) UPSTREAM_PORT=$(grep -oE "server 127\.0\.0\.1:[0-9]+" /etc/nginx/conf.d/upstream.conf 2>/dev/null | grep -oE "[0-9]+$" || echo "8081") if [ "$UPSTREAM_PORT" = "8080" ]; then - ACTIVE_SLOT="blue"; ACTIVE_PORT=8080; NEW_SLOT="green"; NEW_PORT=8081; MANAGEMENT_PORT=9081 + ACTIVE_SLOT="blue"; ACTIVE_PORT=8080; NEW_SLOT="green"; NEW_PORT=9080; MANAGEMENT_PORT=9081 else - ACTIVE_SLOT="green"; ACTIVE_PORT=8081; NEW_SLOT="blue"; NEW_PORT=8080; MANAGEMENT_PORT=9080 + ACTIVE_SLOT="green"; ACTIVE_PORT=9080; NEW_SLOT="blue"; NEW_PORT=8080; MANAGEMENT_PORT=8081 fi echo "Active: ${ACTIVE_SLOT}(${ACTIVE_PORT}) → Deploy: ${NEW_SLOT}(${NEW_PORT}), management: ${MANAGEMENT_PORT}" diff --git a/.github/workflows/prod-cd.yml b/.github/workflows/prod-cd.yml index bb31d5b7d..606f976a5 100644 --- a/.github/workflows/prod-cd.yml +++ b/.github/workflows/prod-cd.yml @@ -138,9 +138,9 @@ jobs: # 1. Active 슬롯 확인 (upstream.conf 기준) UPSTREAM_PORT=$(grep -oE "server 127\.0\.0\.1:[0-9]+" /etc/nginx/conf.d/upstream.conf 2>/dev/null | grep -oE "[0-9]+$" || echo "8081") if [ "$UPSTREAM_PORT" = "8080" ]; then - ACTIVE_SLOT="blue"; ACTIVE_PORT=8080; NEW_SLOT="green"; NEW_PORT=8081; MANAGEMENT_PORT=9081 + ACTIVE_SLOT="blue"; ACTIVE_PORT=8080; NEW_SLOT="green"; NEW_PORT=9080; MANAGEMENT_PORT=9081 else - ACTIVE_SLOT="green"; ACTIVE_PORT=8081; NEW_SLOT="blue"; NEW_PORT=8080; MANAGEMENT_PORT=9080 + ACTIVE_SLOT="green"; ACTIVE_PORT=9080; NEW_SLOT="blue"; NEW_PORT=8080; MANAGEMENT_PORT=8081 fi echo "Active: ${ACTIVE_SLOT}(${ACTIVE_PORT}) → Deploy: ${NEW_SLOT}(${NEW_PORT}), management: ${MANAGEMENT_PORT}" diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index f2cd9b9e5..6fda6d478 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -8,7 +8,7 @@ services: environment: - SPRING_PROFILES_ACTIVE=dev - SERVER_PORT=${APP_PORT:-8080} - - MANAGEMENT_SERVER_PORT=${MANAGEMENT_PORT:-9080} + - MANAGEMENT_SERVER_PORT=${MANAGEMENT_PORT:-8081} - AWS_REGION=ap-northeast-2 - SPRING_DATA_REDIS_HOST=127.0.0.1 - SPRING_DATA_REDIS_PORT=6379 diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 57363231b..d9879f922 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -8,7 +8,7 @@ services: environment: - SPRING_PROFILES_ACTIVE=prod - SERVER_PORT=${APP_PORT:-8080} - - MANAGEMENT_SERVER_PORT=${MANAGEMENT_PORT:-9080} + - MANAGEMENT_SERVER_PORT=${MANAGEMENT_PORT:-8081} - AWS_REGION=ap-northeast-2 - SPRING_DATA_REDIS_HOST=127.0.0.1 - SPRING_DATA_REDIS_PORT=6379