【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

🔍 问题分析

  1. 依赖缺失
    Python 代码中使用了 psycopg2(PostgreSQL 驱动库),但当前运行环境没有安装该依赖。
  2. 运行环境隔离
    Dify 使用的是默认的轻量级 Python 沙箱容器,不包含本地或服务器上的任何第三方库。
  3. 网络限制
    沙箱默认禁止对外访问网络和数据库,导致即使配置了依赖安装也无法联网下载包。

🛠️ 解决方案及排查过程

✅ 步骤一:构建带 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 启用网络访问:

sandbox
  environment:
    ENABLE_NETWORK: "true"

重启后测试结果:
尽管启用了网络访问,但在尝试安装其他工具(如 iputils-ping)时发现无法解析域名,表明 DNS 设置存在问题。
✅ 步骤三:调整 DNS 设置
3.1 修改 docker-compose.yaml ,重启后解决未解决。

sandbox:
    image: dify-sandbox-custom:latest
    build:
      context: .
    restart: always
    dns:
      - 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 代理规则。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值