Files
joke-app/docs/11-deployment-ops.md
EJClaw f4d63e1544 docs: 온라인 보드게임 사이트 계획서 (공통 14편 + 게임 26종)
- 개요, 조사(BGA·한국 인기 보드게임·UI/UX), 아키텍처, 실시간 프로토콜,
  안정성·보안, 계정, 로비·방, UI/UX, 데이터 모델, 게임 엔진, 테스트,
  배포·운영, 로드맵(M0~M9), 사용자 결정 항목
- 게임별 규칙·엔진 설계·UI·테스트 체크리스트 26종

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 04:18:29 +09:00

56 lines
3.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 11. 배포와 운영
## 1. 구성
```
deploy/
├─ Dockerfile # 멀티 스테이지: bun install → web 빌드 → server 번들 → oven/bun:1-slim 실행 이미지
├─ docker-compose.yml # app + caddy, 볼륨: app-data(SQLite), caddy-data(인증서)
├─ Caddyfile # HTTPS 자동, /ws·/api → app:3000, 나머지 정적 파일
└─ .env.example # 필요한 환경 변수 목록(값 없음)
```
### 환경 변수
| 이름 | 설명 |
|---|---|
| `PUBLIC_ORIGIN` | `https://<도메인>` (Origin 검사, OAuth 리다이렉트, 공유 링크) |
| `DISCORD_CLIENT_ID` / `DISCORD_CLIENT_SECRET` | 디스코드 앱 |
| `SESSION_SECRET` | 짧은 수명 서명 쿠키(OAuth state)용 32바이트 |
| `DB_PATH` | 기본 `/data/app.db` |
| `PORT` | 기본 3000 |
| `LOG_LEVEL` | info |
### Caddy
- `encode zstd gzip`
- `/assets/*`: `Cache-Control: public, max-age=31536000, immutable` (파일명에 해시)
- `index.html`: `no-cache` (배포 즉시 반영)
- 보안 헤더: CSP(04 문서 7절), `X-Content-Type-Options: nosniff`, `Referrer-Policy: strict-origin-when-cross-origin`, HSTS.
- WebSocket 프록시는 Caddy 기본 지원. 연결 유지 시간 제한 없음.
## 2. 배포 절차
1. `main`에 커밋·푸시(Gitea `tkrmagid/joke-app`).
2. 서버에서 `git pull && docker compose -f deploy/docker-compose.yml up -d --build`.
3. 옛 컨테이너가 SIGTERM을 받으면 `bye: restart` 전송 후 종료(`stop_grace_period: 15s`), 새 컨테이너가 방 복구 후 시작.
4. 확인: `/healthz`(DB 열림, 방 복구 완료) 200, 로그에 오류 없음, 테스트 방 하나 만들어 오목 한 수.
5. 문제가 있으면 이전 이미지 태그로 되돌림(`docker compose` 이미지에 커밋 해시 태그).
## 3. 개발·테스트 환경
- 로컬: `bun install && bun run dev` → 웹 Vite(5173) + 서버(3000), Vite가 `/api`·`/ws`를 서버로 프록시.
- 디스코드 로그인 없이도 게스트로 모든 기능 테스트 가능(디스코드 값이 없으면 버튼 숨김).
- 공용 테스트 서버(사용자가 직접 접속해 보는 곳)는 배포 위치가 정해지면 같은 compose로 띄운다.
## 4. 백업과 복구
- 매일 04:00 `VACUUM INTO '/data/backup/app-YYYYMMDD.db'`, 14개 보관.
- 복구: 컨테이너 중지 → 백업 파일을 `app.db`로 복사 → 시작. 진행 중이던 방은 백업 시점 상태로 돌아간다.
## 5. 감시
- `/healthz` 1분마다 확인(외부 업타임 감시 또는 호스트 cron), 실패 3번이면 알림(디스코드 웹훅, 선택).
- 지표 `/internal/metrics`는 Caddy에서 외부 차단.
- 로그: Docker json-file, 크기 제한 50MB × 5.
## 6. 정해야 할 것 (사용자 결정 필요)
| 항목 | 선택지 | 기본 제안 |
|---|---|---|
| 서버 위치 | 이 호스트 / .5 Docker 호스트 / 외부 VPS | 개발 중에는 이 호스트에서 테스트, 공개용은 사용자 결정 |
| 도메인 | 예: `game.tkrmagid.kr` | 사용자 결정(DNS 설정 필요) |
| 디스코드 앱 | 개발자 포털에서 생성 → client ID/secret, Redirect URI 등록 | 도메인 정해진 뒤 |