# D601 k3s 开发环境建设计划 > 状态:本过程计划的环境分支方案已废弃。长期权威规则以 `docs/reference/deploy.md` 和 `docs/reference/ci.md` 为准:dev/prod 期望状态统一写在 `master` 分支的根目录 `deploy.json`,通过 `environments.dev` 和 `environments.prod` 区分,不再以 `deploy/dev` 或 `deploy/prod` 分支作为环境事实源。本文件保留为阶段性历史计划,不作为新实现依据。 ## 目标 在现有 D601 原生 k3s 集群内建设一套与生产隔离的 UniDesk 开发环境,让以 LLM 为主力的开发流程可以部署、破坏、重建和验证 backend-core、frontend、Code Queue 及其数据库依赖,而不打断生产主 server。 第一版必须支持通过 GitHub commit id 部署。长期控制点是 GitHub 托管的 `deploy.json`:部署某个环境时,自动读取对应 GitHub 环境分支里的 `deploy.json`,并应用其中声明的 commit id。 初始环境分支: - `deploy/dev`:D601 k3s 开发环境的期望状态。 - `deploy/prod`:生产环境的期望状态。分支保护可以后续补上;第一版仍必须把 prod 部署命令和凭据与 dev 隔离。 ## 非目标 - 第一版不创建第二套物理 k3s 控制平面。先复用现有 D601 原生 k3s 集群,通过 namespace 做隔离。 - 第一版不把生产主 server 的 backend-core/frontend 迁入 k3s。 - dev 环境不得共享生产 PostgreSQL 表、Provider 身份、Provider token、Code Queue 任务状态或部署 worktree 路径。 - `deploy/dev` 和 `deploy/prod` 不是普通源码开发分支的别名,只是环境期望状态分支。 ## 目标开发拓扑 第一版 dev 环境运行在 D601 的 `unidesk-dev` namespace: - `postgres-dev`:dev 独立 PostgreSQL StatefulSet,或等价的持久化数据库。 - `backend-core-dev`:从 `deploy/dev:deploy.json` 声明的 commit id 构建。 - `frontend-dev`:从 `deploy/dev:deploy.json` 声明的 commit id 构建,并且只代理到 `backend-core-dev`。 - `code-queue-mgr-dev`:轻量 Code Queue 控制面,使用 dev 数据库。 - `code-queue-read-dev`、`code-queue-write-dev`、`code-queue-scheduler-dev`:Code Queue k3s 执行组件,使用 dev 数据库、dev 日志、dev state 路径和 dev Code Queue 配置。 - 第一阶段访问方式可选:SSH port-forward 或 D601 私有 ingress。阶段 1 不要求公网暴露。 所有 dev 服务的 `/health` 必须输出环境身份: - `environment=dev` - namespace 名称 - 数据库名称 - service id - GitHub repo 和 commit id - 部署 ref,预期为 `origin/deploy/dev` ## 核心隔离规则 1. dev 服务只能使用 `unidesk-dev` namespace。 2. dev 服务必须使用 dev PostgreSQL 实例或 dev 数据库,不能连接生产 PostgreSQL。 3. dev Provider 身份必须独立,例如 `D601-dev`,不能复用生产 `D601` 的 provider id 或 provider token。 4. dev Code Queue 的 task、queue、attempt、notification 和 trace state 不能写入生产表;除非表名已经显式 namespace 化并经过安全验证。第一版优先使用独立 dev 数据库。 5. dev manifest 不得挂载生产部署根目录,例如主 server 的 `/root/unidesk` 或 D601 生产部署路径;除非只读挂载且确实用于诊断。 6. dev Code Queue 必须使用 dev workdir、dev log dir 和 dev state dir。 7. 生产部署不能读取本地 dirty `deploy.json`;必须从配置好的 GitHub 生产环境 ref 读取生产期望状态。 8. LLM/Code Queue 开发任务默认只获得 dev 部署凭据。 ## 部署清单模型 环境 manifest 使用同一套 schema: ```json { "schemaVersion": 1, "environment": "dev", "services": [ { "id": "backend-core", "repo": "https://github.com/pikasTech/unidesk", "commitId": "" }, { "id": "frontend", "repo": "https://github.com/pikasTech/unidesk", "commitId": "" }, { "id": "code-queue", "repo": "https://github.com/pikasTech/unidesk", "commitId": "" }, { "id": "code-queue-mgr", "repo": "https://github.com/pikasTech/unidesk", "commitId": "" } ] } ``` 环境到 ref 的映射必须固定在代码或权威配置中: - `dev` 映射到 `origin/deploy/dev`。 - `prod` 映射到 `origin/deploy/prod`。 部署命令应接收环境名,而不是让生产部署任意指定分支。debug 或 admin-only 命令可以查看任意 ref,但普通 prod 部署必须走固定映射。 ## 阶段 0:设计与护栏 目的:在加入第二套运行环境前,把目标行为说清楚。 实现项: - 定义环境 manifest schema 和校验规则。 - 给 deploy manifest 增加 `environment` 字段,并拒绝环境不匹配的 manifest。 - 定义固定环境映射:`dev -> deploy/dev`,`prod -> deploy/prod`。 - 记录 dev 的目标 namespace、数据库、Provider 身份和 service id。 - 增加 CLI dry-run plan 输出: - 选中的环境 - GitHub ref - 解析到的 manifest commit - services 和 commit id - 目标 namespace - 目标数据库指纹 - 目标 Provider 身份 验收标准: - `deploy plan --env dev` 可以读取并校验 dev manifest,且不修改集群。 - `deploy plan --env prod` 可以读取并校验 prod manifest,且不使用本地 worktree 的 `deploy.json`。 - `environment=prod` 的 manifest 必须被 `--env dev` 拒绝,反向也必须拒绝。 ## 阶段 1:GitHub 环境分支作为部署源 目的:让 GitHub 里的环境期望状态 ref 成为部署真相源。 实现项: - 创建或初始化 `deploy/dev`,包含有效的 `deploy.json`。 - 创建或初始化 `deploy/prod`,包含有效的 `deploy.json`。 - 增加 CLI 支持:fetch 环境 ref,并从该 ref 读取 `deploy.json`。 - 现有本地 `deploy.json` 只保留为显式本地/管理员流程的兼容模式。 - 校验 manifest 中列出的 commit id 存在于声明的 repo。 - 确保 dev/prod 部署不依赖本地 dirty working tree。 验收标准: - `deploy plan --env dev` 读取 `origin/deploy/dev:deploy.json`。 - `deploy plan --env prod` 读取 `origin/deploy/prod:deploy.json`。 - 修改本地 `deploy.json` 不影响 `--env dev` 或 `--env prod`。 - plan 输出包含实际使用的 Git ref 和 manifest blob/commit。 ## 阶段 2:D601 开发 Namespace 与数据库 目的:创建 dev backend 和 Code Queue state 的最小隔离底座。 实现项: - 增加 `unidesk-dev` namespace 的 k8s manifest。 - 增加 dev PostgreSQL StatefulSet/Service/PVC,或等价持久化 DB。 - 增加 dev DB init 和 migration 流程,用于 backend-core 和 Code Queue 表。 - 增加 dev secrets/config: - 数据库凭据 - provider token - auth/session secret - 必要时的 Code Queue model secrets - 增加资源 requests/limits,避免 dev DB 挤占 D601 生产 k3s workload。 技术决策: - 优先使用独立 dev PostgreSQL 实例,而不是共享生产 PostgreSQL 的不同数据库名。独立实例的故障边界最清晰。 - 如果临时使用共享 PostgreSQL server,CLI 和服务启动时必须硬校验数据库名和连接目标。 验收标准: - `kubectl -n unidesk-dev get pods,svc,pvc` 显示 dev DB ready。 - dev DB 在 Pod 重启后数据仍存在。 - dev 服务误连生产数据库 URL 时,必须启动失败。 ## 阶段 3:backend-core-dev 与 frontend-dev 目的:做出一套可用的 UniDesk dev 控制面,不依赖生产主 server Compose。 实现项: - 增加 `backend-core-dev` 和 `frontend-dev` 的 k8s manifest。 - 从 `deploy/dev:deploy.json` 声明的 commit id 构建镜像。 - 向 backend-core 注入 dev-only config: - `UNIDESK_ENV=dev` - dev `MICROSERVICES_JSON` - dev database URL - dev provider token - dev log paths - 注入 frontend 配置,使其代理到 `backend-core-dev`,不能代理生产 backend-core。 - 增加 service health 和 readiness probe。 - 通过 port-forward 或私有 dev ingress 暴露 dev frontend。 技术决策: - 第一版可以不做公网暴露。验证隔离时使用 port-forward 即可。 - dev frontend 必须有明显 DEV 环境标记,避免操作员混淆。 验收标准: - dev backend-core `/health` 返回 ok,并包含 `environment=dev`。 - dev frontend `/health` 返回 ok,并且只代理到 dev backend-core。 - dev backend/frontend 重部署期间,生产 `bun scripts/cli.ts server status` 仍健康。 - 重建 dev backend/frontend 不触碰主 server Docker Compose 容器。 - 当前实施切片:`deploy apply --env dev --service backend-core|frontend` 先支持 dev core 两个服务;`deploy/dev` 只保存 `deploy.json`,不保存 k8s manifest 或源码。 ## 阶段 4:code-queue-mgr-dev 目的:提供 dev 队列管理和提交路径,同时不写生产 Code Queue 表。 实现项: - 增加 `code-queue-mgr-dev` k8s manifest。 - 配置它只使用 dev 数据库。 - 配置 dev backend-core service catalog,使 dev 稳定 `code-queue` 控制/读取路径路由到 `code-queue-mgr-dev`。 - 确保 `code-queue-mgr-dev` 可以提交、列出、汇总和更新 dev queue state。 - health 输出必须证明: - role 是 `master-control-plane` 或 `dev-control-plane` - database 是 dev - schema ready - no runner dependencies 验收标准: - dev UI/CLI 可以向 dev DB 提交 dry-run 或 queued task。 - dev 提交不会改变生产 Code Queue task list。 - `code-queue-mgr-dev` 内存占用保持在轻量控制面预算内。 ## 阶段 5:code-queue-dev 执行组件 目的:在 `unidesk-dev` 内运行 dev Code Queue 执行面,不干扰生产 Code Queue。 实现项: - 增加 Code Queue manifest 的 dev 变体: - `code-queue-read-dev` - `code-queue-write-dev` - `code-queue-scheduler-dev` - 所有 dev 组件使用 dev 数据库、dev 日志和 dev state 路径。 - 使用 dev service name 和 label,避免生产 k3s adapter 混淆 dev/prod 服务。 - 决定第一版支持真实 Codex 执行,还是只支持 smoke-only 执行。 - 如果启用真实执行: - 隔离 workdir 路径 - 隔离 Codex/OpenCode XDG/state 路径 - 隔离通知 - 限制并发和内存 - 默认不写生产 OA Event Flow,除非显式配置为 dev 技术决策: - 第一版采用真实 Code Queue 进程和 dev PostgreSQL,但部署验收先以执行面可部署、`/health` 通过和 dev DB 隔离为准。 - dev scheduler 使用 `D601-dev` 作为本机 Provider 标识,默认工作目录为 `/workspace-dev`,远程工作目录为 `/home/ubuntu/unidesk-dev-workspace`。 - 默认禁用生产 ClaudeQQ 通知,不使用生产 `d601-tcp-egress-gateway` 或生产 PostgreSQL 入口。 - dev frontend/backend-core 的稳定 `code-queue` 业务路由需要等 `code-queue-mgr-dev` 和 dev service catalog 完成后再接入,本阶段不把 dev 执行面伪装成完整业务入口。 验收标准: - dev Code Queue `/health` 返回 ok,并包含 `environment=dev`。 - `deploy apply --env dev --service code-queue` 可以根据 `origin/deploy/dev:deploy.json` 构建 `unidesk-code-queue:dev`,部署 `code-queue-scheduler-dev`、`code-queue-read-dev`、`code-queue-write-dev`,并验证 health commit。 - 后续接入 `code-queue-mgr-dev` 后,dev scheduler 可以拾取 dev queued task,并推进到终态。 - 重启 dev scheduler 不影响生产 running task。 - dev Code Queue rollout 期间,生产 `code-queue` health 仍健康。 ## 阶段 6:Dev 部署执行 目的:让 `deploy/dev:deploy.json` 端到端驱动 dev 环境。 实现项: - 增加 `deploy apply --env dev`。 - 对 dev manifest 中的每个服务: - fetch 声明的 repo 和 commit - 在 D601 上构建镜像,或复用既有 target-side build 路径 - 用环境和 commit 给镜像打 tag - apply dev k8s manifest - 等待 rollout - 从 `/health` 或 Deployment annotation 验证 live commit - 部署记录包含 environment、ref、service id、commit id、image tag、namespace 和 rollout 状态。 - 增加 `deploy status --env dev` 或等价 drift check。 验收标准: - 更新 `deploy/dev:deploy.json` 到新 commit 后,运行 `deploy apply --env dev` 会更新 dev backend-core/frontend/code-queue 组件。 - live `/health` commit 与 manifest commit 一致。 - dev 部署不会修改任何生产 Deployment、Service、Secret、PVC、DB table 或 Docker Compose 容器。 ## 阶段 7:生产部署 Ref 兼容 目的:让生产部署从 `deploy/prod` 读取期望状态,同时保持生产运行方式不变。 实现项: - 增加 `deploy plan --env prod` 和 `deploy apply --env prod`,读取 `origin/deploy/prod:deploy.json`。 - 初期保持现有生产 executor: - 生产 backend-core/frontend 和 direct sidecar 继续使用主 server Compose。 - 生产 Code Queue 执行面继续使用 D601 k3s。 - 强化生产命令护栏: - 只能在权威根目录执行 - 生产凭据只存在主 server - manifest 必须声明 `environment=prod` - 目标 namespace 和 Provider 身份必须匹配生产 - 建议后续给 `deploy/prod` 增加 branch protection;第一版可暂缓。 验收标准: - 生产部署不再依赖本地 `deploy.json`。 - 生产部署报告实际使用的 Git ref 和 manifest commit。 - 生产部署 rollout 后仍校验 live commit。 ## 阶段 8:操作员与 LLM 安全 目的:降低 LLM agent 和人工操作员混淆环境的概率。 实现项: - 每次 deploy 的 CLI 输出都清晰显示: - environment - ref - namespace - DB 指纹 - provider id - services 和 commits - dev frontend 增加明确 DEV 标记。 - 增加硬启动检查: - dev service 拒绝生产 DB - dev service 拒绝生产 provider id/token - prod service 拒绝 dev namespace/DB - 确保 LLM task container 默认只拿到 dev deploy 凭据,拿不到 prod 凭据。 - 增加 smoke check:故意尝试不安全组合,并验证它们失败。 验收标准: - dev 服务使用生产 DB 配置启动时,在监听端口前失败。 - 从非权威上下文运行 prod deploy 时失败。 - LLM/Code Queue 默认环境可以部署 dev,但没有独立生产凭据路径时不能部署 prod。 ## 风险与缓解 - 风险:namespace 不能隔离节点级 CPU、内存、Docker socket、hostPath 或 containerd 压力。 - 缓解:资源 requests/limits、独立 dev workdir、不挂载生产路径,并限制 Code Queue 并发。 - 风险:dev Code Queue 误写生产 task 表。 - 缓解:独立 dev DB、启动时 DB 指纹检查、health 输出 DB 身份。 - 风险:dev frontend 看起来像 prod,或代理到 prod backend-core。 - 缓解:可见 DEV 标记、`CORE_INTERNAL_URL` 固定到 dev service、proxy target health check。 - 风险:deploy 命令误读本地 manifest,而不是 GitHub 环境 ref。 - 缓解:`--env` 模式必须只读取 remote ref,并报告实际使用的 ref/blob。 - 风险:D601 k3s 控制面故障同时影响 dev 和生产 k3s workload。 - 缓解:Phase 1 接受该风险;只有 namespace 隔离被证明不足后,再考虑独立物理节点或节点级 dev 集群。 - 风险:`deploy/prod` 初期未开启 branch protection。 - 缓解:即使没有 branch protection,生产部署仍必须要求权威主 server 凭据,并报告用于审计的 ref。 ## 建议实现顺序 1. Phase 0 和 Phase 1:建立 GitHub 环境分支期望状态和 dry-run planning。 2. Phase 2 和 Phase 3:创建 dev namespace、dev DB、backend-core-dev 和 frontend-dev。 3. Phase 4 和 Phase 5:增加 dev Code Queue 控制面和执行组件。 4. Phase 6:让 `deploy apply --env dev` 按 commit id 部署完整第一版 dev stack。 5. Phase 7:把生产部署迁移到 `deploy/prod`。 6. Phase 8:强化操作员和 LLM 安全检查。 第一个完整里程碑完成条件:`deploy apply --env dev` 可以根据 `origin/deploy/dev:deploy.json` 声明的 commit id,把 backend-core、frontend、code-queue-mgr 以及 Code Queue read/write/scheduler 部署进 `unidesk-dev`;反复 dev redeploy 不改变生产主 server status,也不改变生产 Code Queue state。阶段 3 的阶段性里程碑先以 `--service backend-core` 和 `--service frontend` 分别部署成功为准。