You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
80 lines
3.9 KiB
Markdown
80 lines
3.9 KiB
Markdown
# 아리(Ari) 운영 런북 (phase-15)
|
|
|
|
> 제3자가 이 문서만으로 기동·마이그레이션·롤백·모니터링·장애 대응을 수행할 수 있도록 작성.
|
|
|
|
## 0. 구성
|
|
|
|
- **frontend** (Next.js standalone, :3000) · **backend** (gunicorn+uvicorn, :8000) · **worker**(스케줄러 전용, `WORKER_ENABLED=true` 1개만) · **ollama**(로컬 LLM) · **db**(SQLite 볼륨 또는 Postgres) · **caddy**(리버스 프록시 + 자동 HTTPS).
|
|
- 인증: `AUTH_ENABLED=true`(운영) / `false`(데모·CI). per-user 스코프는 `user_id` 컬럼 + `auth/scope.scoped()`.
|
|
|
|
## 1. 기동 / 재기동
|
|
|
|
```bash
|
|
cd deploy
|
|
cp .env.prod.example .env.prod # 값 채우기(아래 2. 비밀)
|
|
docker compose up -d --build # dev(SQLite)
|
|
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d --build # prod(Postgres)
|
|
docker compose restart backend worker # 코드/설정 변경 후
|
|
```
|
|
|
|
## 2. 비밀(필수)
|
|
|
|
```bash
|
|
docker compose run --rm backend python -m scripts.gen_secret # SESSION_SECRET / ARI_SECRET_KEY 출력
|
|
# → .env.prod 에 기입. 기본 'insecure' 값이 남아 있으면 ARI_ENV=prod 기동을 거부하도록 운영.
|
|
```
|
|
|
|
- `password_hash`(pbkdf2)·`token_hash`(sha256)·커넥터 `token_enc`(Fernet) — 평문 저장 0건.
|
|
|
|
## 3. 마이그레이션 / 시드
|
|
|
|
```bash
|
|
docker compose run --rm backend alembic upgrade head # 스키마 최신화
|
|
docker compose run --rm backend alembic downgrade -1 # 롤백 1단계
|
|
# 데모→실 전환: AUTH_ENABLED=true 설정 후 upgrade(=user_id 'jiwoo' 백필) + 시드로 자격 생성
|
|
docker compose run --rm backend python -m app.seed # 데모 리셋(reset=True)
|
|
docker compose run --rm backend python -m app.seed --no-reset # 멱등(운영 데이터 보존)
|
|
```
|
|
|
|
## 4. 백업 / 복구
|
|
|
|
```bash
|
|
docker compose exec backend scripts/backup.sh # → /backups/ari-<ts>.db.gz (SQLite .backup, 락 안전)
|
|
docker compose exec backend scripts/restore.sh /backups/ari-<ts>.db.gz
|
|
docker compose restart backend worker
|
|
# SQLite→Postgres 이관:
|
|
docker compose run --rm -e PG_URL=postgresql+psycopg://ari:pw@db/ari backend \
|
|
python -m scripts.migrate-sqlite-to-postgres # 행 수 일치 검증
|
|
```
|
|
|
|
## 5. 모니터링
|
|
|
|
- **liveness**: `GET /api/health` → `{"status":"ok"}`
|
|
- **readiness**: `GET /api/ready` → `{ready, checks:{db,migrations,llm,worker}}` (LLM 미가용=`fallback:heuristic`, 차단 아님)
|
|
- **메트릭**: `GET /api/metrics`(내부망만 — Caddy 가 외부 404). 핵심: `ari_http_latency_seconds`, `ari_llm_calls_total`, `ari_worker_jobs_total`, `ari_approvals_total`, `ari_saved_minutes_total`.
|
|
- **로그**: `docker compose logs -f backend | jq` (JSON 한 줄/요청 — request_id·user_id·path·status·dur_ms).
|
|
|
|
## 6. 능동 레이어(worker)
|
|
|
|
```bash
|
|
# 수동 트리거(WORKER_ENABLED=false 시):
|
|
docker compose exec backend curl -X POST localhost:8000/api/worker/run/digest
|
|
docker compose exec backend curl -X POST localhost:8000/api/worker/run/proactive
|
|
# 스케줄(digest 09:00/13:00/18:30, proactive 30m, weekly 일요일 20:00) — worker 컨테이너만 1개 true.
|
|
```
|
|
|
|
## 7. 장애 대응
|
|
|
|
- **LLM 느림/다운**: 자동 `heuristic` 폴백(서비스 중단 아님). `docker compose restart ollama`.
|
|
- **DB 락(SQLite)**: WAL + busy_timeout. 지속 시 Postgres 승격(§4 이관).
|
|
- **커넥터 토큰 만료**: 라이프 "연결 안 됨"(`token_expired`) → 재인증 유도. mock 폴백으로 페이지 동작.
|
|
- **인증 사고**: 전 세션 폐기 = `auth_session.revoked=true` 일괄 UPDATE; `SESSION_SECRET` 로테이션 후 재기동(기존 쿠키 무효).
|
|
- **프롬프트 인젝션 의심**: `audit_log` `prompt_injection.suspected` 확인. 외부 행동(전송/결제)은 결재함 high-risk 게이트로만 — 자동 실행 0.
|
|
|
|
## 8. 롤백
|
|
|
|
```bash
|
|
git revert <sha> && docker compose up -d --build
|
|
# 스키마 롤백 필요 시: alembic downgrade -1 + 백업 복구(§4).
|
|
```
|