Docker NGINX Proxy not Forwarding Websockets

≡放荡痞女 提交于 2021-01-26 23:50:08

问题


NGINX proxy is passing HTTP GET requests instead of WebSocket handshakes to my django application.

Facts:

  • Rest of the non-websocket proxying to django app is working great.
  • I can get WebSockets to work if I connect to the django application container directly. (Relevant log entries below.)
  • The nginx configuration works localhost on my development machine (no containerizing). (Log example below.)

Relevant Logs:

Daphne log when connecting through containerized nginx proxy:

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

Daphne log when bypassing the containerized proxy and connecting directly to the server:

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" - -

localhost testing of nginx (non-containerized) configuration works:

[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]

Configuration files:

My 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

My proxy.template NGINX configuration template:

  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

I have built a more compact example of the problem using the tutorial on the NGINX website and put it on github at https://github.com/c0yote/nginx-websocket-issue.

You get a 426 instead of a 404, but I believe this is because the simple server doesn't know how to handle the GET that NGINX is sending. I am reinforced in this thought by the fact that if you issue a GET (from a browser for example) directly against the 8000 port you get the same 426.

Therefore the core problem is still that NGINX is sending a GET.

MORE INFO:

tcpdump shows that the GET to the websocket server has an Upgrade field, but the GET against NGINX does not. This is confusing since the wscat command is identical with the exception of the target port.

GIGA UPDATE:*

If I take the NGINX proxy off port 80 to say, 8080 it works. My only guess is that the js client makes some assumption about port 80. If anyone knows why this is the case, I'd love to know.


回答1:


It was my organization's firewall.

It was stripping the connection upgrade out of the GET header on port 80. When I changed to a different port, it worked fine.



来源:https://stackoverflow.com/questions/44167069/docker-nginx-proxy-not-forwarding-websockets

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!