# 既有环境发布的数据库容器隔离设计(待审) ## 调用链与最小修改点 `production-identity-bootstrap.mjs` → `deploy-existing.sh`(固定 existing,身份与迁移预检)→ `deploy.sh`(本地校验/同步 → SSH 远端段 → Compose)。修改真正执行命令的远端段,而非仅在 wrapper 中增加一个无消费者的参数。直接调用 deploy.sh 也必须遵守相同模式约束。 ## 容器执行合同 | 阶段 | existing | initialize | | --- | --- | --- | | 数据路径 | 维持 existing 检查,不补建 PGDATA | 维持现有初始化检查与目录准备 | | db | 仅只读查询/就绪检查,不执行 up | 显式 up db 后有界等待健康 | | init | build init;run --rm --no-deps,保留 -T、entrypoint 与原命令 | 同样隔离依赖,数据库已在上一阶段就绪 | | server | build server → 健康检查 → up -d --no-build --no-deps server | 同样显式指定服务与隔离依赖 | | worker(启用时) | 检查现有镜像,必要时先 build worker → 健康检查 → up -d --no-build --no-deps worker | 同左 | | 可选 MinIO | 保留既有功能,显式限定服务;检查其有效依赖集合不得触达 db | 保留既有功能 | 模式分支包围显式 db 操作本身;不以日志、注释或上游约定代替。不要在本任务新增“绕过隔离”的开关。已有 MinIO 初始化的依赖需要保留,测试按真实图判定,不将所有依赖无差别禁止。 ## 就绪与失败 通过已确定的 Compose project/service 查询 db 容器并只读检查运行和就绪状态,不能用历史固定容器名。就绪检查采用总时限,沿用既有健康语义;同一检查函数复用于初始阶段、build init 后、init 后、build server 后、worker 准备前后,避免耗时阶段后沿用过期健康快照。existing db 不可用时停止,不运行 up/restart 作为恢复手段;initialize 创建后等待就绪。init 失败沿现有 set -e/受控日志传播,不切换应用。 只读 review 发现初稿单次提前检查不足以替代各阶段 service_healthy,现将 server build 与启动拆开,启动使用 --no-build 避免检查后的隐式构建。worker 不一律重建:在 server 切换之前通过 Compose 解析现有 worker 容器,读取其 Config.Image 并确认对应镜像引用可用;仅有旧镜像 ID 不足以证明标签存在。无容器或引用缺失时显式构建后检查健康;无容器但有缓存镜像的情况可能多一次命中缓存的构建,接受此有界兼容差异以消除隐式构建窗口。当前 Compose worker 没有显式 image 覆盖,本任务不改镜像配置、Compose 拓扑或 init 命令内容;未来修改镜像来源需单独验证所需引用与配置一致,不能以已有容器引用代表新配置。MinIO 显式选择 minio/minio_init 并隔离其他依赖,保留初始化容器自己的已有就绪重试。 此保护只隔离容器生命周期。迁移和 seed 会访问数据库内容;保留原有授权、预检和备份约束,不能声称 --no-deps 能代替数据库备份或迁移审查。 ## 命令捕获与行为判定 复用现有 Vitest 临时目录、假二进制模式,新建专用测试,避免继续堆叠静态 contains 断言。优先以 fake SSH 在隔离目录执行生产脚本发送的原始远端 shell,或从当前源码提取唯一 REMOTE heredoc 执行并另外覆盖 wrapper 模式传递;不得手抄一份发布流程作为测试对象。 - fake 记录 JSON 参数数组,区分 compose 全局选项、子命令、服务参数与 init 容器内命令,不把 shell 命令中的词误判为服务。 - 由仓库 Compose 服务依赖生成受测依赖图,不能硬编码一份与实际声明脱节的图。解析未知或含糊命令时失败;测试辅助依赖仅使用项目现有工具,必要新增依赖须再确认。 - 对 up/run 等有依赖传播的操作计算有效服务集合;对 down 或无服务名的项目级生命周期操作按整个项目判定;stop/start/restart/rm/create/kill 等显式触达 db 的操作也拒绝。运行 `init --rm` 仅清理一次性 init 容器,不误判为删除 db。 - existing 断言 db 生命周期事件列表为空,同时断言 init/server/预期 worker 出现,执行順序正确,入口成功完成目标阶段;initialize 断言 db 启动在 init 之前且健康检查生效。 - 源码变异只作用于临时副本:恢复无条件 up db,移除 init/server/worker 各自隔离。每个变异须命中预期修改点并导致具体 db 违规测试失败,禁止 needle 未命中却算失败探针通过。 - 拦截所有外部命令并清理继承敏感环境;未知外部调用直接失败,不允许落到真实 PATH 工具或网络。 ## 兼容、复核与回滚 就绪循环的总时限固定 120 秒,轮询间隔 2 秒;用受限子进程强制截止,包含 Compose/inspect 调用卡住的情况,不仅限制循环次数。超时、查询错误、缺失/停止/不健康/无健康检查均失败退出,不继续 init。测试 fake 在专用 mkdtemp 目录,子进程传入白名单环境与独立 PATH,不更改 process.env、共享 shell 配置或生产文件。 首次真实执行前的工具恢复参考:保留 `05d2a3f` 的 `deploy/trialrun/deploy.sh`(可用 `git show 05d2a3f:deploy/trialrun/deploy.sh` 只读提取)。其原命令序列为 `up -d db` → 可选 MinIO → `build init` → `run --rm -T --entrypoint sh init ...migrate...seed` → `up -d --build server` → 可选 `up -d worker`。这是有风险的旧行为证据,不是获准执行的恢复脚本;禁止盲目复制整段运行。首次生产验证需人工在场,确认 Compose 身份、既有 db 健康、已知可用应用镜像及恢复指令;若新工具失败,先停并区分工具/应用/数据库故障,人工恢复应用也应显式隔离依赖,不重跑 init/seed 或自动启动 db。应用镜像回滚与部署工具恢复分别准备,执行均另行批准。 覆盖 V2 与 V1 fallback,不改 Compose 拓扑和生产配置。只读 reviewer 不写代码,重点查三条入口、健康时序与 fake 是否掩盖风险。缺独立复核能力时明确待复核,不以主会话自检替代。回滚不得无说明地恢复允许触碰 db 的旧发布路径;若防护使既有发布暂停,保持暂停并单独审查修复,不以紧急发布为由关闭保护。