Docs 사이트 배포 (docs.dartbrief.com)
docs/ 전체를 VitePress 단일 사이트로 빌드해 Cloudflare Pages + CF Access(내부 전용)로 배포한다.
- prose docs (
spec/·policies/·api/·dev/·platform/·operations/) → VitePress 가 자동 사이드바·검색·다크모드로 렌더 - design 카탈로그 (
design/) → 기존 Vite 빌드 산출물을 verbatim 으로/design/에 호스팅 (마이그레이션 없음, 1픽셀도 안 바뀜)
⚠️ frontend 의
cloudflare-deploy.md와 다른 타겟이다. frontend 는 SSR/ISR 때문에 Workers + OpenNext 가 필수였지만, docs 사이트는 순수 정적이라 Pages 가 정답. frontend 의 wrangler.toml / worker.js 구조를 복붙하지 말 것.
구조
docs/
├── .vitepress/config.mts # VitePress 설정 (nav / 자동 사이드바 / 링크 재작성)
├── index.md # 사이트 home (hero)
├── package.json # vitepress + vitepress-sidebar
├── public/design/ # ← design/dist 복사본 (gitignore, 빌드 때 생성)
├── spec/ policies/ api/ … # prose 마크다운 (VitePress 페이지)
└── design/ # 기존 Vite 카탈로그 (자체 package.json, 그대로 둠)빌드 / 로컬
cd docs
npm install # 최초 1회 (VitePress)
npm run docs:dev # build:design → public/design 복사 → vitepress dev (5173)
npm run docs:build # 산출물: .vitepress/dist
npm run docs:preview # 빌드 결과 프리뷰build:design 스크립트가 design/ 의 의존성을 npm ci 로 따로 설치 → npm run build → dist/ 를 public/design/ 로 복사한다. (CF Pages 는 root dir 한 곳만 자동 install 하므로 design deps 는 스크립트가 직접 설치.)
Tailscale 원격 프리뷰: npm run docs:dev -- --host → 100.x.x.x:5173.
CF Pages 대시보드 셋업
Workers & Pages → Create → Pages → Connect to Git:
| 필드 | 값 |
|---|---|
| Project name | dartbrief-docs |
| Repository | junhyeon47/dartbrief |
| Production branch | main |
| Root directory | docs ⚠️ (monorepo, 누락 시 빌드 실패) |
| Build command | npm run docs:build |
| Build output directory | .vitepress/dist |
| Env var | NODE_VERSION = 20 |
시크릿·런타임 변수 없음 (백엔드 호출 0, spec md 는 빌드 시점 inline).
커스텀 도메인
Pages → Custom domains → docs.dartbrief.com. dartbrief.com 이 CF DNS 면 CNAME 자동 생성.
CF Access 로 잠그기 (내부 전용)
내부 SSOT 라 외부에 풀 이유가 없다. Zero Trust 이메일 게이트로 막는다.
Zero Trust → Access → Applications → Add → Self-hosted:
| 필드 | 값 |
|---|---|
| Application name | dartbrief-docs |
| Application domain | docs.dartbrief.com (path 전체) |
| Session duration | 1 week |
| Policy | Allow · Emails = [email protected] (+ 협업자) |
| Identity | One-time PIN (이메일 코드) 또는 Google |
⚠️ 도메인 붙이기 전에 Access policy 부터 — 그 사이에 spec/내부 화면이 공개 인덱싱될 수 있음.
링크 재작성 (config.mts)
마크다운 source 는 GitHub/로컬 상대경로로 그대로 두고, 렌더 시점에만 치환:
| md 원본 | 사이트 | 이유 |
|---|---|---|
../../mobile|backend|frontend|scripts/... | GitHub blob 외부 링크 | 레포 코드/스크립트는 사이트에 없음 |
CLAUDE.md (깊이 무관) | GitHub blob | 레포 루트 파일 |
../design/X.html | /design/X.html | design 은 /design 에 verbatim. spec 의 "시각 미리보기" 링크 포함 — 절대 URL 대신 상대경로로 둬야 로컬/프리뷰/prod 모두 동일 동작 |
domain-quota.md 등 문서 간 | VitePress 자동 변환 | — |
비용
CF Pages 무료(빌드 500회/월, 대역폭 무제한) + CF Access 무료 50 seats → 전부 무료.
흔한 함정
- prose 안 bare
<Tag>→ 빌드 실패: VitePress 가 마크다운을 Vue SFC 로 컴파일해서 코드펜스 밖의<String>같은 ASCII-시작 꺾쇠를 미닫힌 태그로 본다. 백틱(`Set<String>`)으로 감싸거나<로 이스케이프. (한글<조건>·autolink<https://>·코드펜스 안은 안전.) - Workers 로 셋업 → 정적이라 불필요. Pages + output
.vitepress/dist. - Root directory 누락 → monorepo 라
docs필수. build:design누락된 빌드 명령 →/design이 통째 404. 반드시npm run docs:build(design 빌드+복사 포함).- design deps 미설치 → CF 는 root(
docs)만 install.build:design의npm ci가 design deps 를 직접 깔아야 함 (이미 스크립트에 포함).