315 lines
7.6 KiB
Markdown
315 lines
7.6 KiB
Markdown
# 前端独立部署 + 统一后端入口实施计划
|
||
|
||
> 目标:在已经切换到“前端独立部署 + 同域反代”的基础上,进一步取消前端 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 路径级业务分流”的长期维护问题。 |