Skip to content

sandbox.mounts 的 host_path 在 docker 生产模式下被静默跳过:同一份 config.yaml 在 make dev 可用、make up 失效 #3244

Description

@yr2b

现象

config.yaml 里的 sandbox.mounts[].host_pathmake devmake up两种模式下语义不一致,且生产模式下挂载失败时没有任何用户可见的错误——挂载会被静默丢弃。结果是:依赖自定义挂载的 skill或工具在本地开发时表现正常,部署到生产后悄无声息地读到空目录。

复现步骤

config.yaml

sandbox:
  use: deerflow.sandbox.local:LocalSandboxProvider
  mounts:
    - host_path: /home/me/project/.deer-flow/knowledge
      container_path: /mnt/knowledge
      read_only: true

其中 /home/me/project/.deer-flow/knowledge 是宿主机上真实存在的目录,里面放着某个 skill 通过 /mnt/knowledge/... 读取的文件。

  • make dev → skill 能正常读到 /mnt/knowledge/...。
  • make up(docker 生产)→ skill 看到 /mnt/knowledge 是空目录 / 不存在。

两种模式都没有用户可见的报错。生产模式下唯一的信号是 local_sandbox_provider.py 里一条 WARNING 日志(Mount host_path does not exist, skipping),实际运维一般不会盯着看。

根因

LocalSandboxProvider._setup_path_mappings()(backend/packages/harness/deerflow/sandbox/local/local_sandbox_provider.py)把 host_path 当成「gateway 进程所在文件系统里的路径」,并用
host_path.exists() 做门禁:

if host_path.exists():
mappings.append(PathMapping(container_path=..., local_path=str(host_path.resolve()), ...))
else:
logger.warning("Mount host_path does not exist, skipping: ...")

  • make dev:gateway 直接跑在宿主机进程里,/home/me/.../knowledge 这种宿主机路径自然存在 → 挂载生效。
  • make up:gateway 跑在 deer-flow-gateway 容器里,docker/docker-compose.yaml 只把 config.yaml、extensions_config.json、skills/、${DEER_FLOW_HOME} 这几项 bind 进容器,配置里其它任何
    host_path 在容器内根本不存在 → host_path.exists() 返回 False → 挂载被丢弃。

变量名 host_path 进一步加深了误解:用户会以为「host」指 docker 宿主机,但在这段代码里它其实指的是「跑 LocalSandbox 的那个进程的文件系统」——生产模式下就是 gateway 容器内部。

影响

  • 任何依赖 sandbox.mounts 的 skill / 知识库 / 工具包装,本地能跑、上生产就静默失效。
  • 故障信号仅在启动日志的 DEBUG/WARNING 一行,agent 侧看到的是空目录而不是工具报错,排查成本很高。

期望行为

至少满足下面一条:

  1. 响亮失败:当 sandbox.mounts 条目解析到不存在的路径时,启动报 ERROR 并给出明确处理指引(甚至拒绝启动),不要静默丢弃。
  2. docker-aware 挂载声明:让 sandbox.mounts 成为唯一事实来源,make up 自动把它翻译成 docker-compose 的 bind 挂载,两种模式无需写两份。
  3. 文档 + 命名修正:最低限度地把 host_path 改成更不易误解的名字(如 source_path / process_path),并在 docs/CONFIGURATION.md 里明确说明:docker 生产模式下,这个路径必须在 gateway
    容器内部存在,运维需要自行在 docker-compose.yaml 里加对应的 bind mount。

临时绕过

在 docker/docker-compose.yaml 的 gateway 服务下增加对应的 bind mount:

services:
gateway:
volumes:
- ${DEER_FLOW_REPO_ROOT}/.deer-flow/knowledge:/app/.deer-flow/knowledge:ro

同时把 config.yaml 里的 sandbox.mounts.host_path 改成容器内的路径(本例是 /app/.deer-flow/knowledge),不能写宿主机路径。然后 ./scripts/deploy.sh start 重建 gateway 容器即可生效。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions