# Operations Guide 작성: AI / 수정: nkey ## Supported Deployment Modes - Dockerfile 기반 단일 컨테이너 실행 (`dockerfile`) - (참고) 로컬에서 Uvicorn 직접 실행 > Docker Compose / Kubernetes / Terraform 관련 파일은 레포에 없습니다. ## Production Checklist - Secrets/ENV: - `DATABASE_URL`는 필수입니다. - Admin API를 운영에서 사용할 경우 `ADMIN_PASSWORD`를 반드시 설정하고, 클라이언트에서 `X-Admin-Password` 헤더로 전달해야 합니다. - Networking: - 인바운드: TCP 8000 (API) - 아웃바운드: solved.ac API, acmicpc.net(백준) 접근 필요(문제/문제집 정보 조회). - Storage: - 앱 자체는 로컬 파일 저장을 전제로 하지 않습니다. - DB는 외부 PostgreSQL을 사용합니다. (주의) 레포에 DDL/마이그레이션이 포함되어 있지 않으므로, 운영 DB 스키마는 별도로 준비되어 있어야 합니다. - Observability: - 기본 Uvicorn 로그(stdout) 기반. 별도 로깅/메트릭 구성은 레포에 없습니다. - Scaling: - `/today`의 search 모드는 DB 없이도 동작 가능(단, 코드상 DB 의존성 주입은 존재). - workbook 모드는 DB 상태(workbook_sends)에 의해 결과가 달라지므로, 다중 인스턴스 운영 시 동일 DB를 바라보도록 구성해야 합니다. ## Deployment ### Docker ```bash # build (주의: 파일명이 'Dockerfile'이 아니라 'dockerfile' 입니다) docker build -f dockerfile -t baekjoon-bot:prod . # run cat > .env <<'EOF' DATABASE_URL=postgresql+asyncpg://USER:PASSWORD@HOST:5432/DBNAME ADMIN_PASSWORD=change-me EOF docker run -d --name baekjoon-bot \ --env-file .env \ -p 8000:8000 \ baekjoon-bot:prod # verify curl -s http://localhost:8000/ | cat ``` ## Operations ### Healthcheck - `GET /` - 성공 조건: `{"status":"ok"}` 응답 ### Logs - Docker 실행 시: ```bash docker logs -f baekjoon-bot ``` ## Security Notes (only with evidence) - Admin API는 `X-Admin-Password` 헤더 기반 단일 비밀번호 체크입니다. - `ADMIN_PASSWORD`가 비어 있으면 admin API 호출 시 500으로 실패합니다(설정 누락). - `.env`는 `.gitignore`에 포함되어 있어 커밋되지 않도록 되어 있습니다. ## Incident Runbook (Top 5) 1) **env 누락** - Symptom: 앱 시작 시 `DATABASE_URL is required...`로 즉시 종료 - Cause: `DATABASE_URL` 미설정 - Fix: `.env` 또는 런타임 환경변수에 `DATABASE_URL` 설정 - Verify: 컨테이너/프로세스 정상 기동 후 `GET /`가 200 2) **포트 충돌** - Symptom: 컨테이너 실행 시 `bind: address already in use` 또는 접근 불가 - Cause: 호스트 8000 포트 사용 중 - Fix: `-p 18000:8000` 같이 호스트 포트 변경 - Verify: `curl http://localhost:18000/` 3) **DB 연결 실패** - Symptom: `/today` 또는 admin 호출 시 500, 로그에 DB 커넥션 에러 - Cause: `DATABASE_URL` 잘못됨 / 네트워크/방화벽 / DB 다운 - Fix: URL 재확인, DB 접근 허용, DB 상태 확인 - Verify: `/today?source_mode=workbook&workbook_id=...`가 정상 응답(워크북 모드 사용 시) 4) **Admin 인증 실패** - Symptom: admin API가 403 `invalid admin password` - Cause: `X-Admin-Password` 누락 또는 불일치 - Fix: `ADMIN_PASSWORD` 값과 동일한 헤더 전달 - Verify: `POST /admin/workbooks/{id}/enrich`가 200 5) **문제집 소진** - Symptom: `GET /today?source_mode=workbook&workbook_id=...`가 409 + `no_more_problems_in_workbook` - Cause: 해당 workbook에서 아직 보내지 않은 문제 후보가 없음(`workbook_sends`에 모두 기록됨) - Fix: 진행상황 초기화 API 호출(주의: 관리자 권한 필요) 또는 다른 workbook 사용 - Verify: 초기화 후 workbook 모드 호출 시 정상 추천 반환