운영 배포 결과와 기동 확인 절차 보완

This commit is contained in:
Yun Chan 2026-09-09 15:00:00 +09:00
parent 1306c524c1
commit 6831a79ffb
8 changed files with 41 additions and 23 deletions

View file

@ -64,7 +64,7 @@ npx playwright test e2e/uc-session-conversation.spec.ts --grep '스트림 도중
| MIGRATION-001 | idempotent DB migration runner | init SQL과 runner의 역할 경계·인프라 영향·소유자 승인 |
| OPS-001 | 운영 티켓 자동 분류 | 관리자 승인·audit 경계를 갖춘 구현 패킷 |
| E2E-001 | 전 기능 E2E 후속 분류 | focused 범위의 locator 18건 교정·keyboard 1건 해결 뒤 `npm run e2e`에서 범위 밖 케이스를 실행하고, 실패별 재현·원인·수정 명령을 분류한다. 과거 sweep 실패를 오늘 결함으로 단정하지 않으며 실API/DB·장치 검증은 fixture 결과와 분리한다. |
| CUA-128 | 실제 배포 Computer Use 재검증 | 128 시나리오 카탈로그 생성은 완료했지만 전체 실배포 검증은 미완료다. 일반 학습자 로그인·교차 역할 차단·P4 추천과 허용된 관리자 P16 1개·학습자 P4 1개 회기 종료를 확인했으나 H09·T18은 local 수정 증거 뒤 배포 재검증이 열려 있다. 순수 teacher·OFF 계정, 교수자 쓰기, 모바일과 독립 관찰자 공개 검증이 남아 있다. |
| CUA-128 | 실제 배포 Computer Use 재검증 | 128 시나리오 카탈로그 생성은 완료했지만 전체 실배포 검증은 미완료다. SHA `1306c524`에서 H09와 일반 학습자 로그인·교차 역할 차단·P4 추천·R09 잠금·R14 워크시트 보존을 재확인했지만, T18은 learner 브라우저만 있어 기존 RED를 종결하지 않았다. 순수 teacher·OFF 계정, 교수자 쓰기, 모바일과 독립 관찰자 공개 검증이 남아 있다. |
## 완료 기록 경계

View file

