Skip to content

feat: 设计并实现 Docker Compose 应用管理 #2

Description

@wuxs

目标

在 devbox 中交付可用于单机开发环境的 Docker Compose 应用管理,与 Kubernetes runtime 并列,并统一复用应用商店、应用列表和管理抽屉。当前范围是:单机、文件原生、持久异步任务驱动、安全受控的 Compose Stack 管理器原生 1Panel 开源应用商店兼容,以及系统 Compose project 自动发现与安全接管

Compose 应用管理(已完成)

  • apps.Controller 统一领域 seam,Compose/Kubernetes adapter 隐藏在模块内部。
  • Application/Task/Revision 稳定模型;旧读路径/action 兼容;phase、service replica/health 由后端聚合。
  • Compose CLI v2 写、Docker Engine API 读;SQLite 保存 Application/Revision/Task/Idempotency/Audit;Compose、env、sidecar 与 revision 文件原生落盘。
  • deploy/start/stop/restart/redeploy/remove/purge/definition restore 全部异步返回 Task。
  • per-app 串行、跨 app 有限并发、显式幂等、乐观并发、崩溃恢复和 last observed 校验。
  • 默认卸载保留数据;purge 只删除 managed 数据;external/bind/socket 永不自动删除。
  • 粘贴/上传、预检、结构化参数、Compose 编辑、版本历史、definition restore,以及概览/服务/日志/Compose/环境变量/存储/版本/操作记录 8 个详情 Tab。
  • edge-apiserver storeapps 与通用 devbox/v1 HTTP/Git catalog 进入同一可信安装链路。

原生 1Panel 应用商店(已完成)

直接读取 1Panel 官方仓库格式(根 data.yamlapps/<key>/data.yml、版本 data.yml/formFieldsdocker-compose.yml),不要求上游转换为 devbox 私有 catalog。

  • UI 可添加、测试、保存、启停、刷新、删除 1Panel Git 来源;自动探测或显式选择 1panel
  • 动态来源持久化到现有 apps.db,与只读 YAML 来源合并;token 只写不回显;来源变更与审计同事务。
  • 原生解析应用、版本、参数和 Compose,安装时可信重取并走 Controller.Apply、Task、revision 与风险策略。
  • 处理来源隔离 ID、1panel-networkcontainer_name、不执行脚本、password 默认值、可变镜像、残留插值、sparse clone、last-good cache 和来源 generation。
  • 动态 URL 仅允许解析到公网地址的 HTTPS,拒绝 userinfo/query/fragment、私网/loopback/link-local/metadata。

系统 Compose project 自动发现与安全接管(已完成)

  • 按标准 Compose labels 扫描所有仍有容器记录(包含 stopped)的 project;与受管应用去重后统一展示。
  • 外部 project 使用稳定 ID,展示 project name、services、phase/health、端口和来源路径诊断;明确标记“已发现 · 只读”。
  • 未接管项目只读,禁止 start/stop/restart/redeploy/remove/edit 等写操作,避免误操作系统现有服务。
  • 列表扫描不读取 labels 指向的宿主文件;只有登录用户显式点击“接管并编辑”后才读取并复制定义。
  • Linux 接管使用 openat2 原子打开,拒绝 symlink/path traversal/magic-link/跨文件系统/非普通文件/超限或读取中变化;FIFO 不会阻塞请求。
  • Compose CLI 前阻断 include/build/env_file/extends/configs/secrets 等额外宿主读取;临时副本 0700/0600、空 env、固定子进程环境。
  • 接管后保留原 Compose project name 原地管理,元数据持久化并可重启恢复;named volume 数据不变。
  • 接管前执行 compose config 与现有风险预检;blocked 不可覆盖,confirmation 需显式确认并审计。
  • 接管成功后进入现有 Compose 编辑、revision、Task、日志、生命周期和卸载数据边界;源目录不被 devbox 修改。
  • 完全 down 且容器记录已删除的外部 project 无法从 Docker daemon 自动发现,UI/文档明确说明;可继续通过粘贴/上传导入。

安全边界

  • blocked 永不可 override:privileged、docker.sock、host network/PID/UTS/userns、cap_add ALL、系统关键 bind 等。
  • Secret 只进入权限受限的 .env/临时期望文件,HTTP、revision、Task、audit、CLI error、日志全链路脱敏。
  • 动态 Git 来源通过 Git CLI 获取,URL 校验到 clone 之间仍存在无法 pin DNS 的 rebinding 时间窗;该残余风险已写入研究文档。
  • 自动发现依赖仍保留的容器 metadata;完全 compose down 后不做文件系统全盘搜索。

验证

  • git diff --check
  • make test(Go race;pkg/apps 71.6%)
  • go vet ./...
  • 目标前端 ESLint 0 error;helper tests 7/7;Vite build
  • make build-all,嵌入 UI 与 Linux amd64 二进制同步
  • integration build tag 编译
  • 真实 Docker 发现→接管→编辑/重部署→进程重启恢复,保留原 project name 与 named volume marker;完全 down 后不再发现(48.89s)
  • 1Panel 官方源真实集成测试(目标机直连官方仓库)

明确边界

  • CasaOS:官方 v2 协议已做一手评估,但构建产物、路径模型与参数模型不同,本 PR 不放入半成品 adapter。
  • fnOS / Unraid:本轮不在范围,不作未经核验的开闭源断言。
  • 多主机、数据备份/恢复、GitOps 自动 reconcile、K8s↔Compose 自动转换:不属于当前单机里程碑。

实现与验证见 PR #3

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions