---
name: shipping-and-launch
description: 프로덕션 출시를 준비합니다. 프로덕션 배포를 준비할 때, 또는 출시 전에 무엇을 갖춰야 하는지 물을 때 사용하세요. 출시 전 체크리스트가 필요할 때, 모니터링을 설정할 때, 단계적 롤아웃을 계획할 때, 롤백 전략이 필요할 때 사용하세요.
---
# Shipping and Launch
## 개요
확신을 갖고 출시하세요. 목표는 배포 자체가 아닙니다. 모니터링을 갖추고, 롤백 계획을 준비하며, 성공이 어떤 모습인지 명확히 알고 안전하게 배포하는 일입니다. 모든 출시는 되돌릴 수 있고, 관찰할 수 있고, 점진적이어야 합니다.
## 언제 사용하나
- 기능을 프로덕션에 처음 배포할 때
- 사용자에게 큰 변경을 릴리스할 때
- 데이터나 인프라를 마이그레이션할 때
- 베타 또는 얼리 액세스 프로그램을 열 때
- 위험이 있는 모든 배포 (배포는 모두 그렇습니다)
## 출시 전 체크리스트
### 코드 품질
- [ ] 모든 테스트가 통과합니다 (단위, 통합, e2e)
- [ ] 경고 없이 빌드가 성공합니다
- [ ] 린트와 타입 체크가 통과합니다
- [ ] 코드 리뷰가 완료되고 승인되었습니다
- [ ] 출시 전에 해결해야 할 TODO 주석이 없습니다
- [ ] 프로덕션 코드에 디버깅용 `console.log`가 없습니다
- [ ] 오류 처리가 예상되는 실패 양상을 다룹니다
### 보안
- [ ] 코드나 버전 관리에 시크릿이 없습니다
- [ ] 생태계의 의존성 감사 (`npm audit`, `pip-audit`, `cargo audit` 등)에서 치명적 또는 높음 취약점이 없습니다
- [ ] 모든 사용자 대면 엔드포인트에 입력 검증이 있습니다
- [ ] 인증과 인가 검사가 있습니다
- [ ] 보안 헤더가 구성되었습니다 (CSP, HSTS 등)
- [ ] 인증 엔드포인트에 속도 제한이 있습니다
- [ ] CORS가 특정 오리진으로 구성되었습니다 (와일드카드가 아님)
### 성능
- [ ] Core Web Vitals가 "Good" 기준 안에 있습니다
- [ ] 핵심 경로에 N+1 쿼리가 없습니다
- [ ] 이미지가 최적화되었습니다 (압축, 반응형 크기, 지연 로딩)
- [ ] 번들 크기가 예산 안에 있습니다
- [ ] 데이터베이스 쿼리에 적절한 인덱스가 있습니다
- [ ] 정적 자산과 반복 쿼리에 캐시가 구성되었습니다
### 접근성
- [ ] 모든 상호작용 요소에서 키보드 탐색이 동작합니다
- [ ] 스크린 리더가 페이지 콘텐츠와 구조를 전달할 수 있습니다
- [ ] 색 대비가 WCAG 2.1 AA를 충족합니다 (텍스트 4.5:1)
- [ ] 모달과 동적 콘텐츠의 포커스 관리가 올바릅니다
- [ ] 오류 메시지가 구체적이고 폼 필드와 연결됩니다
- [ ] axe-core나 Lighthouse에 접근성 경고가 없습니다
### 인프라
- [ ] 프로덕션에 환경 변수가 설정되었습니다
- [ ] 데이터베이스 마이그레이션이 적용되었습니다 (또는 적용 준비가 되었습니다)
- [ ] DNS와 SSL이 구성되었습니다
- [ ] 정적 자산용 CDN이 구성되었습니다
- [ ] 로깅과 오류 보고가 구성되었습니다
- [ ] 헬스 체크 엔드포인트가 있고 응답합니다
### 문서
- [ ] 새로운 설정 요구사항이 있으면 README를 업데이트했습니다
- [ ] API 문서가 최신입니다
- [ ] 아키텍처 결정이 있으면 ADR을 작성했습니다
- [ ] 변경 이력을 업데이트했습니다
- [ ] 해당되면 사용자 대면 문서를 업데이트했습니다
## 피처 플래그 전략
피처 플래그 뒤에 출시해서 배포와 릴리스를 분리하세요.
```typescript
// Feature flag check
const flags = await getFeatureFlags(userId);
if (flags.taskSharing) {
// New feature: task sharing
return ;
}
// Default: existing behavior
return null;
```
**피처 플래그 수명 주기:**
```
1. 플래그 OFF로 배포 → 코드는 프로덕션에 있지만 비활성
2. 팀/베타에 활성화 → 프로덕션 환경에서 내부 테스트
3. 점진적 롤아웃 → 사용자의 5% → 25% → 50% → 100%
4. 각 단계에서 모니터링 → 오류율, 성능, 사용자 피드백을 지켜봅니다
5. 정리 → 전체 롤아웃 후 플래그와 죽은 코드 경로를 제거
```
**규칙:**
- 모든 피처 플래그에는 소유자와 만료일이 있습니다
- 전체 롤아웃 후 2주 안에 플래그를 정리하세요
- 피처 플래그를 중첩하지 마세요 (조합이 지수적으로 늘어납니다)
- CI에서 플래그 두 상태(켜짐과 꺼짐)를 모두 테스트하세요
## 단계적 롤아웃
### 롤아웃 순서
```
1. 스테이징에 배포
└── 스테이징 환경에서 전체 테스트 스위트
└── 핵심 흐름의 수동 스모크 테스트
2. 프로덕션에 배포 (피처 플래그 OFF)
└── 배포 성공 확인 (헬스 체크)
└── 오류 모니터링 확인 (새 오류 없음)
3. 팀에 활성화 (내부 사용자에게 플래그 ON)
└── 팀이 프로덕션에서 기능을 사용
└── 24시간 모니터링 구간
4. 카나리 롤아웃 (사용자 5%에게 플래그 ON)
└── 오류율, 지연 시간, 사용자 행동을 모니터링
└── 지표 비교: 카나리 대 기준선
└── 24~48시간 모니터링 구간
└── 모든 기준을 통과할 때만 진행 (아래 표 참조)
5. 점진적 확대 (25% -> 50% -> 100%)
└── 각 단계에서 같은 모니터링
└── 어느 시점에서든 이전 비율로 롤백할 수 있음
6. 전체 롤아웃 (모든 사용자에게 플래그 ON)
└── 1주 모니터링
└── 피처 플래그 정리
```
### 롤아웃 판단 기준
각 단계에서 진행할지, 보류할지, 롤백할지 이 기준으로 결정하세요.
| 지표 | 진행 (녹색) | 보류하고 조사 (황색) | 롤백 (적색) |
|--------|-----------------|-------------------------------|-----------------|
| 오류율 | 기준선의 10% 이내 | 기준선보다 10~100% 높음 | 기준선의 2배 초과 |
| P95 지연 시간 | 기준선의 20% 이내 | 기준선보다 20~50% 높음 | 기준선보다 50% 초과 |
| 클라이언트 JS 오류 | 새로운 오류 유형 없음 | 세션의 0.1% 미만에서 새 오류 | 세션의 0.1% 초과에서 새 오류 |
| 비즈니스 지표 | 중립 또는 긍정 | 5% 미만 하락 (잡음일 수 있음) | 5% 초과 하락 |
### 언제 롤백하나
다음이면 즉시 롤백하세요.
- 오류율이 기준선의 2배를 넘습니다
- P95 지연 시간이 50%를 넘게 증가합니다
- 사용자 제보 이슈가 급증합니다
- 데이터 무결성 문제가 발견됩니다
- 보안 취약점이 발견됩니다
## 모니터링과 옵저버빌리티
### 무엇을 모니터링하나
```
애플리케이션 지표:
├── 오류율 (전체, 엔드포인트별)
├── 응답 시간 (p50, p95, p99)
├── 요청량
├── 활성 사용자
└── 핵심 비즈니스 지표 (전환, 참여)
인프라 지표:
├── CPU와 메모리 사용률
├── 데이터베이스 커넥션 풀 사용량
├── 디스크 공간
├── 네트워크 지연 시간
└── 큐 깊이 (해당될 때)
클라이언트 지표:
├── Core Web Vitals (LCP, INP, CLS)
├── JavaScript 오류
├── 클라이언트 관점의 API 오류율
└── 페이지 로드 시간
```
### 오류 보고
```typescript
// Set up error boundary with reporting
class ErrorBoundary extends React.Component {
state = { hasError: false };
static getDerivedStateFromError() {
return { hasError: true };
}
componentDidCatch(error: Error, info: React.ErrorInfo) {
// Report to error tracking service
reportError(error, {
componentStack: info.componentStack,
userId: getCurrentUser()?.id,
page: window.location.pathname,
});
}
render() {
if (this.state.hasError) {
return this.setState({ hasError: false })} />;
}
return this.props.children;
}
}
// Server-side error reporting
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
reportError(err, {
method: req.method,
url: req.url,
userId: req.user?.id,
});
// Don't expose internals to users
res.status(500).json({
error: { code: 'INTERNAL_ERROR', message: 'Something went wrong' },
});
});
```
### 출시 후 검증
출시 후 첫 한 시간:
```
1. 헬스 엔드포인트가 200을 반환하는지 확인
2. 오류 모니터링 대시보드 확인 (새 오류 유형 없음)
3. 지연 시간 대시보드 확인 (회귀 없음)
4. 핵심 사용자 흐름을 수동으로 테스트
5. 로그가 흐르고 읽을 수 있는지 확인
6. 롤백 수단이 동작하는지 확인 (가능하면 드라이런)
```
## 오류 예산 릴리스 게이트
서비스의 오류 예산, 즉 SLO가 실패를 허용하는 요청 또는 시간의 비율은 출시해도 안전한지를 결정합니다. 협상 대상이 아니라 객관적인 게이트로 쓰세요.
```
남은 오류 예산 > 20% → 평소대로 출시하고, 면밀히 모니터링하세요
남은 오류 예산 0~20% → 느린 롤아웃만 하세요. 고위험 변경은 하지 마세요
오류 예산 소진 → 기능 작업을 멈추고, 안정성에만 집중하세요
오류 예산 초기화 → 평소 속도로 재개하세요. 예산을 회복시킨 수정이 자리 잡았는지 확인하세요
```
카나리 중 소진 속도가 높으면 (기준 속도보다 빨리 예산을 소모하면) 위 롤아웃 기준 표의 **보류** 신호입니다. 높아진 오류율과 같이 다루세요.
## 롤백 전략
모든 배포에는 실행 전에 롤백 계획이 필요합니다.
```markdown
## [기능/릴리스] 롤백 계획
### 발동 조건
- 오류율 > 기준선의 2배
- P95 지연 시간 > [X]ms
- [특정 이슈]에 대한 사용자 제보
### 롤백 단계
1. 피처 플래그 비활성화 (해당될 때)
또는
1. 이전 버전 배포: `git revert && git push`
2. 롤백 검증: 헬스 체크, 오류 모니터링
3. 소통: 팀에 롤백을 알림
### 데이터베이스 고려사항
- 마이그레이션 [X]에 롤백이 있음: <검증된 명령 또는 런북 링크>
- 새 기능이 넣은 데이터: [보존 / 정리]
### 롤백에 걸리는 시간
- 피처 플래그: 1분 미만
- 이전 버전 재배포: 5분 미만
- 데이터베이스 롤백: 15분 미만
```
## 함께 보기
- 이 체크리스트 전에 모든 변경이 통과해야 하는 프로젝트 전체 완료 정의는 `../../references/definition-of-done.md`를 보세요
- 보안 출시 전 검사는 `../../references/security-checklist.md`를 보세요
- 성능 출시 전 체크리스트는 `../../references/performance-checklist.md`를 보세요
- 출시 전 접근성 검증은 `../../references/accessibility-checklist.md`를 보세요
- 알림 규칙과 SLO에 묶인 기준은 `observability-and-instrumentation`을 보세요
## 흔한 합리화
| 합리화 | 현실 |
|---|---|
| "스테이징에서 되니까 프로덕션에서도 될 것입니다" | 프로덕션은 데이터, 트래픽 패턴, 엣지 케이스가 다릅니다. 배포 후 모니터링하세요. |
| "이것에는 피처 플래그가 필요 없습니다" | 모든 기능은 킬 스위치가 있으면 이득입니다. "단순한" 변경도 무언가를 깨뜨릴 수 있습니다. |
| "모니터링은 오버헤드입니다" | 모니터링이 없으면 대시보드가 아니라 사용자 불만으로 문제를 알게 됩니다. |
| "모니터링은 나중에 넣겠습니다" | 출시 전에 넣으세요. 보이지 않는 것은 디버깅할 수 없습니다. |
| "롤백은 실패를 인정하는 일입니다" | 롤백은 책임 있는 엔지니어링입니다. 실패한 것은 깨진 기능을 출시하는 일입니다. |
| "오류율이 괜찮아 보이니 계속 출시합시다" | 현재 오류율만이 아니라 소진 속도를 보세요. 개별 기준이 녹색이어도, 기준선보다 빨리 예산을 소모하면 보류 신호입니다. |
## 레드 플래그
- 롤백 계획 없이 배포
- 프로덕션에 모니터링이나 오류 보고가 없음
- 빅뱅 릴리스 (한 번에 전부, 스테이징 없음)
- 만료나 소유자가 없는 피처 플래그
- 첫 한 시간 동안 배포를 지켜보는 사람이 없음
- 프로덕션 환경 설정을 코드가 아니라 기억으로 함
- "금요일 오후니까 그냥 출시하자"
- 오류 예산은 소진됐는데 기능 작업은 그대로 계속됨
## 검증
배포 전:
- [ ] 출시 전 체크리스트를 완료했습니다 (모든 절이 녹색)
- [ ] 피처 플래그를 구성했습니다 (해당될 때)
- [ ] 롤백 계획을 문서로 남겼습니다
- [ ] 모니터링 대시보드를 준비했습니다
- [ ] 팀에 배포를 알렸습니다
배포 후:
- [ ] 헬스 체크가 200을 반환합니다
- [ ] 오류율이 정상입니다
- [ ] 지연 시간이 정상입니다
- [ ] 핵심 사용자 흐름이 동작합니다
- [ ] 로그가 흐르고 있습니다
- [ ] 롤백을 테스트했거나, 준비되었음을 확인했습니다
출시한 모든 서비스:
- [ ] 오류 예산 정책이 있습니다. 예산이 20% 아래로 떨어질 때와 소진됐을 때 어떤 조치를 할지 압니다