@ -1,7 +1,7 @@
# 배포 파이프라인 (Deployment Pipeline)
> 작성: 2026-08-31 · 2026-09-08 현행화 · 문서 소유: docs/ops
> 상태: **2026-09-08 NAS Production & Cloudflare Pages 실배포 완료 (SHA `a0311c59`)**.
> 작성: 2026-08-31 · 2026-09-09 현행화 · 문서 소유: docs/ops
> 상태: **2026-09-09 NAS Production & Cloudflare Pages 실배포 완료 (SHA `1306c524`)**. API·engine 동시 기동 중 공백 관찰이 있어 무중단 배포 증거는 아니다.
## 목표 아키텍처 (소유자 지시)
@ -44,7 +44,7 @@ Cloudflare tunnel은 소유자 지시에 따라 제거 대상이다. 다만 현
[NAS] git 컨테이너로 해당 SHA clone·검증
[NAS] API/Web build → online migration → docker compose 재생성
[NAS] 변경 범위·필요 migration 호환성 검토 → 이미지 빌드 → 필요한 서비스별 교체·readiness
vignette-prod (api/web/engine/db/proxy) readiness·데이터 보존 검증
@ -59,7 +59,8 @@ NAS 호스트에는 git이 없으므로 git 컨테이너로 Forgejo에서 clone
- `apps/api`: 관련 test suite (전체 1104 passed / 1 skipped)
- SSOT checker `scripts/check-dev-dashboard-ssot.py`
- Forgejo master == 로컬 master (배포 무결성)
- NAS: `docker compose ps` healthy, `/api/health` ok·db/engine true
- NAS: 후보 변경 파일 범위로 engine 영향부터 판정한다. engine 코드·공통 requirements·`apps/api/Dockerfile`가 바뀌지 않았다면 API와 같은 이미지 참조를 쓰더라도 engine을 재생성하지 않는다.
- NAS: `docker compose ps` healthy, 공개 `/health``db: true`·`engine: true`, 실제 인증 UI 확인 전에는 완료를 선언하지 않는다. 컨테이너 `Started`는 완료 증거가 아니다.
## 5. 실증된 배포 절차 (2026-09-01 1차 실배포 완료, SHA `dce85620`)
@ -77,12 +78,20 @@ docker run --rm -v $PWD:/work alpine/git clone --depth 1 --branch master \
# 2) 이미지 빌드 (API 컨텍스트는 저장소 루트)
cd src-<sha> && docker build -f apps/api/Dockerfile -t vignette-nas-api:<sha> .
docker build --build-arg VITE_API_BASE=/api -t vignette-nas-web:<sha> apps/web
# 3) 새 마이그레이션은 psql로 온라인 적용(initdb 스크립트는 재실행되지 않음),
# 구 API가 의존하는 제약을 바꾸는 마이그레이션은 stop api 후 적용
# 4) private/env.nas의 VIGNETTE_NAS_API_IMAGE/WEB_IMAGE를 새 이미지 ID로 교체
# 3) migration이 필요하면 호환성을 먼저 검토하고 적절한 시점의 별도 게이트에서 적용한다.
# initdb 스크립트는 재실행되지 않으며, 구 API가 의존하는 제약 변경은 stop api 뒤 적용할 수 있다.
# 4) 후보 변경 범위로 교체 대상을 판정한다.
# engine 코드·requirements·apps/api/Dockerfile 변경이 없으면 engine은 유지한다.
# API만 바뀌면 API만, web만 바뀌면 web만 --no-deps로 재생성한다.
# engine 변경이면 engine을 먼저 교체하고 healthy 및 engine readiness를 확인한 뒤 API를 교체한다.
# compose의 --wait 지원 여부는 현장에서 확인되지 않았으므로 쉘 폴링으로 health를 확인한다.
# 단일 API 교체에는 기동 공백이 있다. 무중단은 별도 blue/green 전환 게이트를 통과한 경우에만 주장한다.
# 5) private/env.nas의 VIGNETTE_NAS_API_IMAGE/WEB_IMAGE를 새 이미지 ID로 교체
docker compose -f docker-compose.nas.yml --env-file private/env.nas config --quiet
docker compose -f docker-compose.nas.yml --env-file private/env.nas up -d
# 5) readiness: public health ok·db/engine true, OpenAPI 200, /auth/me 401, 데이터 집계 전후 동일
docker compose -f docker-compose.nas.yml --env-file private/env.nas up -d --no-deps api web
# engine 변경 시에는 위 API/Web 명령 전에 별도로 `up -d --no-deps engine`을 실행한다.
# 6) API 교체 뒤 healthy, 공개 /health의 db/engine true, 실제 인증 UI, 데이터 집계 전후 동일을 확인한다.
# rollback은 자동 실행하지 않는다. 사전 DB dump와 이전 이미지·환경 파일을 보존하고 소유자가 결정한다.
```
공개 웹(Cloudflare Pages)은 별도 배포한다: `apps/web`에서 `npm run build`
@ -109,6 +118,12 @@ docker compose -f docker-compose.nas.yml --env-file private/env.nas up -d
- `https://api-vignette.chanpaca.net/auth/me` -> `401 Unauthorized` (fail-closed 보장)
- `https://vignette.chanpaca.net` -> `HTTP 200 OK`
## 5.2 서비스별 교체·기동 공백 관찰 (2026-09-09, SHA `1306c524`)
- API와 engine을 동시에 재생성한 동안 사용자가 다운을 보고했다. 이는 단일 API 교체에도 기동 공백이 생길 수 있음을 드러낸 관찰이며, 영구 장애 원인으로 단정하지 않는다.
- 이후 같은 버전에서 컨테이너 healthy, 공개 `200`, 학습자 회기 조회 정상과 DB 전체 집계 동일을 확인했다. 이 회복 관찰은 무중단 배포 증거가 아니다.
- 다음 배포는 §5의 변경 범위 판정을 먼저 적용한다. engine 변경이 있으면 engine healthy·readiness 뒤 API를 교체하고, engine 변경이 없으면 API와 같은 이미지 참조만으로 engine을 재생성하지 않는다.
## 6. 남은 구성 작업 (TODO)
- [ ] Forgejo master 기준 NAS 자동배포 후크(수동 절차는 §5, §5.1로 실증 완료)