fix: stabilize green-blue deploy verification
TaxBaik CI/CD / build-and-deploy (push) Failing after 8m16s

This commit is contained in:
2026-07-04 10:46:45 +09:00
parent 58bec88d7d
commit aff388df2d
2 changed files with 82 additions and 15 deletions
+41 -13
View File
@@ -170,6 +170,7 @@ jobs:
DEPLOY_HOME="/home/kjh2064" DEPLOY_HOME="/home/kjh2064"
DEPLOY_DIR="\$DEPLOY_HOME/deployments/taxbaik_${TIMESTAMP}" DEPLOY_DIR="\$DEPLOY_HOME/deployments/taxbaik_${TIMESTAMP}"
TIMESTAMP="${TIMESTAMP}" TIMESTAMP="${TIMESTAMP}"
COMMIT="${COMMIT}"
echo "--- [1/5] 압축 해제 ---" echo "--- [1/5] 압축 해제 ---"
mkdir -p "\$DEPLOY_DIR" mkdir -p "\$DEPLOY_DIR"
@@ -233,39 +234,57 @@ jobs:
echo "--- [5/5] 헬스 체크 (최대 60초) ---" echo "--- [5/5] 헬스 체크 (최대 60초) ---"
ATTEMPTS=20 ATTEMPTS=20
for i in \$(seq 1 \$ATTEMPTS); do for i in \$(seq 1 \$ATTEMPTS); do
STATUS=\$(curl -sf -o /dev/null -w '%{http_code}' http://127.0.0.1:5001/taxbaik/ 2>/dev/null || echo "000") STATUS=\$(curl -sf -o /dev/null -w '%{http_code}' http://127.0.0.1:5001/taxbaik/healthz 2>/dev/null || echo "000")
if [ "\$STATUS" = "200" ]; then if [ "\$STATUS" = "200" ]; then
echo "✓ [1/4] 메인 페이지 로드 완료" echo "✓ [1/6] 헬스 체크 완료"
# 검증 1: CSS 파일 로드 # 검증 1: 메인 페이지 로드. 앱/프록시/PathBase 조합에서 canonical redirect가
# 발생할 수 있으므로 리다이렉트를 따라가 최종 200을 검증한다.
MAIN_STATUS=\$(curl -fsSL -o /dev/null -w '%{http_code}' http://127.0.0.1:5001/taxbaik/ 2>/dev/null || echo "000")
if [ "\$MAIN_STATUS" != "200" ]; then
echo "❌ 메인 페이지 로드 실패 (상태: \$MAIN_STATUS)" >&2
exit 1
fi
echo "✓ [2/6] 메인 페이지 로드 완료"
# 검증 2: CSS 파일 로드
CSS_STATUS=\$(curl -sf -o /dev/null -w '%{http_code}' http://127.0.0.1:5001/taxbaik/css/admin.css 2>/dev/null || echo "000") CSS_STATUS=\$(curl -sf -o /dev/null -w '%{http_code}' http://127.0.0.1:5001/taxbaik/css/admin.css 2>/dev/null || echo "000")
if [ "\$CSS_STATUS" != "200" ]; then if [ "\$CSS_STATUS" != "200" ]; then
echo "❌ CSS 파일 로드 실패 (상태: \$CSS_STATUS)" >&2 echo "❌ CSS 파일 로드 실패 (상태: \$CSS_STATUS)" >&2
exit 1 exit 1
fi fi
echo "✓ [2/4] CSS 파일 로드 완료" echo "✓ [3/6] CSS 파일 로드 완료"
# 검증 2: 버전 정보 # 검증 3: 버전 정보. 파일 존재만 보면 5001이 잘못된 구 프로세스를
# 가리키는 장애를 놓치므로, HTTP 응답이 이번 커밋인지 확인한다.
if [ ! -s "\$DEPLOY_DIR/wwwroot/version.json" ]; then if [ ! -s "\$DEPLOY_DIR/wwwroot/version.json" ]; then
echo "❌ version.json 누락" >&2 echo "❌ version.json 누락" >&2
exit 1 exit 1
fi fi
echo "✓ [3/4] 버전 정보 확인 완료" VERSION_JSON=\$(curl -fsS http://127.0.0.1:5001/taxbaik/version.json 2>/dev/null || true)
if ! printf '%s' "\$VERSION_JSON" | grep -q "\"version\": \"\$COMMIT\""; then
echo "❌ 5001 프록시가 이번 배포 버전을 제공하지 않음" >&2
echo " expected: \$COMMIT" >&2
echo " actual: \$VERSION_JSON" >&2
echo " 확인: 5001 포트가 TaxBaik.Proxy.dll인지, /home/kjh2064/taxbaik_port가 새 포트인지 점검" >&2
exit 1
fi
echo "✓ [4/6] 버전 정보 확인 완료"
# 검증 4: 5001 프록시 확인 # 검증 4: 5001 프록시 확인
if ! ss -tlnp | grep -q ':5001 '; then if ! ss -tlnp | grep -q ':5001 '; then
echo "❌ 5001 프록시가 실행 중이 아님" >&2 echo "❌ 5001 프록시가 실행 중이 아님" >&2
exit 1 exit 1
fi fi
echo "✓ [4/5] 5001 프록시 확인 완료" echo "✓ [5/6] 5001 프록시 확인 완료"
# 검증 5: 관리자 로그인 페이지 # 검증 5: 관리자 로그인 페이지
LOGIN_STATUS=\$(curl -sf -o /dev/null -w '%{http_code}' http://127.0.0.1:5001/taxbaik/admin/login 2>/dev/null || echo "000") LOGIN_STATUS=\$(curl -fsSL -o /dev/null -w '%{http_code}' http://127.0.0.1:5001/taxbaik/admin/login 2>/dev/null || echo "000")
if [ "\$LOGIN_STATUS" != "200" ]; then if [ "\$LOGIN_STATUS" != "200" ]; then
echo "❌ 관리자 로그인 페이지 로드 실패 (상태: \$LOGIN_STATUS)" >&2 echo "❌ 관리자 로그인 페이지 로드 실패 (상태: \$LOGIN_STATUS)" >&2
exit 1 exit 1
fi fi
echo "✓ [5/5] 관리자 페이지 로드 완료" echo "✓ [6/6] 관리자 페이지 로드 완료"
echo "✓ 서비스 정상 (시도 \$i/\$ATTEMPTS)" echo "✓ 서비스 정상 (시도 \$i/\$ATTEMPTS)"
# 구 배포 디렉토리 정리 (최근 5개 보존) # 구 배포 디렉토리 정리 (최근 5개 보존)
@@ -275,10 +294,19 @@ jobs:
fi fi
if [ "\$i" -eq "\$ATTEMPTS" ]; then if [ "\$i" -eq "\$ATTEMPTS" ]; then
echo "=== FATAL: 서비스가 \$ATTEMPTS회 시도 후에도 응답하지 않음 ===" >&2 echo "=== FATAL: 서비스가 \$ATTEMPTS회 시도 후에도 응답하지 않음 ===" >&2
echo "--- systemd 상태 ---" >&2 echo "--- 5001 listener ---" >&2
systemctl is-active taxbaik >&2 || true ss -tlnp 2>/dev/null | grep ':5001 ' >&2 || true
echo "--- 최근 로그 50줄 ---" >&2 echo "--- active port file ---" >&2
journalctl -u taxbaik --no-pager -n 50 >&2 cat "\$DEPLOY_HOME/taxbaik_port" >&2 || true
echo "--- 신규 앱 로그 ---" >&2
ACTIVE_PORT=\$(cat "\$DEPLOY_HOME/taxbaik_port" 2>/dev/null | tr -d '[:space:]' || true)
if [ -n "\$ACTIVE_PORT" ] && [ -s "\$DEPLOY_DIR/web_\${ACTIVE_PORT}.log" ]; then
tail -n 80 "\$DEPLOY_DIR/web_\${ACTIVE_PORT}.log" >&2
else
ls -la "\$DEPLOY_DIR" >&2 || true
fi
echo "--- proxy 로그 ---" >&2
tail -n 80 "\$DEPLOY_HOME/taxbaik_proxy.log" >&2 || true
exit 1 exit 1
fi fi
echo " 대기 중... (\$i/\$ATTEMPTS, HTTP \$STATUS)" echo " 대기 중... (\$i/\$ATTEMPTS, HTTP \$STATUS)"
+41 -2
View File
@@ -48,17 +48,56 @@ if [ ! -s "$DEPLOY_DIR/proxy/TaxBaik.Proxy.dll" ]; then
exit 1 exit 1
fi fi
is_taxbaik_proxy_on_5001() {
local pids
pids=$(ss -tlnp 2>/dev/null | grep ':5001 ' | grep -oP 'pid=\K\d+' | sort -u || true)
[ -n "$pids" ] || return 1
for pid in $pids; do
if tr '\0' ' ' < "/proc/$pid/cmdline" 2>/dev/null | grep -q 'TaxBaik.Proxy.dll'; then
return 0
fi
done
return 1
}
# 0. Ensure the local TCP proxy exists and is running. # 0. Ensure the local TCP proxy exists and is running.
# Nginx and external traffic always enter through 127.0.0.1:5001. # Nginx and external traffic always enter through 127.0.0.1:5001.
if ! ss -tln | grep -q ':5001 '; then if ss -tln | grep -q ':5001 ' && ! is_taxbaik_proxy_on_5001; then
echo "⚠️ Port 5001 is occupied by a non-proxy process. Attempting to stop legacy taxbaik.service..."
echo " Current listener:" >&2
ss -tlnp 2>/dev/null | grep ':5001 ' >&2 || true
if command -v systemctl >/dev/null 2>&1 && systemctl is-active --quiet taxbaik 2>/dev/null; then
if command -v sudo >/dev/null 2>&1 && sudo -n true 2>/dev/null; then
sudo -n systemctl stop taxbaik || true
sudo -n systemctl disable taxbaik || true
sleep 2
else
echo " sudo -n is unavailable; cannot stop legacy taxbaik.service automatically." >&2
fi
fi
if ss -tln | grep -q ':5001 ' && ! is_taxbaik_proxy_on_5001; then
echo "❌ Port 5001 is still occupied by a non-proxy process. Abort deploy to avoid routing traffic to the wrong app." >&2
echo " Expected: TaxBaik.Proxy.dll on 127.0.0.1:5001" >&2
echo " Manual fix: sudo systemctl stop taxbaik && sudo systemctl disable taxbaik" >&2
ss -tlnp 2>/dev/null | grep ':5001 ' >&2 || true
exit 1
fi
fi
if ! is_taxbaik_proxy_on_5001; then
echo "=== Starting proxy on 127.0.0.1:5001 ===" echo "=== Starting proxy on 127.0.0.1:5001 ==="
cd "$DEPLOY_DIR/proxy" cd "$DEPLOY_DIR/proxy"
nohup /usr/bin/dotnet TaxBaik.Proxy.dll > "$DEPLOY_HOME/taxbaik_proxy.log" 2>&1 & nohup /usr/bin/dotnet TaxBaik.Proxy.dll > "$DEPLOY_HOME/taxbaik_proxy.log" 2>&1 &
sleep 2 sleep 2
fi fi
if ! ss -tln | grep -q ':5001 '; then if ! is_taxbaik_proxy_on_5001; then
echo "❌ Proxy on 127.0.0.1:5001 is not running. Abort deploy." >&2 echo "❌ Proxy on 127.0.0.1:5001 is not running. Abort deploy." >&2
ss -tlnp 2>/dev/null | grep ':5001 ' >&2 || true
exit 1 exit 1
fi fi