NGINX代理正在傳遞HTTP GET請求,而不是WebSocket握手到我的Django應用程序。碼頭NGINX代理不轉發Websockets
事實:非WebSocket的代理到Django應用程序的
- 其餘的是偉大的工作。
- 如果我直接連接到django應用程序容器,我可以讓WebSockets工作。 (下面的相關日誌條目。)
- nginx配置在我的開發機器上運行localhost(無集裝箱)。 (登錄下面的例子。)
相關日誌:繞過集裝箱代理,並直接連接到服務器時
`xxx.xxx.xxx.xxx:40214 - - [24/May/2017:19:16:03] "GET /flight/all_flight_updates" 404 99`
瑞香日誌:
瑞香連接時通過集裝箱nginx的代理登錄:
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(n上集裝箱)配置工作:
[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;
}
}
UPDATE
我已經使用NGINX網站上的教程構建了一個更加簡潔的問題示例,並將它放在github上的https://github.com/c0yote/nginx-websocket-issue。
你得到426而不是404,但我相信這是因爲簡單的服務器不知道如何處理NGINX發送的GET。在這個想法中,我強化了這一點,如果你直接針對8000端口發出一個GET(例如從瀏覽器),你將得到相同的426.
因此,核心問題仍然是NGINX發送一個GET。
更多信息:
tcpdump
表明GET
到WebSocket的服務器有一個Upgrade
場,但GET
對NGINX沒有。這是令人困惑的,因爲wscat
命令與目標端口的例外相同。
GIGA UPDATE:*
如果我參加了NGINX代理關閉80端口說,8080它的工作原理。我唯一的猜測就是js客戶端對80端口做了一些假設。如果有人知道爲什麼會發生這種情況,我很想知道。
你可以在容器通過'envsubst'運行後輸出'/ etc/nginx/conf.d/default.conf'文件嗎? –
我已經通過docker exec在運行的容器上對它進行了檢查,並且它是相同的。 –