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