배포 파이프라인·환경 분리 PRD
Background
sports-application은 현재 로컬 docker-compose 기반의 단일 환경만 존재하며, 이 docker-compose.yml에는 backend 애플리케이션도, MySQL·MongoDB·Redis·Kafka 같은 데이터스토어도 포함돼 있지 않다 — 현재 포함된 것은 minio·mock-pg·mock-servers·mailhog뿐이다. backend는 로컬에서 개발자가 직접 빌드·기동하고, MySQL 등은 별도로(로컬 설치 또는 개별 docker run) 띄운다는 것이 현재 전제다. 즉 “DB 인스턴스를 dev/prod로 분리한다”는 목표 이전에, 앱과 데이터스토어 자체를 docker-compose에 편입하는 작업이 먼저 필요하다.
레포의 실제 브랜치 흐름도 확인이 필요하다 — git 이력(023ccdd9 Merge pull request #102 from biuea3866/chore/dev-main-sync)과 팀 관례상, 이 레포는 feat/fix 브랜치가 dev 브랜치에 먼저 PR 머지되고, main은 dev에서 주기적으로 역동기화(chore/dev-main-sync)되는 안정화 스냅샷이다. 즉 “main 머지가 dev 배포를 트리거한다”는 것은 실제 흐름과 반대다 — dev 브랜치 머지가 활성 개발 통합 지점이고, main은 그보다 안정화된 시점의 스냅샷이다.
요구사항이 dev·prod 두 환경 분리를 요구하면서, dev는 (활성 개발 통합 브랜치인) dev 머지 시 자동 배포, prod는 QA를 통과해야만 배포되는 게이트를 요구한다. 이 QA는 신규 도입 예정인 private-qa 에이전트가 수행하는 회귀·시나리오 검증이다. 또한 기존 .github/workflows/load-test.yml은 staging 환경(target_url: https://staging.example.com)을 대상으로 한 수동 부하 시험 워크플로를 이미 갖고 있다 — 본 과제의 prod가 이 staging과 같은 대상인지 별도 환경인지 정리가 필요하다.
이 과제는 [옵저버빌리티 스택 도입](../옵저버빌리티 스택 도입/PRD.md)이 dev·prod를 구분해 계측하기 위한 환경 경계를 제공하고, [상시 트래픽 시뮬레이터](../상시 트래픽 시뮬레이터/PRD.md)가 “실제 운영처럼” 트래픽을 흘려보낼 prod 대상을 확정하는 선행 과제다. dev·prod는 로컬 docker-compose 기준, 같은 머신에서 포트·컨테이너 네임스페이스만 분리한다 — 별도 클라우드 인프라나 별도 머신을 새로 구축하지 않는다(아래 FR-2에서 확정).
Problem Definition
- backend·MySQL·MongoDB·Redis·Kafka가 docker-compose에 편입돼 있지 않다 — dev/prod 환경 분리를 논하기 전에 이 편입 작업이 선행돼야 한다.
- “main 머지 시 dev 자동 배포”라는 전제가 이 레포의 실제 브랜치 흐름(
feat/fix→devPR 머지,main은dev에서 역동기화)과 반대다 — 배포 트리거 브랜치를 정정해야 한다. - prod에 배포하기 전 검증 게이트가 없다 — 회귀가 있는 변경이 그대로 상시 트래픽 환경에 반영될 위험이 있다.
- 기존
load-test.yml의staging환경 명명과 본 과제의prod가 같은 대상인지 정리되지 않았다. - [상시 트래픽 시뮬레이터](../상시 트래픽 시뮬레이터/PRD.md)가 대상으로 삼을 “안정적인 prod”라는 개념이 아직 존재하지 않는다.
env태그(management.metrics.tags.env: ${APP_ENV:local})는 이미 존재하지만, dev/prod 환경 각각에APP_ENV값을 어떻게 주입할지 정의된 적이 없다.
Goals / Non-Goals
Goals
- 선행 작업으로 backend·MySQL·MongoDB·Redis·Kafka를 docker-compose에 신규 편입한다(현재 mock류만 존재).
- 편입된 스택을 dev·prod 두 환경으로 물리적으로 분리한다 — 같은 머신에서 별도 compose 파일 또는 profile로 포트·컨테이너 네임스페이스·DB 인스턴스를 분리한다.
dev브랜치(활성 개발 통합 브랜치) 머지 시 CI가 dev 환경에 자동으로 빌드·배포한다.- prod 배포는
main(=dev에서 동기화된 안정화 스냅샷) 기준으로,private-qa에이전트의 QA 통과(PASS)를 필수 선행 조건으로 한다. - 기존
load-test.yml의staging환경을 본 과제의prod로 통합한다(3환경 운영은 개인 프로젝트 규모에 과하다) — workflow 파일의staging명칭·타깃 URL은 후속 리네임 대상으로 문서화한다. env라벨 값 체계를 정의한다: 기존APP_ENV환경변수(및 이를 참조하는management.metrics.tags.env)를 dev/prod 각 compose 스택에서APP_ENV=dev/APP_ENV=prod로 주입한다. 새 변수를 만들지 않고 기존APP_ENV를 그대로 재사용한다.- prod 배포 실패 또는 배포 후 이상 감지 시 직전 정상 버전으로 롤백하는 절차를 정의한다.
Non-Goals
- 실제 클라우드 인프라(AWS 등)로의 프로덕션 이전 — “prod”는 본 과제에서 정의하는 로컬 docker-compose 기준, 같은 머신의 별도 컨테이너 스택이다(별도 머신 아님).
private-qa에이전트 자체의 정의·구현(하네스 구성) — 본 PRD는 “prod 배포 전 QA 게이트가 반드시 존재하고 그 결과가 배포 가부를 결정한다”는 프로세스 요구사항만 다룬다. QA 판정 기준 자체의 상세는 하네스 구성 문서(에이전트 정의)에서 다룬다.- Blue-Green·Canary 등 고급 무중단 배포 전략 — 1차 범위는 단순 재기동 기반 배포이며, 고급 전략은 Open Questions에서 향후 검토 대상으로 남긴다.
User Scenarios
페르소나: 개발자(본인).
- 해피 패스 — dev 자동 배포: feature 브랜치 PR이
dev에 머지되면, CI가 자동으로 dev 환경(컨테이너 스택,APP_ENV=dev)에 새 버전을 빌드·배포한다. 개발자는 dev 환경 URL에서 변경 사항을 즉시 확인한다. - 동기화 — main 스냅샷:
dev가 안정화되면 기존 관례대로chore/dev-main-sync로main에 반영된다. - QA 게이트 — prod 배포 승인:
main갱신 후private-qa에이전트가 회귀·시나리오 QA를 실행한다. QA가 PASS를 반환하면 prod 환경(APP_ENV=prod) 배포 파이프라인이 활성화된다. - 예외 — QA 실패: QA가 FAIL을 반환하면 prod 배포가 차단되고, 실패 리포트가 개발자에게 통지된다. 개발자는 원인을 수정해 다시
dev에 머지한다. - 롤백: prod 배포 후 [지능형 장애 알림](../지능형 장애 알림/PRD.md)이 심각한 이상(
source=deployment)을 감지하면, 개발자가 직전 정상 버전으로 롤백을 트리거한다.
Benchmarking
| 제품/사례 | 카테고리 | 참조 패턴 | URL |
|---|---|---|---|
| GitHub Actions Environments + Deployment Protection Rules | CI/CD 배포 게이트 | 환경(Development/QA/Staging/Production)별로 필수 리뷰어·보호 규칙을 설정해, 특정 환경으로의 배포가 조건(승인, 외부 서비스 판정 등)을 충족해야만 진행되도록 파이프라인이 일시 정지·재개되는 구조 — 본 과제의 “QA PASS가 prod 배포의 필수 관문”이라는 요구사항과 동일한 패턴 | GitHub Deployment Environments and Approval Gates |
| GitOps 프로모션(Argo CD + Kargo) | 선언적 배포 프로모션 | dev→staging→prod로 버전을 승격시키되, 각 단계 승격 조건을 Git 기반으로 선언하고 자동화하는 패턴 — dev 브랜치 머지 시 dev 자동 반영, 이후 검증 통과 시에만 다음 환경으로 승격되는 본 과제의 흐름과 대응 | From Commit to Production — GitOps Promotion |
Functional Requirements
| ID | 요구사항 | 우선순위 |
|---|---|---|
| FR-1 | (선행) docker-compose에 backend·MySQL·MongoDB·Redis·Kafka를 신규 편입한다 — 현재는 mock류(minio·mock-pg·mock-servers·mailhog)만 존재한다 | P0 |
| FR-2 | FR-1로 편입된 스택을 dev·prod 두 환경으로 분리한다 — 같은 머신에서 별도 compose 파일 또는 profile로 포트·컨테이너 네임스페이스·DB 인스턴스를 분리한다(별도 머신 아님, 확정) | P0 |
| FR-3 | dev 브랜치(활성 개발 통합 브랜치) 머지 시 CI(GitHub Actions)가 자동으로 dev 환경에 빌드·배포한다 | P0 |
| FR-4 | prod 배포는 main(dev에서 동기화된 스냅샷) 기준으로, private-qa 에이전트의 QA 실행 결과가 PASS일 때만 실행된다 — QA 미통과 시 prod 배포 파이프라인이 트리거되지 않는다 | P0 |
| FR-5 | dev·prod 각 compose 스택에서 기존 APP_ENV 환경변수를 각각 dev/prod로 주입한다(신규 라벨 키 도입 없이 기존 env 태그 체계를 그대로 사용) | P0 |
| FR-6 | 기존 load-test.yml의 staging 타깃을 본 과제의 prod 환경으로 통합하고, workflow 리네임(예: staging→prod 명칭 정리)을 후속 작업으로 문서화한다 | P1 |
| FR-7 | QA 게이트의 결과(PASS/FAIL)와 근거 리포트를 배포 파이프라인 로그에 남긴다 | P1 |
| FR-8 | prod 배포 실패 또는 배포 후 이상 감지 시 직전 정상 버전으로 롤백하는 절차를 정의하고 실행 가능하게 한다 | P1 |
| FR-9 | dev·prod 환경별 접근 권한 정책을 수립한다(예: prod는 배포 파이프라인 외 직접 변경 경로를 최소화) | P2 |
Non-Functional Requirements
dev브랜치 머지 후 dev 환경 반영까지 10분 이내.- QA 게이트를 통과하지 않은 상태에서 prod 배포가 실행되는 경로 0건(강제).
- prod 롤백은 트리거 후 5분 이내 이전 정상 상태로 복구된다.
- FR-5의
APP_ENV값 주입 누락(빈 값 또는local기본값이 dev/prod 환경에 그대로 남는 경우) 0건.
Operations
- dev·prod 배포 이력과 QA 게이트 통과/실패 이력을 [옵저버빌리티 스택 도입](../옵저버빌리티 스택 도입/PRD.md) 대시보드 또는 별도 배포 로그에 기록한다.
- 배포 실패 또는 QA 게이트 실패 시 [지능형 장애 알림](../지능형 장애 알림/PRD.md) 채널로 통지하되,
source=deployment로 태깅해 런타임 장애 알림과 구분한다.
Success Metrics
dev머지 → dev 반영 자동화율 100%(수동 개입 0건) — 측정 방법: GitHub Actions run 이력에서dev머지 커밋과 배포 워크플로 트리거 시각의 대응 관계를 확인한다.- QA 미통과 상태에서 prod 배포 시도 시 차단율 100% — 측정 방법:
private-qa게이트 로그(QA FAIL 리포트)와 배포 워크플로 실행 이력을 대조해, FAIL 이후 prod 배포 job이 실행되지 않았음을 확인한다. - 롤백 목표 시간(5분) 이내 복구 달성률 100%.
Milestones
- M1: docker-compose 앱·데이터스토어 편입(FR-1, 선행 — 이 milestone 없이는 M2 이후 진행 불가).
- M2: dev·prod 환경 분리(FR-2),
APP_ENV주입(FR-5). - M3: dev 자동 배포 CI(FR-3).
- M4: QA 게이트 연동(FR-4, FR-7) —
private-qa에이전트의 QA PASS 판정 기준이 최소한이라도 정의되는 것이 이 milestone의 완료 전제 조건이다(Open Questions 참조, 미정 상태로는 M4를 완료로 간주하지 않는다). - M5: staging→prod 통합(FR-6), prod 배포 + 롤백(FR-8, FR-9).
이 과제는 [옵저버빌리티 스택 도입](../옵저버빌리티 스택 도입/PRD.md)과 [상시 트래픽 시뮬레이터](../상시 트래픽 시뮬레이터/PRD.md)의 선행 조건이다 — 두 과제 모두 dev·prod 환경 경계가 확정된 이후에 환경별 대상을 정의할 수 있다. [도메인 경계 재설계](../도메인 경계 재설계/PRD.md)와는 독립적으로 병행 가능하다.
Open Questions
private-qa에이전트의 QA 판정 최소 기준(예: 전 회귀 시나리오 100% 통과, 특정 핵심 시나리오만 통과 등)을 이 과제 관점에서 최소한으로 정의해야 한다 — 상세 구현은 하네스 구성(에이전트 정의) 범위이나, M4 완료를 위해 최소 기준만은 이 과제에서 합의돼야 한다.- Blue-Green 등 무중단 배포 전략 도입 여부와 시점을 결정해야 한다.
Document History
| 날짜 | 변경 내용 |
|---|---|
| 2026-07-03 | 최초 작성 |
| 2026-07-03 | 재검수 1차 반영: 브랜치↔환경 매핑 정정(main 머지가 아니라 dev 브랜치 머지가 dev 배포 트리거, main은 dev에서 역동기화되는 스냅샷), docker-compose에 앱·데이터스토어 자체가 없다는 선행 편입 작업을 FR-1로 신설, 기존 load-test.yml의 staging 환경을 prod로 통합하는 FR-6 추가, FR-1(현 FR-2, 같은 머신 확정)과 모순되던 Open Questions 항목 제거, QA PASS 정의 미확정 상태를 M4 완료 전제 조건으로 명시, Success Metrics에 측정 방법(GitHub Actions 로그·QA 게이트 로그) 연결, 기존 APP_ENV/env 태그 재사용을 FR-5로 명시 |