Browse Source

docs: 记录后端上线(单进程同源托管 + 隔离 conda)— CHANGELOG + docs/02 §10 部署架构

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
tianyu.chu 1 month ago
parent
commit
0387bf9500
2 changed files with 19 additions and 0 deletions
  1. 8 0
      CHANGELOG.md
  2. 11 0
      docs/02-技术架构.md

+ 8 - 0
CHANGELOG.md

@@ -4,6 +4,14 @@
 
 ## 2026-06-26
 
+### 新增
+- **后端上线:服务器单进程同源托管(真实数据)**(`infra/` + 服务器):线上 `http://100.64.0.62:8080/` 从 mock 切到**真实 PG 数据**。
+  - 服务器装**隔离 Miniconda Python 3.11**(`~/miniconda3`,py311_24.7.1,兼容 CentOS7 glibc 2.17;新版 Miniconda 要 glibc≥2.28 故选旧版),pip 仅装运行时依赖(`--only-binary` 走 manylinux2014 轮子,无需编译器);**不动系统 3.6/3.7 环境**。
+  - 后端源码独立 clone 到 `~/hs-api`(feature 分支);`apps/api/.env` 直连 PG(服务器内网可达 100.64.0.10:25432)。
+  - `app/main.py` 加 **`STATIC_DIR` 条件静态托管**:uvicorn **单进程**同源托管 SPA(`~/hs-data`,实时读盘)+ `/api`,端口 8080,取代原 `serve.py`——同源免 CORS、前端相对 `/api` 不变、只剩一个常驻进程。本地/测试未设 `STATIC_DIR` 故不挂载,零影响。
+  - `~/serve-hs-api.sh` 启动器(`nohup setsid`,脱离 SSH 会话存活,幂等);`infra/look.sh` 构建改 `VITE_USE_MOCK=false`、拉产物后确保后端在跑。
+  - 端到端实测(公网 8080):SPA + 深链回退 200,`/api` 三周期均 `ready`(day=最新可用日 20260621,11859→5366)。
+
 ### 变更
 - **后端接通真实 PG**(`apps/api`):由假数据切到真实拼团漏斗预聚合两表(`ads.ads_trd_group_funnel_daily` / `_rolling`)。
   - `config.py` 加 `db_schema`(默认 `ads`);`session.py` 给真实连接挂 `search_path=ads`(asyncpg `server_settings`)——ORM 表名保持无 schema,SQLite 测试不受影响,模型零改动。

+ 11 - 0
docs/02-技术架构.md

@@ -178,3 +178,14 @@ MVP 不引入:
   - 其余 L1/L2 路由渲染统一的"待开发"占位组件。
 - 占位机制:非可用模块复用同一占位组件(`src/modules/placeholder/`),文案统一"待开发",可正常进入、不报错、不空白。
 - L2 子菜单(域内多模块)与 L3 报表列表后续按路线图补;当前 MVP 导航可先平铺 7 个 L1 + 漏斗页,不强求展开全部 L2。
+
+## 10. 部署架构
+
+线上服务器 `100.64.0.62`(CentOS 7,glibc 2.17),内网访问 `http://100.64.0.62:8080/`。
+
+- **单进程同源托管**:服务器跑 **uvicorn**(`app.main:app`),用 `STATIC_DIR` 环境变量同源托管前端 SPA(`~/hs-data`,实时读盘)+ `/api`,端口 8080。前端相对 `/api` 调用走同源,免 CORS、免反向代理,只有一个常驻进程。本地开发/测试不设 `STATIC_DIR`,uvicorn 仅出 `/api`,前端由 Vite dev 提供。
+- **隔离运行时**:服务器装用户态 Miniconda Python 3.11(`~/miniconda3`,旧版 py311_24.7.1 以兼容 glibc 2.17),依赖走 manylinux 轮子(`pip --only-binary`,无需编译器);不动系统 Python(3.6/3.7,其他项目依赖)。
+- **取数**:`apps/api/.env`(gitignored)配 `DATABASE_URL`(直连内网 PG `100.64.0.10:25432`)+ `DB_SCHEMA=ads` + `USE_FAKE_DATA=false`;`session.py` 给连接挂 `search_path=ads`。
+- **两份 clone**:`~/hs-data`(deploy 分支,纯前端产物)+ `~/hs-api`(feature 分支,后端源码)。
+- **发布链路**(`infra/look.sh`,纯 git):本地 `test + build(VITE_USE_MOCK=false)` → 推 `feature`(源码)+ `deploy`(产物)→ 服务器 `git pull` 更新 `~/hs-data`(uvicorn 实时读盘,前端改动**无需重启**)+ `~/serve-hs-api.sh`(`nohup setsid`,幂等)确保后端在跑。
+- **后端代码更新**(非前端):需在服务器 `cd ~/hs-api && git pull` 后**重启 uvicorn**(`pkill -f "uvicorn app.main:app"; ~/serve-hs-api.sh`)——`look.sh` 不自动重启健康的后端以免抖动。