Skip to content

[ Infra ] 운영 배포 파이프라인이 시크릿 미설정으로 계속 실패한다 #94

Open

Description

@RosieOh

💚 어떤 기능인가요?

main 에 머지해도 운영 배포가 되지 않는다. 배포용 시크릿이 비어 있어
Deploy to Production (Blue/Green) 잡이 첫 스텝에서 죽는다.

머지 결과
#78 (2026-08-12) Test/Build/Scan 통과, Deploy to Production 실패
#80 (2026-08-22) Test/Build/Scan 통과, Deploy to Production 실패
success  3. Determine deployment strategy
failure  4. Deploy to target environment      ← test -n "${{ secrets.PRODUCTION_DEPLOY_HOST }}"
skipped  5. Wait for target instance to be ready
skipped  6. Switch traffic to new environment
failure  8. Rollback if needed                ← PRODUCTION_ROUTER_SWITCH_URL 도 비어 있음

로그에서 PRODUCTION_HEALTH_URL: 이 공란으로 찍힌다.

컨테이너를 띄우기 전에 멈추므로 운영 인스턴스를 건드리지는 않는다. 장애는 없다.
문제는 그 반대다 — 아무것도 배포되지 않는데 파이프라인이 그걸 조용히 넘기지 않고
매번 빨간불로 끝나서, 이제는 그 빨간불이 정상처럼 보인다.

지금 당장 문제가 되는 이유

#80 이 P0 두 건(#82 가입 시 role 신뢰, #83 /users 권한 상승)을 고쳤지만
운영에는 반영되지 않았다. 코드가 main 에 있을 뿐이다.
수동 배포를 하지 않으면 "누구나 관리자가 될 수 있는" 상태가 그대로 남는다.

확인이 필요한 시크릿

Deploy to Staging 은 develop 브랜치용이라 지금은 skip 된다. 운영 쪽만 보면 된다.

  • PRODUCTION_DEPLOY_HOST
  • PRODUCTION_DEPLOY_USER
  • PRODUCTION_HEALTH_URL
  • PRODUCTION_ROUTER_STATUS_URL
  • PRODUCTION_ROUTER_SWITCH_URL
  • PRODUCTION_ROUTER_TOKEN
  • PRODUCTION_TARGET_HEALTH_URL_TEMPLATE

또 SSH 로 접속하는데 워크플로에 개인키를 로드하는 스텝이 없다.
ssh -o StrictHostKeyChecking=no ... 만 있어서, 시크릿을 채워도 인증에서 다시 막힐 가능성이 크다.
(테스트·스캔 잡에 배포키를 올리지 않으려고 의도적으로 뺀 흔적이 주석에 있는데,
정작 배포 잡에도 추가되지 않았다.)

배포 시 함께 필요한 환경변수

#80 에서 인증 메일 기준 주소를 필수로 바꿨다. 없으면 기동이 실패한다(의도된 fail-fast).

✅ To Dos

  • 운영 배포 시크릿 7종 설정
  • 배포 잡에 SSH 개인키 로드 스텝 추가 (webfactory/ssh-agent 등)
  • /opt/carecode/.env 에 EMAIL_VERIFICATION_BASE_URL 추가
  • 파이프라인이 실제로 끝까지 도는지 한 번 확인 (블루/그린 전환 + 롤백 경로 포함)
  • 그때까지는 FIX : 권한 상승 경로 차단과 커뮤니티 N+1 개선 #80 의 보안 수정을 수동 배포로 먼저 반영
  • 배포 실패가 눈에 띄도록 알림 연결 (현재 Notify deployment status 는 echo 만 한다)

