Docker NGINX + Logspout不转发websocket

我试图使用NGINX从Logspout(升级到Websocket)访问httpstream。

这里是我docker-compose.yml文件的代码片段:

 version: '3' services: api: restart: always build: args: - DEBUG - DOMAINS - IPS - SECRET_KEY context: .. dockerfile: Dockerfile environment: - DEBUG - DOMAINS - IPS - SECRET_KEY - GUNICORN_LOG_LEVEL expose: - '8000' volumes: - ../db.sqlite3:/db.sqlite3 - /opt/scos:/opt/scos devices: - /dev/bus/usb:/dev/bus/usb:rw command: /docker/api_entrypoint.sh nginx: image: ${NGINX_IMAGE} restart: always ports: - '80:80' - '443:443' volumes: - ../nginx/conf.d:/etc/nginx/conf.d:ro - ../src/static:/var/www/scos-sensor/static:ro - ${SSL_CERT_PATH}:/etc/ssl/certs/ssl-cert.pem:ro - ${SSL_KEY_PATH}:/etc/ssl/private/ssl-cert.key:ro ws_logger: image: gliderlabs/logspout expose: - '80' volumes: - /var/run/docker.sock:/var/run/docker.sock 

基本上,我有一个API上运行的api:8000ws_logger:80上的ws_logger:80 。 因此,我的/etc/nginx/conf.d/scos-sensor.conf文件看起来像:

 # -*- conf -*- upstream wsgi-server { # fail_timeout=0 means we always retry an upstream even if it failed # to return a good HTTP response (in case the gunicorn master nukes a # single worker for timing out). server api:8000 fail_timeout=0; } upstream ws-logger { server ws_logger:80; } map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 80 default_server; listen [::]:80 default_server; # Redirect all HTTP requests to HTTPS with a 301 Moved Permanently response. #return 301 https://$host$request_uri; # For testing, use 307 so that redirect is not cached in browser return 307 https://$host$request_uri; } server { # SSL configuration listen 443 ssl; listen [::]:443 ssl; server_name ${DOMAINS}; # reduce "upstream response is buffered to a temporary file" warnings proxy_buffers 16 16k; proxy_buffer_size 16k; ssl on; ssl_certificate /etc/ssl/certs/ssl-cert.pem; ssl_certificate_key /etc/ssl/private/ssl-cert.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # path for static files root /var/www/scos-sensor/; location / { # checks for static file, if not found proxy to wsgi server try_files $uri @proxy_to_wsgi_server; } location /logs/ { proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_pass http://ws-logger/logs; } # Pass off requests to Gunicorn location @proxy_to_wsgi_server { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://wsgi-server; } } 

我期望的是当我运行docker-compose -p scossensor up ,我可以轻松运行wscat -c wss://localhost/logs/ -n来连接到websocket。

但是,当我运行wscat -c wss://localhost/logs/ -n ,它会closuresws_logger容器,并显示以下错误消息:

 ws_logger_1 | panic: send on closed channel ws_logger_1 | ws_logger_1 | goroutine 3 [running]: ws_logger_1 | panic(0x563922414400, 0xc420202050) ws_logger_1 | /usr/lib/go/src/runtime/panic.go:500 +0x1a5 ws_logger_1 | github.com/gliderlabs/logspout/router.(*containerPump).send(0xc420012f80, 0xc4201c2ac0) ws_logger_1 | /go/src/github.com/gliderlabs/logspout/router/pump.go:377 +0x153 ws_logger_1 | github.com/gliderlabs/logspout/router.newContainerPump.func1(0x563922141b29, 0x6, 0x5639225e8820, 0xc420024008) ws_logger_1 | /go/src/github.com/gliderlabs/logspout/router/pump.go:362 +0x21f ws_logger_1 | created by github.com/gliderlabs/logspout/router.newContainerPump ws_logger_1 | /go/src/github.com/gliderlabs/logspout/router/pump.go:365 +0x158 scossensor_ws_logger_1 exited with code 2 

有人遇到过这种情况么? 我确信我错过了一些与NGINX有关的东西,但是我的智慧已经结束了。

UPDATE

最后得到修复(在NGINX conf):

 location /logs { proxy_pass http://ws-logger/logs; proxy_http_version 1.1; proxy_set_header Upgrade "websocket"; proxy_set_header Connection "upgrade"; 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-Proto https; proxy_read_timeout 86400; # neccessary to avoid websocket timeout disconnect proxy_redirect off; }