Dify+Nginx反向代理:80端口冲突的优雅解决方案
如果你使用 Docker Compose 部署,你可以通过修改.env配置来自定义 Dify 的访问端口。
一、修改页面访问端口
- 定位配置文件:首先,在Dify的安装目录中找到.env文件,该文件通常位于docker/子目录下。
- 调整端口参数:
- 打开.env文件,找到NGINX_PORT配置项,将其值修改为所需的端口号,例如6060。
- 同时,修改EXPOSE_NGINX_PORT配置项,确保其值与NGINX_PORT一致,即6060。
- 如果需要启用HTTPS,还需同步修改NGINX_SSL_PORT和EXPOSE_NGINX_SSL_PORT配置项,分别定义SSL端口和对外暴露的HTTPS端口。
- 重启服务:完成修改后,停止并移除旧容器,使用命令docker compose down。然后,重新构建并启动容器,使用命令docker compose up -d。
# dify在docker容器内部的端口
NGINX_PORT=6060
NGINX_SSL_PORT=6443# 修改nginx对外暴漏的端口,是上面docker内部的端口对外的映射
EXPOSE_NGINX_PORT=6060 # 默认参数是80,这里修改为6060,
EXPOSE_NGINX_SSL_PORT=6443 # 默认参数是443,这里修改为6443
二、修改API访问端口
通过以上方式修改端口后,发现api服务无法访问,修改方式如下:
- 定位配置文件:首先,在Dify的安装目录中找到.env文件,该文件通常位于docker/子目录下。
- 调整URL参数:
SERVICE_API_URL=http://实际IP:6060APP_API_URL=http://实际IP:6060APP_WEB_URL=http://实际IP:6060
经过以上配置后,发现api服务还是无法访问,具体如下:
API的访问地址:
- http://实际IP:6060/v1 (最后不带/,返回308,重定向后,丢失端口6060,报404)
- http://实际IP:6060/v1/ (最后带/,可以访问)
三、Nginx 308 重定向丢失端口问题处理
该问题是由于 Nginx 的默认行为和代理配置共同作用导致
问题原因
- 308 重定向的来源:
- 当访问 http://ip:6060/v1(无尾部斜杠)时,Nginx 默认会将其视为目录请求
- Nginx 会自动添加斜杠(/v1/)并返回 308 永久重定向
- 这是 Nginx 的默认行为,目的是标准化 URL
- 重定向到错误端口的原因:
- 问题出在重定向时丢失了端口号(6060)
- 默认情况下,Nginx 的重定向会使用 $host 变量,但不包括端口号
- 因此重定向到 http://ip/v1/ 而不是 http://ip:6060/v1/
- 404 错误的根本原因:
- 重定向后的 URL 使用了默认的 80 端口
- 由于没有映射 80 端口,请求无法到达容器内的 Nginx
解决方案
1、在default.conf.template的 server 模块中添加或修改以下配置:
server {listen 6060;server_name _;# 方案1:强制 Nginx 在重定向中包含端口号# port_in_redirect on;# 方案2:使用相对重定向而非绝对重定向(更优雅的解决方案,推荐)absolute_redirect off;# 明确设置主机头(非Dify中可以在此处设置)#set $full_host $host:${NGINX_PORT};#proxy_set_header Host $full_host;# 其余配置保持不变...
}
2、在 proxy.conf.template 中设置 proxy_set_header Host
- 问题:新增以上配置后,重定向端口号还是丢失掉了
- 分析:发现 proxy.conf 设置了 proxy_set_header Host $host;,不包含端口信息
- 方案:设置Host为主机和端口 proxy_set_header Host $host:6060;
# 修改配置,强制指定重定向主机和端口(最可靠)
# 修改前:proxy_set_header Host $host;
# ${NGINX_PORT} 为dify默认设置的变量
proxy_set_header Host $host:${NGINX_PORT};# 其余配置保持不变...
至此,Dify 修改端口后,web服务和api服务,均可正常访问。