This commit is contained in:
2026-08-31 18:01:34 +08:00
parent 3ea59551db
commit bee439cf34
46 changed files with 1884 additions and 1898 deletions
+315
View File
@@ -0,0 +1,315 @@
# 前端独立部署 + 统一后端入口实施计划
> 目标:在已经切换到“前端独立部署 + 同域反代”的基础上,进一步取消前端 Nginx 对 `/api` 的路径级分流,改为反代到一个真正的 **unified backend**,一次性解决长期维护成本。
---
## 1. 背景
当前项目已经完成了两项关键演进:
1. 前端从历史 `static/` 托管模式中抽离,开始走独立构建与独立部署
2. 前端通过同域 Nginx 反代访问后端 API 与分析产物
但当前 Nginx 仍然承担了“后端路由所有权判断”的职责:
- 一部分 `/api/...` 被转发到 `moldinsight`
- 另一部分 `/api/...` 被转发到 `inventory`
这虽然能跑通当前功能,但长期存在明显问题:
- 每新增一个 gemold API,Nginx 都要同步改配置
- Nginx 配置承担了业务边界知识,维护成本高
- `/health` 只能代表某一套后端,而不是统一入口
- 与“unified / gemold-only / inventory-only”三种部署模式的目标不完全一致
因此,本轮改造的目标是:
> 把前端入口反代逻辑从“按路径分流到两套后端”升级为“统一反代到一个 unified backend”。
---
## 2. 目标状态
### 浏览器视角
浏览器始终只访问一个同域入口:
- `/` → 前端静态页面
- `/api/*` → unified backend
- `/health` → unified backend
- `/html/*` → unified backend(由 unified backend 再提供 gemold 产物访问)
### Nginx 视角
Nginx 不再负责理解 gemold / inventory 的业务边界。
它只做两件事:
1. 提供前端静态文件与 SPA fallback
2. 把 `/api`、`/health`、`/html` 统一转发给一个 backend upstream
### 后端视角
后端新增一个统一入口,负责组合:
- auth
- moldinsight routes
- inventory routes
- `/health`
- `/html`
同时继续保留:
- `moldinsight-only`
- `inventory-only`
以满足模块独立部署场景。
---
## 3. 设计决策
### 3.1 为什么要引入 unified backend
因为前端与网关层最适合面对的是一个统一后端,而不是两套需要网关手工分流的内部模块。
收益:
- Nginx 配置显著简化
- 新增 API 不需要修改网关规则
- 文档和运维认知更简单
- 前端保持统一 `/api` 契约
- 更符合模块化蓝图中对 `unified` 模式的定义
### 3.2 为什么不直接把 split 模式删掉
因为:
- `gemold-only` 和 `inventory-only` 仍然有独立部署价值
- 当前仓库已经形成了清晰模块边界
- 统一入口应该成为**前端同域反代的默认方案**,而不是抹掉模块部署模式
所以最终保留三类入口:
- `src/entrypoints/unified.py`
- `src/entrypoints/moldinsight.py`
- `src/entrypoints/inventory.py`
---
## 4. 需要改动的核心文件
## 4.1 新增 unified 入口
新增:
- `src/entrypoints/unified.py`
职责:
- 基于 `shared.app_factory.create_app()` 创建应用
- 统一挂载:
- `moldinsight.api.router`(prefix=`/api`)
- `inventory.api.inventory_router`
- 使用:
- `mount_html=True`
- `serve_frontend_static=False`
- 不额外挂载 auth(交给 `app_factory`)
- 不手工重复定义 `/health`
## 4.2 简化前端 Nginx
修改:
- `deploy/nginx/frontend.conf`
从当前:
- 双 upstream:`moldinsight` / `inventory`
- 多个 `location /api/...` 手工分流
改成:
- 单 upstream:例如 `gemold_backend_upstream`
- 统一转发:
- `/api/` → unified backend
- `/health` → unified backend
- `/html/` → unified backend
保留:
- `/` 的 SPA fallback
- `/assets/` 的静态缓存策略
## 4.3 调整 Compose
修改:
- `docker-compose.yml`
目标:
- 增加 unified backend 服务
- `frontend` 只依赖 unified backend
- 保留 `moldinsight-celery`
- 按需保留 split backend 入口作为独立 profile
建议最终 profile 语义:
- `full`:frontend + unified + celery
- `frontend`:仅前端入口
- `moldinsight`:仅 gemold-only
- `inventory`:仅 inventory-only
- (可选)`unified`:仅 unified backend
## 4.4 视实现需要调整 Dockerfile
可能新增:
- `deploy/Dockerfile.unified`
或复用已有:
- `deploy/Dockerfile.moldinsight`
取决于是否希望 unified backend 使用单独镜像名。
统一要求:
- unified backend 镜像必须包含:
- `src/moldinsight/`
- `src/inventory/`
- `src/shared/`
- `src/entrypoints/unified.py`
## 4.5 文档同步
需要更新:
- `README.md`
- `frontend/README.md`
- `docs/deployment/LINUX_SETUP.md`
- `docs/deployment/DEPLOY_PORT.md`
- `docs/deployment/PORT_CONFIG.md`
重点改动:
- 当前推荐部署方式改为“frontend + unified backend + celery”
- 说明 split 模式仍保留,但不再是前端同域反代默认方式
- 端口说明中要区分:
- 前端入口端口
- unified backend 内部/对外端口
- gemold-only / inventory-only 模块端口
---
## 5. 路由与冲突评估
根据当前代码结构,unified 模式可行,主要原因:
- inventory 所有业务路由都挂在 `/api` 下,并且以独立业务前缀区分
- moldinsight 业务路由同样挂在 `/api` 下,但使用不同子路径
- auth 路由使用 `/api/auth`
- top-level `/health` 由 `app_factory` 提供
- moldinsight 内部还有 `/api/health`,与 top-level `/health` 不冲突
- `/html` 只有 moldinsight 需要
关键约束:
1. unified 入口中不要重复 include auth
2. unified 入口中不要手工再定义 top-level `/health`
3. unified 入口必须 `mount_html=True`
---
## 6. 风险与控制
### 风险 1:统一入口与现有 split 入口行为不一致
**控制:**
- 保留现有 `moldinsight.py` 与 `inventory.py`
- 只把 unified 作为前端默认 upstream
### 风险 2:`/health` 语义变化
当前前端只请求一个 `/health`,但 split 时代它实际上只代表某个后端。
**控制:**
- unified 上的 `/health` 明确作为“前端默认 backend 健康入口”
- 文档中明确其语义
### 风险 3:`/html` 丢失或不可达
**控制:**
- unified backend 继续 `mount_html=True`
- 前端 Nginx 保留 `/html/` 反代
### 风险 4:Compose、Nginx、文档不同步
**控制:**
- 先写本计划文档
- 再改 unified 入口、Nginx、Compose
- 最后统一 README 与 deployment docs
---
## 7. 验证方案
## 7.1 路由验证
unified backend 启动后应验证:
- `/api/auth/login`
- `/api/auth/me`
- `/api/upload`
- `/api/status/{task_id}`
- `/api/history`
- `/api/cost-estimate`
- `/api/products`
- `/api/inventory`
- `/api/dashboard`
- `/api/finance/*`
- `/health`
- `/html/...`
## 7.2 前端验证
前端同域访问应验证:
- `/login`
- `/moldinsight`
- `/inventory`
- `/moldinsight/result/:taskId`
关键交互:
- 登录
- 模具上传
- 任务轮询
- 成本估算
- 产品/库存/订单页面加载
- `/html` 分析结果页访问
## 7.3 Compose 验证
完整系统:
```bash
docker compose --profile full up -d
```
应满足:
- `frontend` 正常提供页面
- `frontend` 只反代一个 unified backend
- `moldinsight-celery` 正常运行
- 不再依赖 Nginx 路径级业务分流
---
## 8. 实施顺序
1. 新增 `docs/FRONTEND_UNIFIED_DEPLOYMENT_PLAN.md`
2. 新增 `src/entrypoints/unified.py`
3. 修改 `deploy/nginx/frontend.conf`
4. 修改 `docker-compose.yml`
5. 按需要修改 Dockerfile / 构建脚本
6. 更新 README 与 deployment docs
7. 做一致性验证
---
## 9. 最终预期
完成后,系统对外部署形态将变成:
- 前端:独立 Nginx 静态站点
- 网关:同域同入口
- 后端:一个 unified backend 作为前端默认 upstream
- worker:保留 gemold Celery 异步处理
- split 模式:继续作为模块独立部署能力保留
这能一次性解决当前“前端入口依赖 Nginx 路径级业务分流”的长期维护问题。