在Dify中访问Gemini等模型代理设置指南
问题背景
Google Gemini模型可纯免费使用,且性能也相当不错,一般个人使用或研究足够。但在在国内访问,需设置代理。在Docker部署Dify时,虽然按官方文档介绍设置代理环境变量,但实测发现并不生效。我们通过研究试验解决了这个问题,并探索了可配置化的按需走代理的方法。
说明:本文主要内容不是介绍dify本地部署的内容,可参见Dify官方部署指南。如看官有兴趣,小子可以写一个专门文章。
根因分析
先说结论
Dify中访问Gemini模型使用了Google的generativeai Python SDK,底层通过gRPC进行通信,它要求代理相关的环境变量必须使用小写形式,大写形式不生效。
详细分析过程
-
Dify官方文档说明
Dify的官方文档中提到可以通过设置环境变量(在.env.example和.env文件中)来配置代理,但没有特别说明大小写问题。文档中通常使用的是大写形式的环境变量,如HTTP_PROXY
和HTTPS_PROXY
。HTTP_PROXYHTTP 代理地址,用于解决国内无法访问 OpenAI、HuggingFace 的问题。注意,若代理部署在宿主机 (例如 http://127.0.0.1:7890),此处代理地址应当和接入本地模型时一样,使用 Docker 容器内部的宿主机地址(例如 http://192.168.1.100:7890 或 http://172.17.0.1:7890)。HTTPS_PROXYHTTPS 代理地址,用于解决国内无法访问 OpenAI、HuggingFace 的问题。同上。
-
Gemini模型插件实现
Dify的Gemini模型插件使用了Google的generativeai Python SDK。 -
底层通信机制
Google的generativeai SDK底层使用gRPC进行通信。根据gRPC官方文档,它支持以下几个代理相关的环境变量:grpc_proxy, https_proxy, http_proxy The URI of the proxy to use for HTTP CONNECT support. These variables are checked in order, and the first one that has a value is used. no_grpc_proxy, no_proxy A comma separated list of hostnames to connect to without using a proxy even if a proxy is set. These variables are checked in order, and the first one that has a value is used.
-
问题确认
对比Dify文档中说明的变量是大写形式(如HTTP_PROXY
),而gRPC文档中是小写形式(如http_proxy
)。通过实验确认,只有小写形式的环境变量对Gemini模型生效。 -
版本差异
对于Dify 0.15.x版本(尚未引入插件概念的版本),Gemini模型的源代码位于主仓库中,但代理环境变量的要求相同。
解决方案
同时设置大小写环境变量
最直接的解决方法是同时设置大小写两套环境变量,确保各种组件都能正确识别代理设置。
如果在Docker容器中设置了全局代理环境变量,所有HTTP请求都会走代理,这可能会导致不必要的性能开销。
虽然可能通过no_proxy(NO_PROXY)配置,但黑名单域名多起来就比较麻烦。
也可以让http proxy server那边配置,也不是所有的proxy server都能进行配置。我们看到,dify本身是有一个ssrf_proxy的容器服务,是使用squid支持的。至于为何dify添加了这个组件,一句话:为了安全,参见官方介绍。
我们借用这个服务,更优雅地实现按需代理。因为squid是一个非常经典的代理服务器,它支持代理链(proxy chain)和域名白名单配置。
实现步骤
确保已有可用的HTTP代理服务器(相信看官都会有,如果没有小子也提供不了)
-
在dify/docker/.env中配置环境变量
变量名没有使用官方指定,因为原来处理逻辑比较绕,可以简化,另外域名变量是为了使用白名单,而不是黑名单。为何分开主机和端口配置?这个是为了适配squid(ssrf_proxy),后续说明。# public http proxy server used in ssrf_proxy service(squid), change for your ip/port HTTP_PROXY_SERVER_HOST = 192.168.0.1 HTTP_PROXY_SERVER_PORT = 3128 # domains through public http proxy, space separate(if include subdomains, domain wildcard must be begin with comma) DOMAINS_BY_PROXY = ".googleapis.com .google.com google.dev .openai.com .anthropic.com .github.com .githubusercontent.com .githubassets.com .youtube.com .duckduckgo.com .huggingface.co .dify.ai"
-
修改dify/docker/ssrf_proxy/squid.conf.template
找到以下行(40多行的位置):# cache_dir ufs /var/spool/squid 100 16 256 # upstream proxy, set to your own upstream proxy IP to avoid SSRF attacks # cache_peer 172.1.1.1 parent 3128 0 no-query no-digest no-netdb-exchange default
替换为(必须要替换在原来的这个位置,因为squid有一序列的规则,有兴趣可参见官方文档):
# 使用squid的机制实现对指定域名及其子域名走上游代理, cache_peer ${HTTP_PROXY_SERVER_HOST} parent ${HTTP_PROXY_SERVER_PORT} 0 no-query no-digest no-netdb-exchange default acl external_domains dstdomain ${DOMAINS_BY_PROXY} never_direct allow external_domains cache_peer_access ${HTTP_PROXY_SERVER_HOST} allow external_domains cache_peer_access ${HTTP_PROXY_SERVER_HOST} deny all
-
修改dify/docker/docker-compose-template.yaml
尽量不直接修改docker-compose.yaml,但也是可行的,看官自己选择。在api、plugin_daemon、sandbox几个服务的"environment:" 节中增加如下配置environment:...# setting http proxy using ssrf_proxy serviceHTTP_PROXY: ${SANDBOX_HTTP_PROXY:-http://ssrf_proxy:3128}HTTPS_PROXY: ${SANDBOX_HTTPS_PROXY:-http://ssrf_proxy:3128}# lowercase set again for google grpc and othershttp_proxy: ${SANDBOX_HTTP_PROXY:-http://ssrf_proxy:3128}https_proxy: ${SANDBOX_HTTPS_PROXY:-http://ssrf_proxy:3128}
-
使用工具重新生成docker-compose.yaml
cd dify/docker ./generate_docker_compose
-
重建container并重启
cd dify/docker docker compose down docker compose up -d
-
验证配置
在Dify控制台中添加Gemini模型,测试连接是否成功。如果配置正确,应该能够成功连接到Google的Gemini API服务。可以docker logs docker-ssrf_proxy-1查看日志,出现以下日志(FIRSTUP_PARENT/)说明已经走了上游代理。1741518209.044 260965 172.19.0.8 TCP_TUNNEL/200 13177 CONNECT generativelanguage.googleapis.com:443 - FIRSTUP_PARENT/192.168.0.1 -
Dify的Docker网络架构简要说明
这个图表主要展示了Dify系统中的网络连接情况(可能不完全准确供参考),重点突出了以下几个方面:
-
用户访问流程:用户通过nginx访问系统,nginx将请求分发给api和web服务
-
核心服务组件:
- api:核心API服务
- web:前端Web应用
- worker:后台工作进程
- plugin_daemon:插件管理服务
- sandbox:安全的代码执行环境
-
代理服务:
- ssrf_proxy:基于Squid的代理服务器,
注意事项
- 本方案已在Dify 1.0.0版本上验证通过,对0.15.x系列版本也适用
- 如果使用SSRF代理方式,确保
ssrf_proxy
容器能够正常访问您的代理服务器 - 对于不同的模型提供商,可能需要不同的代理配置,请根据实际情况调整(国内的供应供应商一般不用配置)
- 另外发现dify官方域名dify.ai主机也是在国外,有时访问不畅,尤其是添加工具或插件,查看插件市场时,访问缓慢,所以可以让它也走代理,配置方案参见第3点。
总结
通过正确配置代理环境变量,特别是注意使用小写形式的环境变量,可以解决在国内环境下Dify使用Gemini模型的网络连接问题。利用Dify内置的SSRF代理组件,可以实现更灵活的按需代理配置,提高系统整体性能。
参考资料
- Dify官方文档
- gRPC环境变量文档
- Google Generative AI Python SDK
相关文章:
在Dify中访问Gemini等模型代理设置指南
问题背景 Google Gemini模型可纯免费使用,且性能也相当不错,一般个人使用或研究足够。但在在国内访问,需设置代理。在Docker部署Dify时,虽然按官方文档介绍设置代理环境变量,但实测发现并不生效。我们通过研究试验解决…...

MySQL的安装以及数据库的基本配置
MySQL的安装及配置 MySQL的下载 选择想要安装的版本,点击Download下载 Mysql官网下载地址: https://downloads.mysql.com/archives/installer/ MySQL的安装 选择是自定义安装,所以直接选择“Custom”,点击“Next” …...
设备树的组成
根节点下含有 compatile 属性的子节点 含有特定 compatile 属性的节点的子节点 如果一个节点的 compatile 属性,它的值是这 4 者之一:"simple-bus","simple-mfd","isa","arm,amba-bus", 那 么 它 的 子结点 (…...

C++入门——输入输出、缺省参数
C入门——输入输出、缺省参数 一、C标准库——命名空间 std C标准库std是一个命名空间,全称为"standard",其中包括标准模板库(STL),输入输出系统,文件系统库,智能指针与内存管理&am…...

deepseek 本地部署
deepseek 本地部署 纯新手教学,手把手5分钟带你在本地部署一个私有的deepseek,再也不用受网络影响。流畅使用deepseek!!! 如果不想看文章,指路:Deep seek R1本地部署 小白超详细教程 ࿰…...

[网络爬虫] 动态网页抓取 — Selenium 入门操作
🌟想系统化学习爬虫技术?看看这个:[数据抓取] Python 网络爬虫 - 学习手册-CSDN博客 0x01:WebDriver 类基础属性 & 方法 为模仿用户真实操作浏览器的基本过程,Selenium 的 WebDriver 模块提供了一个 WebDriver 类…...
HTML 超链接(简单易懂较详细)
在 HTML 中,超链接是通过 <a> 标签(anchor tag)创建的。超链接允许用户通过点击文本、图像或其他元素跳转到另一个网页、文件或页面的特定部分。本文将详细介绍 HTML 超链接的语法、属性和应用场景。 一、基本语法 <a href"U…...
rpc和proto
rpc全称远程过程控制,说白了是一种对信息发送和接收的规则编写方法,来自google,这些规则会以protobuf代码存到proto文件里。我以autoGen中agent_worker.proto为例,大概长这样 syntax "proto3";package agents;option …...

OPENGLPG第九版学习 -颜色、像素和片元 PART1
文章目录 4.1 基本颜色理论4.2 缓存及其用途颜色缓存深度缓存 / z缓存 / z-buffer模板缓存 4.2.1 缓存的清除4.2.2 缓存的掩码 4.3 颜色与OpenGL4.3.1 颜色的表达与OpenGL4.3.2 平滑数据插值 4.4 片元的测试与操作4.4.1 剪切测试4.4.2 多重采样的片元操作4.4.3 模板测试模板查询…...

【js逆向】某精灵网
地址:aHR0cHM6Ly93d3cuamluZ2xpbmdzaHVqdS5jb20vYXJ0aWNsZXM f12查看数据包,下面这个不是,你得到的是你的用户信息,需要点击第2页才会显示数据接口 查看载荷 查看预览数据,发现是加密的 查看启动器,看到 Pr…...

自然语言处理:高斯混合模型
介绍 大家好,博主又来给大家分享知识了,今天给大家分享的内容是自然语言处理中的高斯混合模型。 在自然语言处理这个充满挑战与机遇的领域,我们常常面临海量且复杂的文本数据。如何从这些数据中挖掘出有价值的信息,对文本进行有…...

RISC-V汇编学习(三)—— RV指令集
有了前两节对于RISC-V汇编、寄存器、汇编语法等的认识,本节开始介绍RISC-V指令集和伪指令。 前面说了RISC-V的模块化特点,是以RV32I为作为ISA的核心模块,其他都是要基于此为基础,可以这样认为:RISC-V ISA 基本整数指…...

OpenCV连续数字识别—可运行验证
前言 文章开始,瞎说一点其他的东西,真的是很离谱,找了至少两三个小时,就一个简单的需求: 1、利用OpenCV 在Windows进行抓图 2、利用OpenCV 进行连续数字的检测。 3、使用C,Qt 3、将检测的结果显示出来 …...
Python中与字符串操作相关的30个常用函数及其示例
以下是Python中与字符串操作相关的30个常用函数及其示例: 1. str.capitalize() 将字符串的第一个字符大写,其余字符小写。 s "hello world" print(s.capitalize()) # 输出: Hello world2. str.lower() 将字符串中的所有字符转换为小写。…...

007-Property在C++中的实现与应用
Property在C中的实现与应用 以下是在C中实现属性(Property)的完整实现方案,结合模板技术和运算符重载实现类型安全的属性访问,支持独立模块化封装: #include <iostream> #include <functional>template<typename HostType, t…...

【实战篇】【DeepSeek 全攻略:从入门到进阶,再到高级应用】
凌晨三点,某程序员在Stack Overflow上发出灵魂拷问:“为什么我的DeepSeek会把财务报表生成成修仙小说?” 这个魔性的AI工具,今天我们就来场从开机键到改造人类文明的硬核教学。(文末含高危操作集锦,未成年人请在师父陪同下观看) 一、萌新村任务:把你的电脑变成炼丹炉 …...

clickhouse属于国产吗
《ClickHouse:探索其背景与国内的应用实例》 当我们谈论数据库技术时,ClickHouse是一个绕不开的话题。很多人可能会好奇,ClickHouse是否属于国产软件呢?答案是,虽然ClickHouse最初并非在中国开发,但这款列…...

ESP32 UART select解析json数据,上位机控制LED灯实验
前言: 本实验的目的主要是通过上位机通过UART来控制ESP32端的LED的点亮以及熄灭,整个项目逻辑比较简单,整体架构如下: 上位机(PC)主要是跑在PC端的一个软件,主要作用包含: 1)串口相关配置&…...

K8S 集群搭建——cri-dockerd版
目录 一、工作准备 1.配置主机名 2.配置hosts解析 3.配置免密登录(只需要在master上操作) 4.时间同步(每台节点都要做,必做,否则可能会因为时间不同步导致集群初始化失败) 5.关闭系统防火墙 6.配置…...
基于Python的电商销售数据分析与可视化系统实
一、系统架构设计 1.1系统流程图 #mermaid-svg-Pdo9oZWrVHNuOoTT {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Pdo9oZWrVHNuOoTT .error-icon{fill:#552222;}#mermaid-svg-Pdo9oZWrVHNuOoTT .error-text{fill:#5…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
Pydantic + Function Calling的结合
1、Pydantic Pydantic 是一个 Python 库,用于数据验证和设置管理,通过 Python 类型注解强制执行数据类型。它广泛用于 API 开发(如 FastAPI)、配置管理和数据解析,核心功能包括: 数据验证:通过…...

算术操作符与类型转换:从基础到精通
目录 前言:从基础到实践——探索运算符与类型转换的奥秘 算术操作符超级详解 算术操作符:、-、*、/、% 赋值操作符:和复合赋值 单⽬操作符:、--、、- 前言:从基础到实践——探索运算符与类型转换的奥秘 在先前的文…...
Docker环境下安装 Elasticsearch + IK 分词器 + Pinyin插件 + Kibana(适配7.10.1)
做RAG自己打算使用esmilvus自己开发一个,安装时好像网上没有比较新的安装方法,然后找了个旧的方法对应试试: 🚀 本文将手把手教你在 Docker 环境中部署 Elasticsearch 7.10.1 IK分词器 拼音插件 Kibana,适配中文搜索…...

基于django+vue的健身房管理系统-vue
开发语言:Python框架:djangoPython版本:python3.8数据库:mysql 5.7数据库工具:Navicat12开发软件:PyCharm 系统展示 会员信息管理 员工信息管理 会员卡类型管理 健身项目管理 会员卡管理 摘要 健身房管理…...

LeetCode - 148. 排序链表
目录 题目 思路 基本情况检查 复杂度分析 执行示例 读者可能出的错误 正确的写法 题目 148. 排序链表 - 力扣(LeetCode) 思路 链表归并排序采用"分治"的策略,主要分为三个步骤: 分割:将链表从中间…...