首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Docker NGINX代理不转发Websockets

问Docker NGINX代理不转发Websockets
EN

Stack Overflow用户
提问于 2017-05-24 19:33:57
回答 1查看 4K关注 0票数 11

NGINX代理将HTTP请求传递给我的django应用程序,而不是WebSocket握手。

事实:

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

相关日志:

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

代码语言:javascript
复制
`xxx.xxx.xxx.xxx:40214 - - [24/May/2017:19:16:03] "GET /flight/all_flight_updates" 404 99`

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

代码语言:javascript
复制
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 (非容器)配置工程的本地主机测试:

代码语言:javascript
复制
[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

代码语言:javascript
复制
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配置模板:

代码语言:javascript
复制
  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网站上的教程构建了一个更紧凑的问题示例,并将其放在https://github.com/c0yote/nginx-websocket-issue的github上。

您可以得到426而不是404,但我相信这是因为简单的服务器不知道如何处理NGINX发送的get。如果您直接针对8000端口发出GET (例如,来自浏览器的) get,您将得到同样的426。

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

更多信息:

tcpdump显示websocket服务器的GET有一个Upgrade字段,但是针对NGINX的GET没有。这是令人困惑的,因为除了目标端口之外,wscat命令是相同的。

GIGA更新:*

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

EN

回答 1

Stack Overflow用户

发布于 2017-05-25 21:33:54

那是我组织的防火墙。

它将连接升级从端口80上的GET头中剥离出来。当我换到另一个港口时,它工作得很好。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44167069

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档