From 6bdb1f8ae6b998cf94f8910d5ccebe6fde67a76d Mon Sep 17 00:00:00 2001 From: WorkBuddy Date: Mon, 21 Sep 2026 21:02:16 +0800 Subject: [PATCH] =?UTF-8?q?docs(deploy):=20=E8=A1=A5=E5=85=85=E7=94=9F?= =?UTF-8?q?=E4=BA=A7=E4=B8=8A=E7=BA=BF=E6=A3=80=E6=9F=A5=E6=B8=85=E5=8D=95?= =?UTF-8?q?(README=20+=20docs/06)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - docs/06 新增「生产上线检查清单」10 项:APP_ENV / SECRET_KEY 强随机 / 管理鉴权二选一 / 数据库强密码 / HTTPS+Cookie Secure / TRUST_PROXY_HEADERS+X-Forwarded-For / Nginx limit_req 限流前置 (应用内限流与 KeyRing 单进程限制) / uvicorn 单 worker / /health 与 /health/ready / alembic 迁移已内置 - README 在部署说明后加同名精简清单,链接到 docs/06 详情 - 全部条目均对齐真实实现(security_check 弱值黑名单、auth.py secure=production、deps.py TRUST_PROXY 解析、app.py 双健康检查、 compose/Dockerfile 内置迁移);纯文档,未改业务逻辑 --- README.md | 15 +++++++++++++++ docs/06-deployment.md | 16 ++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/README.md b/README.md index 2327947..f325e6a 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,21 @@ cd frontend && npm install && npm run dev 后端运行在 `http://localhost:8000`,前端在 `http://localhost:5173`。 +## 生产上线检查清单 + +公网部署前逐项确认(第 1–4 项由启动校验强制,不满足拒绝启动;详见 [docs/06-deployment.md](docs/06-deployment.md#生产上线检查清单)): + +- [ ] `APP_ENV=production`(安全校验 / Cookie `Secure` / 管理端点 fail-closed 的总开关) +- [ ] `SECRET_KEY` 强随机:`openssl rand -base64 32`,禁止弱值 +- [ ] `ADMIN_PASSWORD` 或 `ADMIN_API_KEY` 至少配置其一 +- [ ] 数据库强密码,禁止 `football:football` 等示例弱密码 +- [ ] HTTPS(反代终结 TLS;production 下会话 Cookie 自动 `Secure`) +- [ ] 反代后设 `TRUST_PROXY_HEADERS=True`,仅可信反代可达 API,并配置 `X-Forwarded-For` / `X-Real-IP` +- [ ] 限流前置到 Nginx `limit_req`;应用内限流与 KeyRing 仅单进程有效,多 worker 会放大配额 +- [ ] uvicorn 单 worker(默认);需扩容先网关统一限流再起多实例 +- [ ] 启动后验证 `/health` 与 `/health/ready` 均 200 +- [ ] 数据库迁移已内置:compose/Dockerfile 启动即执行 `alembic upgrade head` + ## 安全与限流 - `/api/v1/predict`: 内存滑动窗口限流(10 次/分钟/IP),多 worker 时每进程独立计数 diff --git a/docs/06-deployment.md b/docs/06-deployment.md index a6966dc..a87c365 100644 --- a/docs/06-deployment.md +++ b/docs/06-deployment.md @@ -33,6 +33,22 @@ curl http://localhost:8000/health > **注意**: `api` 服务启动时会先执行 `alembic upgrade head` 迁移数据库,再启动 uvicorn。 > 容器内数据库连接自动使用 `postgres` 服务名(通过 compose `environment` 覆盖 `.env` 中的 `DB_HOST`)。 +## 生产上线检查清单 + +公网上线前逐项勾选。第 1–4 项由 `src/core/security_check.py` 在 `APP_ENV=production` +启动时**强制校验**,不满足直接拒绝启动(开发环境仅告警);管理鉴权另有请求期 fail-closed(503)。 + +- [ ] **1. `APP_ENV=production`** — 安全校验、Cookie `Secure`、管理端点 fail-closed 均以它为总开关 +- [ ] **2. `SECRET_KEY` 强随机** — 用 `openssl rand -base64 32` 生成;禁止弱值/短值(弱值黑名单会拒绝启动,含把生成指令原样粘进去的情况) +- [ ] **3. 管理鉴权至少其一** — `ADMIN_PASSWORD` 或 `ADMIN_API_KEY`(后台改过密码后以数据库哈希优先);两者皆空时管理接口 503 +- [ ] **4. 数据库强密码** — 禁止 `football:football` 等示例弱密码(启动校验会拒绝);compose 的 `POSTGRES_PASSWORD` 必填,缺失时容器拒绝启动 +- [ ] **5. HTTPS** — 由反代(Nginx/Caddy)终结 TLS;`APP_ENV=production` 下会话 Cookie 自动 `Secure`(且 HttpOnly + SameSite=Lax) +- [ ] **6. 反代信任头** — `TRUST_PROXY_HEADERS=True`,且**仅可信反代可达 API**;反代需设置 `X-Forwarded-For`(`$proxy_add_x_forwarded_for`)与 `X-Real-IP`,否则限流/日志按反代 IP 计数 +- [ ] **7. 限流前置到网关** — 推荐 Nginx `limit_req`(配置见[安全与限流](#安全与限流));应用内限流与 KeyRing 为**单进程内存实现**,多 worker 各自独立计数会把实际配额放大 N 倍(启动时会打印一次性告警) +- [ ] **8. uvicorn 单 worker** — compose/Dockerfile 默认单 worker,保持即可;需横向扩容时先在网关统一限流,再起多实例(每实例仍单 worker) +- [ ] **9. 启动后健康检查** — `curl /health` 返回 200(存活);`curl /health/ready` 返回 200(就绪,校验数据库连通,不可达时 503) +- [ ] **10. 数据库迁移** — compose/Dockerfile 启动命令已内置 `alembic upgrade head && uvicorn …`,升级镜像重启即自动迁移,无需手动执行 + ## 本地开发部署 ```bash