Activity

  1. added this to the Hotfix milestone on Aug 22, 2026
  2. added theissue type on Aug 22, 2026
  3. RosieOh commented on Aug 24, 2026

    @RosieOh
    ContributorAuthor

    저장소 쪽 몫 처리 — PR #97

    시크릿 미설정이 직접 원인이지만, 확인해보니 시크릿을 채워도 그대로는 통과하지 못하는
    상태였다. 그 부분을 먼저 고쳤다.

    고친 것

    문제 조치
    SSH 개인키 로드 스텝이 아예 없음 — 시크릿을 채워도 인증에서 막힘 키를 env 로 받아 ~/.ssh/deploy_key 에 쓰고 -i 로 지정. StrictHostKeyChecking=no 제거
    시크릿이 없을 때 무엇이 없는지 알 수 없음 잡 시작 시 전부 확인하고 이름을 찍어 실패
    롤백이 트래픽 전환 전에도 발동 failure() && steps.switch.outcome == 'success'
    배포 실패가 아무에게도 안 닿음 (echo 만) 잡 요약 + ::error:: + OPS_SLACK_WEBHOOK_URL 있으면 슬랙
    시크릿을 run: 본문에 직접 박아 씀 전부 env: 로 이동
    전역 env 에 헬스 URL 제거 — test/scan 잡 환경에까지 실릴 이유가 없다

    YAML 파싱과 run 블록 19개 전부 bash -n 문법 검사를 통과했다.
    필요한 시크릿 목록은 docs/features/operations.md 에 표로 정리했다.

    남은 몫 (저장소 밖이라 여기서 못 함)

    • PRODUCTION_DEPLOY_HOST
    • PRODUCTION_DEPLOY_USER
    • PRODUCTION_SSH_KEY ← 새로 필요. 이게 없으면 위 스텝이 무의미하다
    • PRODUCTION_HEALTH_URL
    • PRODUCTION_TARGET_HEALTH_URL_TEMPLATE — {port} 를 포함해야 한다
    • PRODUCTION_ROUTER_STATUS_URL
    • PRODUCTION_ROUTER_SWITCH_URL
    • PRODUCTION_ROUTER_TOKEN
    • 서버 /opt/carecode/.env 에 EMAIL_VERIFICATION_BASE_URL 추가 ([ Infra ] #80 머지 전 운영 전제 확인 (XFF 신뢰, 리프레시 토큰 저장소) #90)
    • 선택: PRODUCTION_SSH_KNOWN_HOSTS(호스트키 고정), OPS_SLACK_WEBHOOK_URL(실패 알림)

    스테이징은 STAGING_ 접두사로 DEPLOY_HOST / DEPLOY_USER / SSH_KEY / HEALTH_URL 네 개.

    확인 방법

    시크릿을 채운 뒤 workflow_dispatch 로 한 번 돌리면 전환·롤백 경로까지 실제로 도는지 볼 수 있다.
    채우기 전에 돌리면 이제는 첫 스텝에서 빠진 이름을 찍고 멈춘다.

    왜 급한지

    #80 (권한 상승 P0 2건), #96 (아이 특이사항 유실) 이 main 에 머지됐지만
    배포되지 않아 사용자에게 닿지 않았다. 파이프라인이 복구될 때까지는
    수동 배포가 필요하다.

  4. RosieOh commented on Aug 24, 2026

    @RosieOh
    ContributorAuthor

    정정 — 시크릿을 채워도 이 워크플로는 완주할 수 없다

    앞선 코멘트에서 "시크릿을 채우면 된다"는 취지로 적었는데, 틀렸다.
    조직의 다른 저장소까지 확인하고 나서 알게 된 내용이다.

    워크플로가 가정하는 router API 가 존재하지 않는다

    블루/그린 전환이 HTTP 엔드포인트 두 개를 전제한다.

    CURRENT_ENV=$(curl -fsS "$ROUTER_STATUS_URL" || echo "blue")   # 현재 활성 색 조회
    curl -X POST "$ROUTER_SWITCH_URL" -H "Authorization: Bearer $ROUTER_TOKEN" ...  # 전환

    그런데 실제 블루/그린 도구인 CareCode_Nohub_Deploy 는 HTTP 서버가 아니다.

    requirements.txt: requests, python-dotenv, paramiko     ← 웹 프레임워크 없음
    사용법: python src/scripts/deploy.py --action full --version <버전>
    

    paramiko 로 SSH 해서 nginx conf 를 바꾸는 CLI 도구다.
    ROUTER_STATUS_URL / ROUTER_SWITCH_URL 을 제공하는 구현은 조직 어디에도 없다.

    즉 시크릿을 다 채워도 Switch traffic to new environment 에서 멈춘다.
    컨테이너는 뜨지만 트래픽이 넘어가지 않는다. 그리고 그 시점에는 이미
    Deploy to target environment 가 서버의 컨테이너를 갈아치운 뒤다.

    배포 경로가 세 갈래로 갈려 있다

    경로 위치 상태
    GitHub Actions (SSH + docker run) 이 저장소 ci-cd.yml 완주 불가 — router API 없음
    Python 블루/그린 CLI CareCode_Nohub_Deploy 수동 실행
    K8s + ArgoCD + Istio + Jenkins CareCode_CICD —

    CareCode_CICD README 는 jenkins/Jenkinsfile 이 "앱 저장소에서 실행된다" 고 적고 있는데,
    이 저장소에 Jenkinsfile 이 없다. 워크플로도 ci-cd.yml, codeql.yml 둘뿐이다.

    덧붙여 이 저장소 README 는 docker-compose.yml 과 Nginx 설정을 프로젝트 구조에 명시하고
    배포 가이드도 docker-compose up -d 로 안내하는데, 두 파일 모두 저장소에 없다.

    그래서 #97 은?

    #97 이 고친 것(SSH 키 로드, 시크릿 누락 시 이름 표시, 롤백 조건, 실패 알림)은
    그 자체로는 여전히 맞다. 다만 "고치면 배포가 된다"는 전제는 성립하지 않는다.
    router API 가 없는 한 어느 쪽이든 완주하지 못한다.

    판단이 필요하다.

    • A. GHA 배포 잡을 제거/비활성화 — 실제 배포는 Nohub_Deploy 나 ArgoCD 가 한다.
      머지마다 빨간불이 뜨는 걸 없애는 게 우선. 지금은 실패가 정상처럼 보인다.
    • B. router API 를 만든다 — CareCode_Nohub_Deploy 에 상태·전환 엔드포인트를 붙여
      워크플로가 호출할 수 있게 한다.
    • C. GHA 에서 Nohub_Deploy CLI 를 직접 호출 — SSH 로 deploy.py --action full 을
      실행하는 방식. router API 없이도 성립한다.

    어느 쪽이든 "세 경로 중 무엇이 정본인가" 를 먼저 정해야 한다.
    그게 정해지지 않은 채로는 어떤 수정도 다른 두 경로와 계속 어긋난다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:infra인프라/설정/배포priority:P0즉시 대응 필요type:bug버그/회귀 이슈

    Type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions