我正在尝试为 Web 应用程序(特别是 JupyterLab,但这个问题是通用的)编写 Nginx 反向代理配置。
Web 应用程序在多个不相交的 URL 层次结构中使用多个 WebSocket 端点。例如,
/jupyter/api/yjs/...
/jupyter/terminals/...
/jupyter/api/collaboration/room/...
- (和别的)
都是 WebSocket 端点。我写了一个临时配置,如下所示:
location /jupyter/ {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
client_max_body_size 0;
proxy_pass http://jupyter;
}
location ~ ^/jupyter/api/yjs/ {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass http://jupyter;
}
<repeated sections for other WebSockets endpoints>
然而,WebSockets 端点的完整列表并未记录在案。我尝试分析 nginx 和应用程序日志并推断哪些 URL 需要被代理为 WebSocket,但这显然不可靠。
有没有办法编写 nginx 配置,以便将所有传入的 WebSockets 请求代理为 WebSockets,将纯 HTTP 请求代理为纯 HTTP,而不需要在 nginx 配置中对 WebSockets 位置进行硬编码?
我发现使用 Web-ui 应用程序更容易管理反向代理
nginx-proxy-manager
。我在创建代理主机时找到了一个选项来启用websockets support
. 如果您有兴趣使用 nginxproxymanager。您可以使用此应用程序轻松地将所有传入的 WebSocket 请求代理为 WebSocket。这可以使用映射变量和一些有关 WebSocket 的知识来实现。
WebSocket 连接是使用带有两个标头的 HTTP 1.1 请求发起的:
Connection: Upgrade
和Upgrade: WebSocket
,这两个标头都是逐跳的(因此通常不会被代理)。我们可以简单地在后端连接上启用 HTTP 1.1,并使用和
proxy_http_version 1.1
代理两个标头。然而,我们仍然需要提供常规(非 WebSocket)请求以与 NGINX 默认值保持一致。因此:proxy_set_header Connection $http_connection
proxy_set_header Upgrade $http_upgrade
Connection: close