HTTP_SEC_WEBSOCKET_KEY
Good evening!
I'm currently trying to integrate websockets into my django app. I'm using nginx to proxy my client side requests to the uWSGIWebsocketServer. I've been following your guide here with setting up two different uWSGI instances: https://django-websocket-redis.readthedocs.org/en/latest/running.html#django-with-websockets-for-redis-behind-nginx-using-uwsgi. Currently, my setup works fine locally: I can connect successfully and receive messages. However, when I try to deploy my site on docker, I can't connect at all and get a 500 error saying that the HTTP_SEC_WEBSOCKET_KEY isn't set in environ here:
https://github.com/jrief/django-websocket-redis/blob/master/ws4redis/uwsgi_runserver.py#L52. All of my processes are running and I can hit my site fine, I just can't connect with websockets.
I've checked and can see that when trying to connect to my docker container, the Sec-Websocket-Key is set in the request header and the request looks almost identical to the local one. The only difference is that nginx is version 1.6.8 on my docker image vs 1.8.0 on my local machine. This shouldn't be an issue though since websockets have been supported since 1.3. I'm really not sure what's happening so I was wondering if you have any ideas. Here are my relevant files:
nginx.conf:
daemon off;
error_log /dev/stdout info;
user root;
worker_processes 2;
worker_rlimit_nofile 100000;
events {
worker_connections 50000;
accept_mutex off;
}
http {
access_log off;
sendfile on;
server {
listen 80;
server_name _;
charset utf-8;
include /etc/nginx/mime.types;
root /srv/site/;
# max upload size
client_max_body_size 75M; # adjust
location / {
include /etc/nginx/uwsgi_params.default;
proxy_pass http://localhost:8000;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host:$server_port;
proxy_redirect off;
proxy_buffering off;
proxy_read_timeout 600s;
gzip on;
gzip_http_version 1.0;
gzip_comp_level 5;
gzip_min_length 256;
gzip_disable "MSIE [1-6]\.";
gzip_types application/atom+xml
application/javascript
application/json
application/ld+json
application/manifest+json
application/rss+xml
application/vnd.geo+json
application/vnd.ms-fontobject
application/x-font-ttf
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
font/opentype
image/bmp
image/svg+xml
image/x-icon
text/cache-manifest
text/css
text/plain
text/vcard
text/vnd.rim.location.xloc
text/vtt
text/x-component
text/x-cross-domain-policy;
}
location /ws/ {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_pass http://localhost:8001;
}
}
}
websocket ini file:
[uwsgi]
umask = 002
chdir = /srv/site/
pythonpath = server/
module = base.wsgi_websocket:application
no-orphans = true
die-on-term = true
memory-report = true
http-socket = 0.0.0.0:8001
http-websockets = true
gevent = 1000
threads = 1
processes = 1
master = true
Dockerfile:
FROM centos:latest
RUN yum -y update
RUN yum group install -y "Development Tools"
RUN yum install -y epel-release
RUN yum -y install supervisor nginx python-devel python-setuptools postgresql-devel ncurses-devel
RUN easy_install pip
ADD . /srv/site
WORKDIR /srv/site
ADD scripts/assets/requirements.txt /srv/site/scripts/assets/requirements.txt
RUN pip install -r scripts/assets/requirements.txt
RUN pip install uwsgi
WORKDIR /srv/site
EXPOSE 80
CMD ["/usr/bin/supervisord", "-c", "/srv/site/deploy/supervisord.conf"]
supervisord.conf
[supervisord]
nodaemon = true
[program:nginx]
user=root
command = /usr/sbin/nginx -p /srv/site/deploy/ -c /srv/site/deploy/nginx.conf
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
[program:app-site]
command = /usr/bin/uwsgi --ini /srv/site/deploy/webserver.ini
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
[program:app-websockets]
command = /usr/bin/uwsgi --ini /srv/site/deploy/websocket.ini
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
Looking forward to hearing back!
Are you developing on Linux or do you use boot2docker? In the latter case, this could be an issue because of some NAT/Bridging stuff.
I use docker machine (the newer, officially supported version of boot2docker). Do you have any suggestions on how to inspect the NAT/bridge configurations?
Its about a year, since I used Docker the last time. I believe that you can access the VM guest, which runs the real Docker containers. However without having hand on your environment, its rather difficult to give advice.
BTW, why do you use supervisor to spawn uwsgi and nginx? uwsgi can be used in emperor mode for this job. Also, I don't see where you start the Redis daemon on your Docker guest.
I am currently facing a similar issue. Locally, I am able to connect to the websocket and exchange messages, but when I try toi deploy it to a vm I get this:
Traceback (most recent call last): File "/home/minus/minus_env/local/lib/python2.7/site-packages/ws4redis/wsgi_server.py", line 113, in __call__ websocket = self.upgrade_websocket(environ, start_response) File "/home/minus/minus_env/local/lib/python2.7/site-packages/ws4redis/uwsgi_runserver.py", line 52, in upgrade_websocket uwsgi.websocket_handshake(environ['HTTP_SEC_WEBSOCKET_KEY'], environ.get('HTTP_ORIGIN', '')) IOError: unable to complete websocket handshake Starting late response on websocket Finish non-websocket response with status code: 500 [pid: 1516|app: 0|req: 1/2] 0.0.0.0 () {44 vars in 905 bytes} [Thu Oct 5 12:01:27 2017] GET /ws/live-score?subscribe-broadcast&publish-broadcast&echo => generated 38 bytes in 6 msecs (HTTP/1.1 500) 1 headers in 78 bytes (3 switches on core 999)
Nginx: version - 1.4.6
location /ws/ { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_pass http://unix:/home/minus/home-screen/uwsgi_socket.sock; }
Uwsgi: version - 2.0.14 `[uwsgi]
virtualenv = /home/minus/minus_env/ chdir = /home/minus/home-screen/ http-socket = /home/minus/home-screen/uwsgi_socket.sock chmod-socket = 664 gevent = 1000 http-websockets = true workers = 2 master = true module = minus.websocket_wsgi:application`
Any idea, what's wrong?