website: 스모크 테스트 도입 — 배포 후 핵심 조회 API 실동작 확인
배포 파이프라인 `cd.yml`에 있던 빈 껍데기 "스모크 테스트" 스텝을 실제로 동작하게 채우고, 검증 방식을 SSH+localhost에서 공개 도메인 직접 호출로 바꾼 PR입니다. dev 브랜치를 대상으로 병합됐습니다.
cd.yml의 스모크 테스트 스텝은 이름만 있고 실제로는 주석 처리된 curl 예시만 들어 있는 상태였다. "엔드포인트 구현 후 아래에 추가"라고만 적힌 채 비어 있었고, 그 예시조차 BASE_URL을 OCI_HOST:포트로 잡는 구조라 애초에 동작할 수 없었다. 확인해보니 8080/8081 포트는 보안 목록상 막혀 있고, nginx가 붙은 80/443만 열려 있었다.
헬스체크(/actuator/health)는 이미 파이프라인에 있었지만, 이는 앱 프로세스가 떴는지만 보장할 뿐 DB 연결이나 JPA 매핑, 직렬화가 정상 동작하는지는 확인해주지 않는다. 배포 후 핵심 기능이 실제로 살아있는지 확인할 방법이 없었다.
구현
첫 커밋에서는 SSH로 서버에 들어가 localhost를 직접 호출하는 방식으로 구현했다. 헬스체크보다 한 단계 더 들어간 검증(DB, JPA, 직렬화까지)이 가능했고, stage 환경에서 4개 엔드포인트(/api/members, /api/staff, /api/posts, /api/projects) 모두 200을 확인했다.
리뷰에서는 SSH+localhost 방식이 앱 프로세스 동작은 확인하지만 DNS, TLS, nginx 라우팅 등 실제 사용자 경로는 검증하지 못한다는 지적이 있었다. nginx.conf를 확인해보니 api.stage.likelion-khu.com, api.prod.likelion-khu.com이 이미 공개 도메인으로 열려 있어서, GitHub Actions 러너에서 이 도메인을 직접 호출하는 방식으로 최종 구현을 변경했다. SSH 왕복이 사라지면서 스텝도 단순해졌다.
- name: 스모크 테스트
run: |
BASE_URL="https://api.${{ steps.config.outputs.env }}.likelion-khu.com"
FAILED=0
for path in /api/members /api/staff /api/posts /api/projects; do
STATUS=BASE_URL$path" || echo "000")
if [ "$STATUS" == "200" ]; then
echo "✅ [STATUS"
else
echo "❌ [{STATUS}"
FAILED=1
fi
done
[ "$FAILED" == "1" ] && exit 1
echo "=== 스모크 테스트 완료 ==="
대상은 인증 없이 이미 공개된 조회용 API 4개로 한정했다. 어드민류는 인증이 필요해 제외했다. 실패 시 기존 롤백 스텝(if: failure())이 그대로 이어받아 자동으로 이전 태그로 되돌리므로 별도 롤백 로직은 필요 없었다. 변경 파일은 .github/workflows/cd.yml 하나, 추가 21줄·삭제 4줄이다.
부가 발견
검증 중 prod(api.prod.likelion-khu.com)의 /api/staff, /api/projects가 401을 반환하는 걸 확인했다. localhost 호출에서도 동일하게 401이 나와 nginx 문제는 아니었고, prod(main) 브랜치가 dev의 최근 병합분(staff/project 모듈 도입 + SecurityConfig의 permitAll 설정)을 아직 반영하지 못한 상태가 원인이었다. 이 PR은 dev만 대상으로 하므로 현재 prod CD에는 영향이 없고, 다음 dev→main 승격 시 자연히 해소된다.
배포 파이프라인에 검증 스텝을 넣을 때는 무엇을 검증 대상으로 삼을지가 결과의 신뢰도를 좌우한다. 헬스체크만으로는 부족했고, 서버 내부 검증도 사용자가 실제로 겪는 경로 전체를 보장하지는 못했다. 병합 후 dev CD에서 스모크 테스트가 stage 도메인으로 정상 통과하는지, 실패 시나리오에서 롤백이 제대로 트리거되는지는 다음 검증 대상이다.