difyai安装模型失败:failed to create virtual environment: exit status 101

Dify 的 plugin_daemon 在给插件创建 Python 虚拟环境时失败了。失败点不是插件本身,而是底层的 uv 在当前容器/系统环境里执行某个操作时被拒绝,返回了 Operation not permitted,所以虚拟环境初始化失败。 Dify 社区里有和你几乎一致的报错:failed to create virtual environment: exit status 101,接着是 Tokio executor failed ... PermissionDenied, message: "Operation not permitted"。 

从 Dify 的相关 issue 看,问题出在 plugin_daemon 容器初始化插件环境这一步,且它默认会把工作目录放在 PLUGIN_WORKING_PATH=/app/storage/cwd,通常通过 volume 挂载到宿主机目录。 

这类 Operation not permitted 常见有三类根因:

  1. 挂载目录权限不对

  2. 挂载目录所在分区带了 noexec / 受限挂载参数

  3. Docker / libseccomp / 容器运行时过旧或安全限制过严,导致 uv 执行时被拒绝

Dify 和 Docker 官方镜像生态里都出现过这类由容器兼容性或安全限制引发的 Operation not permitted。 

你可以按这个顺序改。

第一种改法:先检查 plugin_daemon 的宿主机目录权限

先找到 compose 里这段:

bash 复制代码
plugin_daemon:
  volumes:
    - ./volumes/plugin_daemon:/app/storage

Dify issue 里就是这种挂载方式。 

然后在宿主机执行:

bash 复制代码
mkdir -p ./volumes/plugin_daemon/cwd
chmod -R 777 ./volumes/plugin_daemon

然后重启:

bash 复制代码
docker compose down
docker compose up -d
docker compose logs -f plugin_daemon

这是最快的验证方式。先别纠结最优权限,先确认是不是纯权限问题。

第二种改法:检查挂载目录是不是 noexec

这个非常像你现在的症状。因为 uv 创建虚拟环境时,通常需要在工作目录里创建和运行一些文件;如果挂载目录所在磁盘是 noexec,就很容易报这种 Operation not permitted。

在宿主机执行:

bash 复制代码
mount | grep plugin_daemon
mount | grep /app
mount | grep /data
mount | grep /home

也可以直接看你项目目录所在分区:

bash 复制代码
df -h .
mount | grep "$(df . | tail -1 | awk '{print $1}')"

如果看到挂载参数里有 noexec,那就是高概率根因。

处理办法有两个:

把 ./volumes/plugin_daemon 换到一个可执行的本地目录,比如:

bash 复制代码
plugin_daemon:
  volumes:
    - /opt/dify/plugin_daemon:/app/storage

然后:

bash 复制代码
mkdir -p /opt/dify/plugin_daemon/cwd
chmod -R 777 /opt/dify/plugin_daemon

再重启容器。

第三种改法:给 plugin_daemon 放宽 seccomp 做验证

如果目录权限没问题、挂载也不是 noexec,那就很像容器运行时限制。

在 plugin_daemon 服务里临时加:

bash 复制代码
plugin_daemon:
  security_opt:
    - seccomp=unconfined

然后重启:

bash 复制代码
docker compose down
docker compose up -d
docker compose logs -f plugin_daemon

如果这样就好了,说明就是容器安全限制或宿主机 Docker 运行时兼容性问题。Docker 生态里类似 Operation not permitted 问题经常和 seccomp / 旧版运行时有关。 

第四种改法:升级宿主机 Docker / containerd / runc / libseccomp

如果你机器比较老,这一步很重要。

这类问题经常发生在:

• 老版本 CentOS / Ubuntu

• 老版本 Docker CE

• 老版本 libseccomp

先查版本:

bash 复制代码
docker version
docker info

CentOS/RHEL:

bash 复制代码
rpm -qa | grep -E 'docker|containerd|runc|libseccomp'

Ubuntu/Debian:

bash 复制代码
dpkg -l | grep -E 'docker|containerd|runc|libseccomp'

Dify 和 Docker 相关 issue 都表明,这类 Operation not permitted 往往和宿主机运行时环境有关,而不是 Dify 配置本身写错。 

我最建议你直接这样改

先改 plugin_daemon 这一段:

bash 复制代码
plugin_daemon:
  volumes:
    - /opt/dify/plugin_daemon:/app/storage
  security_opt:
    - seccomp=unconfined
  environment:
    PLUGIN_WORKING_PATH: /app/storage/cwd
    RUST_BACKTRACE: full

然后宿主机执行:

bash 复制代码
mkdir -p /opt/dify/plugin_daemon/cwd
chmod -R 777 /opt/dify/plugin_daemon
docker compose down
docker compose up -d
docker compose logs -f plugin_daemon

这套改法的目的很明确:

• 避开原目录可能的权限/挂载问题

• 临时绕开 seccomp 限制

• 打开更完整的 Rust 回溯方便确认