NGINXプロキシがWebSocketハンドシェイクの代わりにHTTP GET要求を私のdjangoアプリケーションに渡しています。Docker NGINXプロキシがWebソケットを転送しない
事実:アプリをDjangoのために非のWebSocketプロキシの
- 残りは素晴らしい取り組んでいます。
- djangoアプリケーションコンテナに直接接続すると、WebSocketが動作するようになります。 (下の関連するログエントリ)
- 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;
}
}
更新
私はNGINXのWebサイトでチュートリアルを使用して問題のよりコンパクトな例を構築し、https://github.com/c0yote/nginx-websocket-issueというgithubに載せました。
404の代わりに426が表示されますが、NGINXが送信しているGETの処理方法が単純なサーバーで分からないためです。私はこの考え方で、8000ポートに対してGET(ブラウザなどから直接)を発行すると同じ426ポートを取得するという事実によって強化されています。したがって、NGINXがGETを送信しているという重大な問題があります。
MORE INFO:
tcpdump
はWebSocketのサーバーへGET
がUpgrade
フィールドを持っていることを示しているが、nginxのに対してGET
はしていません。これは、wscat
コマンドがターゲットポートを除いて同一であるため、混乱します。
GIGAのUPDATE:*
私が言うには、ポート80、8080オフnginxのプロキシを取る場合は、それが動作します。私の唯一の推測は、jsクライアントがポート80についていくつかの仮定をすることです。誰かがこれがなぜそのようなことを知っていれば、私は知りたいです。
'/ etc/nginx/conf.d/default.conf'ファイルは、' envsubst'を実行した後にコンテナから出力できますか? –
私はdockerのexecを使ってそれをチェックして、実行中のコンテナのbashにしました。これは同じです。 –