【Dify 沙箱网络问题排查与解决】
🛠️ 背景介绍
在使用 Dify 的代码执行沙箱功能时,通过 rookie_text2data 插件生成 SQL 语句,并调用 rookie_execute_sql 执行数据库查询。但在实际运行过程中遇到了如下报错:
Run failed: Traceback (most recent call last):
File "/var/sandbox/sandbox-python/tmp/ec0b9d02_5c61_41e4_8894_54814b587a52.py", line 48, in
File "", line 3, in
ModuleNotFoundError: No module named 'psycopg2'
error: exit status 255
🔍 问题分析
- 依赖缺失
Python 代码中使用了 psycopg2(PostgreSQL 驱动库),但当前运行环境没有安装该依赖。 - 运行环境隔离
Dify 使用的是默认的轻量级 Python 沙箱容器,不包含本地或服务器上的任何第三方库。 - 网络限制
沙箱默认禁止对外访问网络和数据库,导致即使配置了依赖安装也无法联网下载包。
🛠️ 解决方案及排查过程
✅ 步骤一:构建带 psycopg2 的自定义沙箱镜像
1.1 创建 Dockerfile 文件
在 Dify 安装目录下的 C:\dify-1.1.3\dify-1.1.3\docker,新建 Dockerfile,内容如下:
FROM dify-sandbox-local:latest# 安装 psycopg2(PostgreSQL 支持)
RUN pip install --no-cache-dir psycopg2-binary# 可选:安装其他常用库
RUN pip install --no-cache-dir pandas requests openpyxl
1.2 构建镜像
docker build -t dify-sandbox-custom:latest .
1.3 重启
# 停止并移除所有容器
docker-compose down
# 启动服务
docker-compose up -d
测试结果:
构建成功后,重启服务并验证是否解决了问题。然而,依旧遇到错误提示:operation not permitted,说明沙箱仍然存在网络限制问题。
✅ 步骤二:启用网络访问
根据错误提示,确认沙箱默认禁用了对外网络访问。因此,修改 docker-compose.yaml 启用网络访问:
sandboxenvironment:ENABLE_NETWORK: "true"
重启后测试结果:
尽管启用了网络访问,但在尝试安装其他工具(如 iputils-ping)时发现无法解析域名,表明 DNS 设置存在问题。
✅ 步骤三:调整 DNS 设置
3.1 修改 docker-compose.yaml ,重启后解决未解决。
sandbox:image: dify-sandbox-custom:latestbuild:context: .restart: alwaysdns:- 8.8.8.8- 8.8.4.4
3.2 进入容器内部手动设置 /etc/resolv.conf:
docker exec -it dify-sandbox bash
echo "nameserver 8.8.8.8" > /etc/resolv.conf
echo "nameserver 8.8.4.4" >> /etc/resolv.conf
测试结果:
尝试安装软件包时依然失败,提示 Unable to locate package iputils-ping,表明容器网络仍然不通。
✅ 步骤四:检查 ssrf_proxy 网络模块
可能存在代理干扰,决定检查并移除 ssrf_proxy 网络模块。首先注释掉 docker-compose.yaml 中的相关部分:
# ssrf_proxy server -暂不使用
# for more information, please refer to
# https://docs.dify.ai/learn-more/faq/install-faq#id-18.-why-is-ssrf_proxy-needed
# ssrf_proxy:
# image: ubuntu/squid:latest
# restart: always
# volumes:
# - ./ssrf_proxy/squid.conf.template:/etc/squid/squid.conf.template
# - ./ssrf_proxy/docker-entrypoint.sh:/docker-entrypoint-mount.sh
# entrypoint: [ 'sh', '-c', "cp /docker-entrypoint-mount.sh /docker-entrypoint.sh && sed -i 's/\r$$//' /docker-entrypoint.sh && chmod +x /docker-entrypoint.sh && /docker-entrypoint.sh" ]
# environment:
# # pls clearly modify the squid env vars to fit your network environment.
# HTTP_PORT: ${SSRF_HTTP_PORT:-3128}
# COREDUMP_DIR: ${SSRF_COREDUMP_DIR:-/var/spool/squid}
# REVERSE_PROXY_PORT: ${SSRF_REVERSE_PROXY_PORT:-8194}
# SANDBOX_HOST: ${SSRF_SANDBOX_HOST:-sandbox}
# SANDBOX_PORT: ${SANDBOX_PORT:-8194}
# networks:
# - ssrf_proxy_network
# - default
同时将沙箱服务的网络配置改为使用默认网络:
networks:- default
强制清理旧容器和网络, Docker 默认不会自动更新网络配置,因此需要执行强制清理:
cd C:\dify-1.1.3\dify-1.1.3\docker# 停止并移除所有容器
docker-compose down# 强制重建 sandbox 服务(不使用缓存)
docker-compose build --no-cache sandbox# 启动服务
docker-compose up -d
删除 ssrf_proxy_network 网络
如果仍存在残留的 ssrf_proxy_network,需先停止相关容器:
docker stop docker-ssrf_proxy-1
docker rm docker-ssrf_proxy-1
然后删除网络:
docker network rm docker_ssrf_proxy_network
如果遇到以下错误:
Error response from daemon: error while removing network: network docker_ssrf_proxy_network has active endpoints (docker-ssrf_proxy-1)
可以通过以下命令强制清理:
docker system prune --all --volumes --force
最终测试结果
重新启动服务并进入容器进行测试,发现所有网络操作均恢复正常,能够成功解析域名并安装所需的工具包。
docker exec -it dify-sandbox bash
apt update && apt install -y iproute2 curl dnsutils
apt install -y python3 python3-pip
📌 总结
不仅解决了 Dify 沙箱中因缺少 psycopg2 导致的 SQL 执行失败问题,还逐步排查并解决了沙箱内的网络限制和 DNS 配置问题。最终实现了沙箱正常执行 SQL 并连接远程数据库的功能。
💡 补充建议
如果是生产部署,可保留 ssrf_proxy,但需正确配置 Squid 代理规则。