gpt4 book ai didi

django - Docker NGINX 代理不转发 Websocket

转载 作者:IT老高 更新时间:2023-10-28 21:23:57 44 4
gpt4 key购买 nike

NGINX 代理正在向我的 django 应用程序传递 HTTP GET 请求而不是 WebSocket 握手。

事实:

  • django 应用的其他非 websocket 代理运行良好。
  • 如果我直接连接到 django 应用程序容器,我可以让 WebSockets 工作。 (以下相关日志条目。)
  • nginx 配置在我的开发机器上运行 localhost(没有容器化)。 (下面的日志示例。)

相关日志:

通过容器化 nginx 代理连接时的 Daphne 日志:

`xxx.xxx.xxx.xxx:40214 - - [24/May/2017:19:16:03] "GET /flight/all_flight_updates" 404 99`

绕过容器化代理并直接连接到服务器时的 Daphne 日志:

xxx.xxx.xxx.xxx:6566 - - [24/May/2017:19:17:02] "WSCONNECTING /flight/all_flight_updates" - -
xxx.xxx.xxx.xxx:6566 - - [24/May/2017:19:17:02] "WSCONNECT /flight/all_flight_updates" - -

nginx(非容器化)配置的 localhost 测试有效:

[2017/05/24 14:24:19] WebSocket HANDSHAKING /flight/all_flight_updates [127.0.0.1:65100]
[2017/05/24 14:24:19] WebSocket CONNECT /flight/all_flight_updates [127.0.0.1:65100]

配置文件:

我的docker-compose.yml:

version: '3'
services:
db:
image: postgres
redis:
image: redis:alpine
web:
image: nginx
ports:
- '80:80'
volumes:
- ./deploy/proxy.template:/etc/nginx/conf.d/proxy.template
links:
- cdn
- app
command: /bin/bash -c "envsubst '' < /etc/nginx/conf.d/proxy.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
cdn:
image: nginx
volumes:
- ./cdn_static:/usr/share/nginx/static
- ./deploy/cdn.template:/etc/nginx/conf.d/cdn.template
command: /bin/bash -c "envsubst '' < /etc/nginx/conf.d/cdn.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
app:
build: .
image: app
ports:
- '8000:8000'
links:
- redis
- db
volumes:
- ./cdn_static:/var/static

我的proxy.template NGINX 配置模板:

  upstream cdn_proxy {
server cdn:80;
}

upstream daphne {
server app:8000;
keepalive 100;
}

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

server {
location /static {
proxy_pass http://cdn_proxy;
}

location / {
proxy_buffering off;
proxy_pass http://daphne;
proxy_read_timeout 300;
proxy_connect_timeout 300;

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;

proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;

}
}

更新

我使用 NGINX 网站上的教程构建了一个更紧凑的问题示例,并将其放在 github 上 https://github.com/c0yote/nginx-websocket-issue .

你得到的是 426 而不是 404,但我相信这是因为简单的服务器不知道如何处理 NGINX 发送的 GET。如果您直接针对 8000 端口发出 GET(例如从浏览器中),您会得到相同的 426,这让我更加坚信这一点。

因此核心问题仍然是 NGINX 正在发送 GET。

更多信息:

tcpdump 表明到 websocket 服务器的 GET 有一个 Upgrade 字段,但是针对 NGINX 的 GET才不是。这很令人困惑,因为 wscat 命令与目标端口不同。

GIGA 更新:*

如果我把 NGINX 代理从端口 80 上取下来,8080 就可以了。我唯一的猜测是 js 客户端对端口 80 做了一些假设。如果有人知道为什么会这样,我很想知道。

最佳答案

这是我组织的防火墙。

它正在从端口 80 上的 GET header 中剥离连接升级。当我更改为不同的端口时,它工作正常。

关于django - Docker NGINX 代理不转发 Websocket,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44167069/

44 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com