当前位置: 首页 > news >正文

【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 启用网络访问:

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 代理规则。

http://www.lqws.cn/news/443665.html

相关文章:

  • 亚马逊云科技中国峰会召开 解码Agentic AI时代企业加速创新路径
  • Codeforces Round 1032 (Div. 3)
  • Netty实战:从核心组件到多协议实现(超详细注释,udp,tcp,websocket,http完整demo)
  • (17)-java+ selenium->自动化测试-元素定位大法之By css上
  • openKylin高校沙龙 | 走进成都高校,推动开源技术交流与人才培养
  • ollama优化小贴士
  • flex布局 项目属性
  • 5_STM32F103ZET6系统启动过程
  • windows11 + ubuntu2204双系统+ros2 humble安装
  • IT小白到高手:HCIA、HCIP、HCIE认证攻略
  • (哈希)128. 最长连续序列
  • 嵌入式Web服务实战:OpenWRT+内网穿透实现物联网设备公网访问全攻略
  • ‘conda‘ 不是内部或外部命令,也不是可运行的程序或批处理文件?
  • FPGA基础 -- Verilog 系统任务与系统函数
  • 嘉立创EDA学习笔记4
  • 集合的处理:JDK和Guava孰强孰弱?
  • C#建立与数据库连接(版本问题的解决方案)踩坑总结
  • docker 目录更改,必须做数据迁移才能启动
  • 输入url之后发生了什么
  • Python-循环结构解析
  • Windows 10开始菜单优化方案,如何实现Win7风格开始菜单的还原
  • oracle通过dblink 连接pg数据库
  • 使用 Prometheus 访问 TDengine ---
  • OpenCV——直方图与匹配
  • Postman 的 Jenkins 管理 - 手动构建
  • OpenCV指定pid和vid通过MSMF打开摄像头
  • Spring AOP @Before (前置通知): 在目标方法执行前做什么?
  • 智能家居HA篇 二、配置Home Assistant并实现外部访问
  • android 省市区联动选择
  • 计算机视觉阶段一:CV入门基础