Administrator
发布于 2026-08-05 / 0 阅读
0
0

记录一次nginx代理dify的异常处理

故障现象

Dify 通过 HTTPS 域名访问时,页面持续刷新或请求异常;使用 HTTP 访问正常。

部署链路为:

浏览器
  -> HTTPS
阿里云 Nginx(TLS 终止)
  -> HTTP / 100.100.0.9:80
本机 Nginx
  -> HTTP
Dify Docker Nginx / 应用

Dify 的公开地址已经统一配置为 HTTPS:

CONSOLE_API_URL=https://dify.nhub.site
CONSOLE_WEB_URL=https://dify.nhub.site
SERVICE_API_URL=https://dify.nhub.site
APP_API_URL=https://dify.nhub.site
APP_WEB_URL=https://dify.nhub.site
FILES_URL=https://dify.nhub.site

根因

1. HTTPS 协议头在多层代理之间丢失

HTTPS 只在阿里云 Nginx 上终止。转发到本机 Nginx 时,网络连接本身是 HTTP;如果本机 Nginx 使用 $scheme 设置 X-Forwarded-Proto,传给 Dify 的值就会变成 http

Dify 前端配置虽然是 HTTPS,但后端根据请求头判断出当前请求是 HTTP,可能导致 Cookie、安全跳转和接口地址判断不一致,表现为登录跳转或页面反复刷新。

2. Dify 流式响应被 Nginx 缓冲

Dify 对话接口和部分 API 使用 SSE/流式响应。Nginx 默认可能缓冲上游响应,导致流式请求表现为卡住、延迟返回或连接不断重试。

处理方式

阿里云 Nginx

阿里云 HTTPS 入口必须明确向后端传递原始协议:

proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header X-Forwarded-Ssl on;

同时关闭流式响应缓冲:

proxy_buffering off;
proxy_request_buffering off;
proxy_cache off;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;

HTTP 和 HTTPS 使用两个独立的 server,HTTP 统一跳转 HTTPS:

server {
    listen 80;
    server_name nhub.site *.nhub.site;
    return 301 https://$host$request_uri;
}

本机 Nginx

本机虽然监听 HTTP,但它前面的公网请求已经是 HTTPS,所以转发给 Dify 时也要保持:

proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Port 443;
proxy_set_header X-Forwarded-Ssl on;

本机到 Dify Docker 的代理同样关闭缓冲:

proxy_buffering off;
proxy_request_buffering off;
proxy_cache off;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;

WebSocket 连接头

在 Nginx 主配置的 http {} 中定义:

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

代理配置使用:

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;

不建议对所有请求固定发送 Connection: upgrade

移除错误的 CORS 配置

以下配置不正确:

add_header Access-Control-Allow-Origin '*.nhub.site';
add_header Access-Control-Allow-Credentials 'true';

Access-Control-Allow-Origin 不支持 *.nhub.site 这种通配域名;与 Cookie 凭据一起使用时更容易造成浏览器拒绝请求。此次处理删除了这组自定义 CORS 头,由 Dify 自己处理跨域策略。

验证步骤

修改两层配置后分别执行:

nginx -t
systemctl reload nginx

检查 HTTPS 响应:

curl -k -I https://dify.nhub.site

查看 Nginx 日志:

tail -f /var/log/nginx/access.log /var/log/nginx/error.log

查看 Dify Docker 日志:

cd /opt/dify/docker
docker compose logs -f --tail=200

浏览器开发者工具的 Network 面板重点检查:

  • 是否存在 httphttps 之间反复的 301/302/307 跳转

  • Dify API 是否持续返回 401/403

  • SSE 请求是否一直 Pending

  • 是否出现 WebSocket 或 CORS 错误

结论

这次问题不是 Dify 的 HTTPS 地址变量错误,而是反向代理链路中原始 HTTPS 状态没有可靠传递,同时流式响应没有关闭 Nginx 缓冲。修复的关键是:

  1. 阿里云和本机 Nginx 都向 Dify 传递 X-Forwarded-Proto: https

  2. 关闭 Dify 相关代理的 proxy_buffering

  3. 正确处理 WebSocket 升级头。

  4. 删除无效的泛域名 CORS 配置。


评论