Dify 安装 Tavily 插件失败排查全记录

问题现象failed to launch plugin: failed to install dependencies: signal: killed ... failed to init environment

最近在阿里云 ECS 上部署 Dify 1.14.2,尝试从插件市场安装 Tavily 搜索插件,每次都在依赖安装阶段失败,报错如下:

failed to launch plugin: failed to install dependencies: signal: killed,
output: ... Downloading tiktoken (1.1MiB)
         Downloading pydantic-core (2.0MiB)
         Downloading gevent (2.0MiB)
         Downloaded tiktoken

failed to init environment

折腾了一圈,终于定位了根本原因并解决。记录在此,供遇到同样问题的朋友参考。


环境信息

  • 服务器:阿里云 ECS(iZ2zed5cx1d7iitujxzp2wZ)
  • 内存:14GB
  • Dify 版本:1.14.2(Docker Compose 部署)
  • Plugin Daemon 镜像:langgenius/dify-plugin-daemon:0.6.1-local

排查过程

第一步:找到正确的容器名

报错信息来自 Dify 前端界面,第一反应是查日志。但容器名猜错了:

sudo docker logs dify-plugin-daemon
# Error response from daemon: No such container: dify-plugin-daemon

先列出所有相关容器:

sudo docker ps -a | grep dify

输出中找到了真正的 Plugin Daemon 容器名:docker-plugin_daemon-1

第二步:初步判断原因

看到报错中的关键词,脑子里首先浮现两个方向:

  • signal: killed → 进程被强制终止,可能是 OOM 或超时
  • init process exited due to no activity for 120 seconds → 某处 120 秒超时

第三步:诊断三件套

# 1. 查内存
free -h

# 2. 看容器里 uv 进程是否还活着
sudo docker exec docker-plugin_daemon-1 ps aux | grep uv

# 3. 查 OOM Kill 记录
dmesg | grep -E "oom|killed|Out of memory" | tail -20

结果让人意外:

              total        used        free    available
Mem:           14Gi       1.8Gi       3.3Gi        12Gi   ← 内存充足

root  72  0.2  0.5  895580 89856  Sl  11:37  0:00 /usr/local/bin/uv sync ...  ← uv 还活着

(dmesg 无输出)← 没有 OOM

内存完全不是问题,uv 进程还在运行,也没有被系统 OOM Kill。

第四步:盯住日志,等待真相

既然进程还活着,就用 --tail 100 跟踪日志,耐心等待。几分钟后,错误终于出现了:

11:42:41 ERROR  local runtime start failed
  plugin=langgenius/tavily:0.1.10
  error="failed to install dependencies: signal: killed, output:
  ...
  DEBUG No cache entry for: https://files.pythonhosted.org/packages/.../gevent-26.5.0...
  DEBUG Sending fresh GET request for: https://files.pythonhosted.org/packages/.../gevent-26.5.0...
  ...
  Downloading tiktoken (1.1MiB)
  Downloading pydantic-core (2.0MiB)
  Downloading gevent (2.0MiB)
  Downloaded tiktoken

  failed to init environment"

根本原因

日志里有一行关键配置:

uv command args=[sync --no-dev --frozen -i https://pypi.tuna.tsinghua.edu.cn/simple -v]

daemon 已经配置了清华镜像(-i tsinghua),看起来没问题。但仔细看 debug 输出:

DEBUG Sending fresh GET request for: https://files.pythonhosted.org/packages/.../gevent...
DEBUG Sending fresh GET request for: https://files.pythonhosted.org/packages/.../pydantic_core...

实际下载地址仍然是 files.pythonhosted.org,不是清华镜像!

原因在于 uv 的工作机制:

  • -i https://pypi.tuna.tsinghua.edu.cn/simple 只改变包元数据的查询地址(相当于”查目录”)
  • --frozen 模式下,uv 严格遵循 uv.lock 文件中锁定的 URL
  • uv.lock 里的实际 .whl 文件地址硬编码指向 files.pythonhosted.org

结果就是:元数据从清华查,但真正的包文件还是从 pypi.org 下载。在国内服务器上,下载 gevent(2MB)+ pydantic-core(2MB)+ tiktoken(1.1MB)等包速度极慢,触发了 daemon 的超时保护,进程被 SIGKILL。


解决方案

方案一:手动预热 uv 缓存(立即见效)

uv 有全局包缓存(默认 ~/.cache/uv)。只要在容器内手动跑一次 uv sync,绕开 daemon 的超时限制把包下载到缓存里,后续 daemon 再触发安装时就会命中缓存,瞬间完成。

# Step 1:进入容器
sudo docker exec -it docker-plugin_daemon-1 bash

# Step 2:找到插件解压目录
ls /app/storage/cwd/langgenius/ | grep tavily

# Step 3:进入插件目录,手动执行 uv sync(超时时间设为 600 秒)
cd /app/storage/cwd/langgenius/tavily-0.1.10@b43f5dc49fbafc69...

UV_HTTP_TIMEOUT=600 /usr/local/bin/uv sync --no-dev --frozen -v

# Step 4:等待下载完成后退出容器
exit

完成后回到 Dify 界面重新安装 Tavily 插件,几秒内即可成功。

方案二:增大 uv 超时(治本配置)

编辑 docker-compose.yaml,在 plugin_daemon 服务下添加环境变量:

plugin_daemon:
  environment:
    - UV_HTTP_TIMEOUT=600
    - UV_REQUEST_TIMEOUT=600

然后重启 plugin_daemon:

sudo docker compose up -d plugin_daemon

这样以后安装任何插件都不会再因为网络慢而超时。


总结

现象 误判方向 真实原因
signal: killed OOM / 内存不足 下载超时,daemon 强制终止 uv 进程
已配置清华镜像 网络问题已解决 -i 只影响元数据查询,--frozen 下实际文件仍从 pypi.org 下载
内存 12GB 空闲 硬件资源充足无问题 真正瓶颈是网络 I/O 超时,与内存无关

一句话总结:uv 的 --frozen 模式会忽略 -i 镜像参数,直接使用 uv.lock 中锁定的原始 pypi.org 下载地址。解决办法是手动预热缓存或增大超时时间。


环境:Dify 1.14.2 · dify-plugin-daemon 0.6.1 · uv 0.11.14 · 阿里云 ECS