Files
social-app/docs/runtime/runtime-runbook.md
T
qzl 1cc8fa1abf feat(auth): switch signup to OTP verification flow
Replace legacy signup with start/verify/resend endpoints, add OTP-focused mail templates and auth rate limits, and align compose/env/runbook for local self-hosted Supabase OTP behavior.
2026-02-25 13:34:02 +08:00

191 lines
6.9 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.
# Runtime Runbook
**Date:** 2026-02-24
**Status:** Active
## 启动方式
### 一键启动 (推荐)
```bash
# 前提:基础设施已手动启动(redis + supabase
# docker compose --env-file .env -f infra/docker/docker-compose.yml up -d
# 一键执行 bootstrap + 拉起 web/workertmux
bash infra/scripts/dev-app-up.sh
# 查看窗口
tmux list-windows -t social-dev
# 进入会话观察日志
tmux attach -t social-dev
```
或者手动执行:
```bash
# 1. 启动基础设施(当前编排不包含 web/worker)
docker compose --env-file .env -f infra/docker/docker-compose.yml up -d
# 2. 运行迁移和初始化
docker compose --env-file .env -f infra/docker/docker-compose.yml --profile job run --rm --build init-job
# 3. 一键执行应用层启动(bootstrap + web + workers
bash infra/scripts/dev-app-up.sh
```
### 生产环境迁移防遗漏(必读)
- 生产发布前必须先通过 bootstrap gate,再启动业务进程;禁止绕过 gate 直接起服务。
- 使用容器执行迁移时必须带 `--build`,确保最新 Alembic 迁移已进入镜像。
- 建议在迁移后做一次版本核对,确认已到预期 head。
```bash
# 1) 先执行 bootstrap gate
make runtime-bootstrap-gate
# 2) 如采用 init-job 单跑,必须带 --build
docker compose --env-file .env -f infra/docker/docker-compose.yml --profile job run --rm --build init-job
# 3) 核对 Alembic 版本
docker compose --env-file .env -f infra/docker/docker-compose.yml exec -T db \
psql -U postgres -d postgres -c "SELECT version_num FROM public.alembic_version;"
```
### 本地 CLI (开发调试)
> 适用于本地开发调试,不依赖 Docker。
> 开发调试阶段推荐直接使用本地一次性迁移脚本,不通过 Docker 触发数据库迁移,避免反复重建镜像。
```bash
# 推荐:一次性迁移(开发调试)
PYTHONPATH=backend/src uv run python -m core.runtime.cli migrate
# 需要初始化数据时再执行
PYTHONPATH=backend/src uv run python -m core.runtime.cli init-data
# 或一键执行(migrate + init-data
PYTHONPATH=backend/src uv run python -m core.runtime.cli bootstrap
# 启动 Web (gunicorn)
PYTHONPATH=backend/src uv run gunicorn app:app --bind 0.0.0.0:8000 --workers 2 --worker-class uvicorn.workers.UvicornWorker
# 启动 Worker (按队列分组)
PYTHONPATH=backend/src uv run celery -A core.celery.app worker --loglevel=info --queues=critical --concurrency=2
PYTHONPATH=backend/src uv run celery -A core.celery.app worker --loglevel=info --queues=default --concurrency=2
PYTHONPATH=backend/src uv run celery -A core.celery.app worker --loglevel=info --queues=bulk --concurrency=1
```
### tmux 会话管理
```bash
# 进入会话
tmux attach -t social-dev
# 杀掉会话(停止 web/workers
tmux kill-session -t social-dev
```
## 服务说明
| 服务 | 说明 | 备注 |
|------|------|------|
| redis | 缓存与 Celery broker | docker-compose 编排 |
| supabase-* | 认证与数据库相关服务 | docker-compose 编排 |
| init-job | 数据库迁移和初始化 | docker-compose 按需 run |
| web | Web 服务 (gunicorn) | 本地 CLI 启动 |
| worker-* | Celery worker | 本地 CLI 启动 |
## 配置说明
### Web 服务器配置
| 环境变量 | 说明 | 默认值 | 有效范围 |
|----------|------|--------|----------|
| `SOCIAL_WEB__HOST` | 监听地址 | 0.0.0.0 | - |
| `SOCIAL_WEB__PORT` | 监听端口 | 8000 | 1-65535 |
| `SOCIAL_WEB__RELOAD` | 开发模式热重载 | false | true/false |
| `SOCIAL_WEB__GUNICORN__WORKERS` | Gunicorn 工作进程数 | 2 | 1-64 |
| `SOCIAL_WEB__GUNICORN__WORKER_CLASS` | Gunicorn worker 类 | uvicorn.workers.UvicornWorker | Python import path |
| `SOCIAL_WEB__GUNICORN__TIMEOUT` | 请求超时秒数 | 60 | 1-600 |
| `SOCIAL_WEB__GUNICORN__KEEPALIVE` | Keep-alive 秒数 | 5 | 1-120 |
| `SOCIAL_WEB__LOG_LEVEL` | 日志级别 | info | debug/info/warning/error/critical |
### Celery 队列路由
| 任务前缀 | 队列 |
|----------|------|
| tasks.critical.* | critical |
| tasks.bulk.* | bulk |
| 其他 | default |
## 健康检查
```bash
# Supabase 网关
curl -fsS http://127.0.0.1:${SOCIAL_SUPABASE__KONG_HTTP_PORT:-8000}/health
# 数据库迁移与初始化
docker compose --env-file .env -f infra/docker/docker-compose.yml --profile job run --rm --build init-job
```
## 查看服务状态
```bash
docker compose --env-file .env -f infra/docker/docker-compose.yml ps
docker compose --env-file .env -f infra/docker/docker-compose.yml logs -f db
# init-job 为一次性任务(run --rm),如需查看日志请重跑:
docker compose --env-file .env -f infra/docker/docker-compose.yml --profile job run --rm --build init-job
```
## Auth/Profile 验证
```bash
# 注意:默认模板地址 http://mail-templates/* 仅在 Docker Compose 内网可用。
# 生产环境请替换为 gotrue 可访问的模板 URL。
# signup start: username + email + password(发送验证码)
curl -sS -X POST http://127.0.0.1:8000/api/v1/auth/signup/start \
-H 'Content-Type: application/json' \
-d '{"username":"demo","email":"demo@example.com","password":"secret123"}'
# signup verify: email + token6位验证码)
curl -sS -X POST http://127.0.0.1:8000/api/v1/auth/signup/verify \
-H 'Content-Type: application/json' \
-d '{"email":"demo@example.com","token":"123456"}'
# signup resend: email(重发验证码)
curl -sS -X POST http://127.0.0.1:8000/api/v1/auth/signup/resend \
-H 'Content-Type: application/json' \
-d '{"email":"demo@example.com"}'
# login: email + password
curl -sS -X POST http://127.0.0.1:8000/api/v1/auth/login \
-H 'Content-Type: application/json' \
-d '{"email":"demo@example.com","password":"secret123"}'
# by-email lookup
curl -sS "http://127.0.0.1:8000/api/v1/auth/users/by-email?email=demo@example.com"
# patch profile: username/avatar_url/bio only
curl -sS -X PATCH http://127.0.0.1:8000/api/v1/profile/me \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer <access_token>" \
-d '{"username":"demo2","bio":"hello"}'
```
---
## 变更日志
| 日期 | 变更 |
|------|------|
| 2026-02-24 | 创建运行时手册,删除 legacy 脚本,统一使用 gunicorn |
| 2026-02-24 | 清理配置:合并 AppSettings 到 WebSettings,删除 Worker 旧配置 (enabled_queues/queues),统一使用 SOCIAL_WEB__GUNICORN__* 命名 |
| 2026-02-24 | 开发阶段 compose 暂不编排 web/worker,仅保留 redis/supabase 与 init-job |
| 2026-02-24 | 新增 dev-app-up 脚本:手动基础设施后,一键 bootstrap + tmux 拉起 web/worker |
| 2026-02-25 | 补充迁移防遗漏规则:容器迁移命令统一追加 --build;开发调试优先使用本地 CLI 一次性迁移脚本 |
| 2026-02-25 | Auth 注册切换为 OTP 三段式:signup/start、signup/verify、signup/resend;邮件模板改为纯验证码展示 |
| 2026-02-25 | 清理未使用配置类:删除 WebSettings/GunicornSettings/WorkerSettings/WorkerGroupSettings(脚本仍使用环境变量启动服务) |