Files
pikasTech-unidesk/docs/reference/microservices.md
T
2026-05-06 01:54:51 +00:00

141 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# UniDesk Microservices Reference
UniDesk microservice 是挂载到主 server 控制面的非核心业务后端。业务容器运行在计算节点 Docker 中,主 server 只保存仓库引用、commit id、Dockerfile/docker-compose 引用、provider 映射和前端集成配置,不把业务仓库整体复制进 UniDesk。
## Boundary
- microservice 后端端口默认只绑定计算节点本机地址,例如 `127.0.0.1:<port>`,不得直接暴露公网。
- 浏览器只访问 UniDesk frontendfrontend 通过同源 `/api/microservices/*` 代理到 backend-corebackend-core 再通过目标 provider-gateway 的 `microservice.http` 能力访问计算节点本机后端。
- backend-core REST API、database 和计算节点 microservice 后端都不得新增公网端口;公网入口仍只有 frontend 和 provider ingress。
- `microservice.http` 只允许 provider-gateway 访问 `http://127.0.0.1``http://localhost``http://host.docker.internal` 这类节点本地地址;主 server 内置 microservice 可使用同一 Compose 网络内的显式服务名,例如 `todo-note:4211`。backend-core 还必须用 `allowedPathPrefixes``allowedMethods` 同时限制可代理路径和 HTTP 方法。
## Config Contract
`config.json``microservices` 是 microservice 的唯一登记来源。每个条目必须包含:
- `id``name``providerId``description`,用于 CLI、backend-core 和 frontend 统一识别。
- `repository.url``repository.commitId`,用于记录业务代码的外部权威来源;UniDesk 不 vendoring 业务全量代码。
- `repository.dockerfile``repository.composeFile``repository.composeService``repository.containerName`,用于说明部署应复用业务仓库自身维护的 Dockerfile/docker-compose。
- `backend.nodeBaseUrl``backend.nodeBindHost``backend.nodePort``backend.proxyMode``backend.public=false``backend.frontendOnly=true``backend.allowedMethods``backend.allowedPathPrefixes``backend.healthPath`,用于定义计算节点端口到 UniDesk frontend-only 代理的映射。
- `development.providerId``development.sshPassthrough=true``development.worktreePath`,用于说明开发调试入口必须在计算节点上通过 UniDesk SSH 透传完成。
- `frontend.route``frontend.integrated=true`,用于说明该业务前端已经整合到 UniDesk React 控制台,而不是继续公开业务自身前端。
## Compute-Node Development Convention
主 server 本地开发边界固定为只开发 UniDesk frontend 与必要的 UniDesk 配置/代理登记;非 UniDesk 核心功能的后端、Dockerfile、GPU/训练容器、业务数据迁移和业务调试不得默认占用主 server 有限主机资源。涉及 findjob、pipeline、MET Nonlinear 这类业务功能时,应通过 `bun scripts/cli.ts ssh <PROVIDER_ID> ...` 或 remote CLI SSH 透传进入计算节点,在计算节点本地业务仓库中开发、构建和调试;开发完成后,只把业务服务以 microservice 形式登记到 UniDesk。
业务仓库由业务系统自己维护,包括源码、Dockerfile、docker-compose、配置模板和业务测试。UniDesk 只引用业务仓库 URL、commit id、Dockerfile/docker-compose 路径和运行容器名;不得把业务全量代码复制到 `src/components/microservices/` 形成双维护。`src/components/microservices/` 只能放通用示例或 UniDesk 自有示例,不作为业务仓库镜像。
## Main Server Microservices
主 server 只承载对统一入口或状态迁移有明确必要的 microservice。该类服务仍遵守不暴露公网端口、前端统一 React 控件化展示、状态写入主 PostgreSQL 的规则。
### Todo Note On Main Server
当前 Todo Note 作为 `id=todo-note` 的 microservice 登记在 `config.json`
- 来源工作树:D518 的 `/mnt/d/work/todo_note`;主 server 工作树固定放在 `/root/todo_note`,用于 Docker build 和后端维护。
- Provider`main-server`,由本机 provider-gateway 通过 `microservice.http` 访问同一 Compose 网络内的 `http://todo-note:4211`
- 代码引用:`https://gitee.com/Lyon1998/todo_note` 与配置中的 `repository.commitId`;UniDesk 仓库只记录引用,不 vendoring Todo Note 全量业务代码。
- 部署引用:`/root/todo_note/Dockerfile` 构建纯后端镜像,Compose service 为 `todo-note`,容器名为 `todo-note-backend`
- 数据库:Todo Note 不再使用 JSON 文件作为运行时权威存储;必须把 D518 `data/registry.json``data/instances/*.todo.json``*.history.jsonl` 迁移到主 server PostgreSQL 的 `todo_note_instances``todo_note_history` 表。
- 代理路径:只允许 `/api/` 前缀;允许方法为 `GET``HEAD``POST``DELETE`,用于保持 Todo Note 原有清单创建/删除、任务增删改、提醒、展开/收起、移动、撤销/重做等功能。
- UniDesk 前端:`微服务 / Todo Note` React 页面负责展示清单列表、树形任务、筛选、提醒、拖放/上移下移、撤销/重做、字号控制和显式原始 JSON 按钮。
Todo Note 在 UniDesk 语境中按纯后端服务管理:不得继续公开 Todo Note 自身 Vite/Web 前端,也不得把 `4211` 映射为公网端口。浏览器只能通过 UniDesk frontend 的 `/api/microservices/todo-note/...` 同源代理访问 Todo Note 后端。
Todo Note 首次迁移或源 JSON 修复时,在主 server 通过 Docker 内网执行 `/root/todo_note/scripts/migrate-json-to-pg.ts`,并显式指向主 PostgreSQL`docker run --rm --network unidesk_default -v /root/todo_note:/app -w /app -e DATABASE_URL='postgres://unidesk:unidesk_dev_password@database:5432/unidesk' oven/bun:1-alpine bun scripts/migrate-json-to-pg.ts`。迁移脚本必须输出 `importedInstances: 5``totalTodos: 100``completedTodos: 54` 这一类可审计摘要,不能只依赖前端页面观察。
Todo Note 数据迁移后必须验证:`microservice proxy todo-note /api/instances` 至少能看到 `CONSTAR``大论文``找工作``小论文``事务` 五个迁移清单,总任务数不低于源数据的 100 条;再通过代理创建临时清单、添加任务、切换完成、撤销并删除临时清单,证明写入路径走 PostgreSQL 且不会污染长期数据。
## D601 Microservices
当前 `D601` 同时承载以下 UniDesk microservice
- `findjob`FindJob 纯后端服务,UniDesk frontend 渲染岗位指标、岗位预览和草稿报告。
- `pipeline`Pipeline v2 观测服务,UniDesk frontend 渲染组件矩阵、React Flow 控制图、运行状态和证据日志摘要。
- `met-nonlinear`MET Nonlinear 训练编排服务,UniDesk frontend 渲染 GPU/镜像、训练队列、Project config 预览、训练进度、ETA 和历史记录。
### FindJob On D601
当前 FindJob 作为 `id=findjob` 的 microservice 登记在 `config.json`
- Provider`D601`
- 开发工作树:`/home/ubuntu/findjob`,开发和调试必须通过 UniDesk SSH 透传进入 D601。
- 代码引用:`https://gitee.com/Lyon1998/findjob` 与配置中的 `repository.commitId`
- 部署引用:业务仓库自身 `Dockerfile``docker-compose.yml``composeService=server``containerName=findjob-server`
- 节点后端:D601 上 `127.0.0.1:3254`provider-gateway 容器内通过 `http://host.docker.internal:3254` 访问。
- 代理路径:只允许 `/api/` 前缀;`/` 上的业务旧前端即使仍存在,也不作为 UniDesk microservice 入口使用。
- UniDesk 前端:`微服务 / FindJob` React 页面负责展示指标、岗位预览、草稿报告和原始 JSON 显式查看按钮。
FindJob 在 UniDesk 语境中按纯后端服务管理:默认页面不得 iframe 或跳转到 findjob 自身前端,也不得直接暴露 D601 的 `3254` 到公网。UniDesk frontend 只能通过 `/api/microservices/findjob/health``/api/microservices/findjob/proxy/api/...` 访问 FindJob 后端。
### Pipeline On D601
当前 Pipeline v2 作为 `id=pipeline` 的 microservice 登记在 `config.json`
- Provider`D601`
- 开发工作树:`/home/ubuntu/pipeline`,开发和调试必须通过 UniDesk SSH 透传进入 D601。
- 代码引用:`https://github.com/pikasTech/pipeline` 与配置中的 `repository.commitId`
- 部署引用:业务仓库自身 `Dockerfile``docker-compose.yml``composeService=pipeline-webui``containerName=pipeline-v2-webui`
- 节点后端:D601 上 `127.0.0.1:18082`provider-gateway 容器内通过 `http://host.docker.internal:18082` 访问。
- 代理路径:只允许 `/health``/api/` 前缀;Pipeline 自身 WebUI 静态页面即使仍由 `pipeline-webui` 提供,也不作为 UniDesk microservice 入口使用。
- UniDesk 前端:`微服务 / Pipeline` React 页面负责展示 health、组件数量、React Flow pipeline 控制图框图、最近运行、OA/procedure 摘要和显式原始 JSON 按钮。
Pipeline 在 UniDesk 语境中按观测后端服务管理:默认页面不得 iframe 或跳转到 Pipeline 自身 WebUI,也不得直接暴露 D601 的 `18082` 到公网。UniDesk frontend 只能通过 `/api/microservices/pipeline/health``/api/microservices/pipeline/proxy/api/snapshot?...` 访问 Pipeline 后端;超大 snapshot 必须使用 `__unideskArrayLimit=registry.components:<limit>,runs:<limit>` 做展示级裁剪。
### MET Nonlinear On D601
当前 MET Nonlinear 作为 `id=met-nonlinear` 的 microservice 登记在 `config.json`
- Provider`D601`
- 开发工作树:`/home/ubuntu/met_nonlinear`,后端、Dockerfile、训练队列和训练容器都必须通过 UniDesk SSH 透传在 D601 开发调试;主 server 本地只允许开发 UniDesk frontend 与代理登记。
- 数据挂载:D601 的 `/mnt/f/BaiduSyncdisk/data` 挂载为训练容器内 `/data/data`,并设置 `MET_DATA_BASE=/data`,让旧配置中的 `data/M50` 解析为 `/data/data/M50`WSL 本机不安装 TensorFlow 训练环境。
- 代码引用:`https://github.com/pikasTech/met_nonlinear` 与配置中的 `repository.commitId`
- 部署引用:业务仓库内 `docker-compose.unidesk.yml``docker/unidesk/Dockerfile.server``docker/unidesk/Dockerfile.ml``composeService=met-nonlinear-ts``containerName=met-nonlinear-ts`
- 节点后端:D601 上 `127.0.0.1:3288`provider-gateway 容器内通过 `http://host.docker.internal:3288` 访问。
- 代理路径:只允许 `/health``/api/` 前缀;允许 `GET``HEAD``POST``PUT`,用于读取队列/历史、从已有 Project fork 新 Project、保存队列设置、加入待启动队列和启动队列。
- UniDesk 前端:`微服务 / MET Nonlinear` React 页面采用类似下载器的工作台交互,负责从项目库选择已有 Project、fork 新 Project、加入待启动队列、启动队列、调整最大并发、分标签展示当前队列/已完成/失败诊断/GPU 与镜像,并展示训练进度、ETA、历史训练记录和显式原始 JSON 按钮。
MET Nonlinear 的长期服务边界写在业务仓库 `~/met_nonlinear/docs/reference/unidesk_microservice.md``met-nonlinear-ts` 是长驻 Bun TypeScript 编排后端,`met-nonlinear-ml:tf26` 是按需训练镜像,每个训练任务用一个 `docker run --rm` 容器执行 `python cli.py -t <projectPath>`,训练完成后容器自动销毁。训练镜像 Dockerfile 必须使用中国大陆可达的软件源;当前固定使用 Huawei Cloud mirror 的 `nvidia/cuda:11.2.2-cudnn8-runtime-ubuntu20.04`、Aliyun apt mirror、Tsinghua PyPI mirror、Ubuntu Python 3.8 和 `tensorflow==2.6.0`,避免官方 TensorFlow 2.6 GPU 镜像 Python 3.6 与业务源码类型注解不兼容。
MET Nonlinear 验收必须通过公网 UniDesk frontend 的交互式 UI 完成:选择已有 source Project,设置训练轮数和最大并发,使用 `Fork Project` 创建新的 `projects/unidesk_forks/` Project,确认新 Project 只是被选中而不会直接训练,再加入待启动队列并点击 `启动队列`。验收时必须确认待启动、排队中、训练中、已完成和失败诊断分标签可见,最大并发按 UI 设置生效,运行中行显示训练进度和 ETA,目标 GPU 为 2080Ti2080Ti 显存余量低于 20% 时自动限制并发,并确认训练容器结束后不残留。批量规模由 UI 输入框决定,完整验收可以通过输入 `Fork 数量=10``训练轮数=200``最大并发=3` 执行,但不得把该规模做成专用硬编码按钮。CLI `/api/queue/server-test` 仅保留为后端兼容入口,不作为 frontend 操作入口。
## CLI
- `bun scripts/cli.ts microservice list`:列出全部 microservice、provider 映射、仓库引用、后端映射和运行态容器摘要。
- `bun scripts/cli.ts microservice status findjob`:查看单个 microservice 的配置与运行态。
- `bun scripts/cli.ts microservice health findjob`:通过 backend-core -> provider-gateway -> D601 本机后端链路探测 FindJob `/api/health`
- `bun scripts/cli.ts microservice proxy findjob /api/summary`:通过同一私有代理读取业务 API,适合人工验证,不用于公开业务端口。
- `bun scripts/cli.ts microservice health pipeline`:通过 backend-core -> provider-gateway -> D601 本机后端链路探测 Pipeline `/health`
- `bun scripts/cli.ts microservice proxy pipeline '/api/snapshot?__unideskArrayLimit=registry.components:8,runs:3'`:读取 Pipeline snapshot 的有界预览,适合人工验证,不用于公开业务端口;若 body 仍超过 CLI 阈值,默认只输出 `bodyPreview`,需要完整 body 时显式追加 `--raw`
- `bun scripts/cli.ts microservice health met-nonlinear`:通过 backend-core -> provider-gateway -> D601 本机 TS 编排后端链路探测 MET Nonlinear `/health`
- `bun scripts/cli.ts microservice proxy met-nonlinear /api/queue``bun scripts/cli.ts microservice proxy met-nonlinear /api/images`:读取 MET Nonlinear 队列、GPU 策略和训练镜像状态,适合人工验证,不用于公开业务端口。
- `bun scripts/cli.ts microservice health todo-note``bun scripts/cli.ts microservice proxy todo-note /api/instances`:验证主 server Todo Note 后端、PostgreSQL 存储和本机 provider-gateway 私有代理链路。
- `bun scripts/cli.ts --main-server-ip 74.48.78.17 microservice health findjob`:在计算节点或其他非主 server 主机上通过公网 frontend remote CLI 进行同一验证,不需要主 server SSH key。
`debug dispatch D601 microservice.http --payload-json ...` 仅用于开发调试 provider-gateway 代理能力;正式验收和用户入口应优先使用 `microservice` 命令与 frontend 页面。
## Frontend Rules
microservice 前端必须整合到 `src/components/frontend/src/` 下的 TypeScript + React 模块中。`app.tsx` 只做 shell/router 和导入分发,业务页面必须拆成独立 TSX,例如 `todo-note.tsx``findjob.tsx``pipeline.tsx`。默认展示必须是业务控件:指标卡、状态徽标、表格、草稿卡片、运行卡片、树形任务、表单控件、日志摘要、链接和字段摘要;只有操作员点击 `查看原始JSON` 时才允许打开原始 JSON 弹窗。
对于超大业务 JSONbackend-core 可把 `__unideskArrayLimit=<path>:<limit>` 作为 frontend-only 代理参数传给 provider-gateway,由 provider-gateway 在返回前裁剪指定 JSON 数组并写入 `_unidesk.arrayLimits` 元数据。该参数只用于控制 UniDesk 展示预览,不能替代业务后端自身分页 API 的长期设计。CLI 的 `microservice proxy` 还会对超过默认阈值的 body 做二次有界预览,防止人工验证时输出爆炸;只有显式 `--raw` 才允许倾倒完整 body。
## Verification
microservice 交付必须同时通过后端、CLI 和公网 frontend 验证:
- 在主 server 运行 `bun scripts/cli.ts microservice list`,确认 `findjob``providerId=D601``public=false``frontendOnly=true`、仓库 URL、commit id、`127.0.0.1:3254` 映射和 `findjob-server` 容器摘要可见。
- 在主 server 运行 `bun scripts/cli.ts microservice list`,确认 `pipeline``providerId=D601``public=false``frontendOnly=true`、仓库 URL、commit id、`127.0.0.1:18082` 映射和 `pipeline-v2-webui` 容器摘要可见。
- 在主 server 运行 `bun scripts/cli.ts microservice list`,确认 `met-nonlinear``providerId=D601``public=false``frontendOnly=true`、仓库 URL、commit id、`127.0.0.1:3288` 映射和 `met-nonlinear-ts` 容器摘要可见。
- 运行 `bun scripts/cli.ts microservice health findjob``bun scripts/cli.ts microservice proxy findjob /api/summary`,确认真实链路经过 backend-core、WebSocket、D601 provider-gateway 和 D601 本机 FindJob 后端。
- 运行 `bun scripts/cli.ts microservice health pipeline``bun scripts/cli.ts microservice proxy pipeline '/api/snapshot?__unideskArrayLimit=registry.components:8,runs:3'`,确认真实链路经过 backend-core、WebSocket、D601 provider-gateway 和 D601 本机 Pipeline 后端。
- 运行 `bun scripts/cli.ts microservice health met-nonlinear``bun scripts/cli.ts microservice proxy met-nonlinear /api/queue``bun scripts/cli.ts microservice proxy met-nonlinear '/api/projects?root=projects&limit=20'``bun scripts/cli.ts microservice proxy met-nonlinear /api/images`,确认真实链路经过 backend-core、WebSocket、D601 provider-gateway 和 D601 本机 MET Nonlinear TS 后端。
- 运行 `bun scripts/cli.ts microservice health todo-note``bun scripts/cli.ts microservice proxy todo-note /api/instances`,确认真实链路经过 backend-core、WebSocket、main-server provider-gateway 和主 server `todo-note-backend` 后端;输出中必须包含五个迁移清单和 PostgreSQL 存储健康状态。
- 在 D601 上用 `bun scripts/cli.ts ssh D601 ...` 调试业务仓库和容器,确认 `curl http://127.0.0.1:3254/api/health` 可用;不要把调试服务部署到主 server。
- 在 D601 上用 `bun scripts/cli.ts ssh D601 ...` 调试业务仓库和容器,确认 `curl http://127.0.0.1:18082/health``curl http://127.0.0.1:18082/api/snapshot` 可用;不要把 Pipeline 调试服务部署到主 server。
- 在 D601 上用 `bun scripts/cli.ts ssh D601 ...` 调试 `~/met_nonlinear`,确认 `curl http://127.0.0.1:3288/health` 可用;最终验收必须回到公网 UniDesk frontend,通过项目库选择、Fork、加入待启动队列和启动队列完成,不要把 MET Nonlinear 后端、Docker build 或训练任务部署到主 server。
- 运行 `bun scripts/cli.ts e2e run`,确认 microservice 相关检查 passed,并确认 Playwright 访问的是公网 `http://74.48.78.17:18081/`
- 登录公网 frontend,进入 `微服务 / 服务目录``微服务 / Todo Note``微服务 / FindJob``微服务 / Pipeline``微服务 / MET Nonlinear`,确认能看到主 server 与 D601 provider、仓库引用、后端私有映射、Todo Note 迁移清单与树形任务、FindJob 指标和岗位预览、Pipeline 组件矩阵、React Flow 控制图和最近运行、MET Nonlinear 队列/GPU/镜像/Project config/训练历史;Todo Note 页面必须能创建临时清单、添加任务并删除临时清单,删除前必须按唯一临时清单名称重新选中对应行,禁止用未确认的当前 active 清单执行删除,FindJob 页面必须显示真实数字指标、`HEALTH OK` 和非空岗位预览,Pipeline 页面必须显示 `Pipeline v2 工作台``Health OK`、组件数和最近运行,MET Nonlinear 页面必须显示 `Health OK``Fork Project``启动队列``当前队列`、最大并发设置和 GPU/镜像面板,不能只停留在 loading 骨架;页面默认不得出现裸 JSON。