使用 SSL 使用 Daphne + NGINX 部署 Django 通道

Posted

技术标签:

【中文标题】使用 SSL 使用 Daphne + NGINX 部署 Django 通道【英文标题】:Deploying Django Channels with Daphne + NGINX using SSL 【发布时间】:2017-09-20 14:26:44 【问题描述】:

我有一个 nginx 代理到 django 频道的上游 daphne 服务器的工作配置。但是,当我将网站移至 ssl 时,我开始遇到 websocket 请求的问题 403 错误。这是来自我的错误日志:

None - - [24/Apr/2017:02:43:36] "WSCONNECTING /pulse_events" - -
None - - [24/Apr/2017:02:43:36] "WSREJECT /pulse_events" - -
2017/04/24 02:43:37 [info] 465#465: *10 client 69.203.115.135 closed keepalive 
connection

从访问日志中:

- - [24/Apr/2017:02:48:54 +0000] "GET /pulse_events HTTP/1.1" 403 5 "-" "-"
- - [24/Apr/2017:02:49:03 +0000] "GET /pulse_state/ HTTP/2.0" 200 1376 "-" "Pulse/1 CFNetwork/811.4.18 Darwin/16.1.0"

我的nginx配置如下:

upstream pulse_web_server 
    server unix:/home/pulseweb/run/gunicorn.sock fail_timeout=0;


upstream pulse_web_sockets 
   server unix:/home/pulseweb/run/daphne.sock;


map $http_upgrade $connection_upgrade 
     default upgrade;
     '' close;


server 
    listen 80;
    server_name backend.com;
    return 301 https://$host$request_uri;



server 
    listen         443 http2 ssl;
    server_name    backend.com;

    root /var/www/vhosts/backend.com;
  location ~ /.well-known 
       allow all;
  

  include snippets/ssl-params.conf;
  ssl_certificate /etc/letsencrypt/live/backend.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/backend.com/privkey.pem;



    client_max_body_size 4G;

    access_log  /var/log/nginx/pulse-access.log;
    error_log   /var/log/nginx/pulse-error.log info;

    location /static/ 
        alias /var/www/vhosts/backend.com/static/;
    

    location /pulse_events 
    proxy_pass http://pulse_web_sockets;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    

    location / 
      proxy_redirect off;
      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 $scheme;
      proxy_set_header Host $http_host;
      proxy_set_header X-NginX-Proxy true;
      proxy_set_header Connection "";
      proxy_http_version 1.1;
      server_tokens off;
      proxy_buffering on;
      if (!-f $request_filename) 
          proxy_pass http://pulse_web_server;
          break;
      
  

这是我的 requirements.txt:

asgi-redis==0.14.0
asgiref==0.14.0
asyncio==3.4.3
autobahn==0.16.0
channels==0.17.2
daphne==0.14.3
Django==1.10
django-extensions==1.7.2
django-webpack-loader==0.3.3
djangorestframework==3.4.4
msgpack-python==0.4.8
python-dateutil==2.5.3
redis==2.10.5
requests==2.11.0
six==1.10.0
Twisted==16.2.0
txaio==2.5.1
zope.interface==4.2.0

任何见解将不胜感激。

【问题讨论】:

你检查你的javascript中的方案吗? 嘿。你解决了吗? 你爱过吗?? 【参考方案1】:

我确实有 Django+Daphne+nginx+ssl 的工作配置,没有任何问题,我通过主管使用以下配置文件运行 daphne:

[program:project]

directory=<project_directory>
command=daphne -u <path_to_socket>/daphne.sock --root-path=<project_directory> <project>.asgi:channel_layer
stdout_logfile = <log_path>
stderr_logfile= <error_log_path>

[program:project_asgi_workers]

command=python <project_directory>/manage.py runworker
stdout_logfile=<log_file_path_2>
stderr_logfile=<log_error_path_2>
process_name=asgi_worker%(process_num)s
numprocs=2
environment=LANG=en_US.UTF-8,LC_ALL=en_US.UTF-8                        ; Set UTF-8 as default encoding
autostart=true
autorestart=true
redirect_stderr=true
stopasgroup=true

要停止和启动这些工作人员,我运行以下命令:

sudo supervisorctl stop all sudo supervisorctl start all

在 nginx 内部,我有以下配置可以连接到我的 websocket:

location /pulse_events/ 
    proxy_pass http://unix:<path_to_socket>/daphne.sock;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header 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;

我在这个项目中使用了 daphne 版本 1.4.1、asgi-redis 1.4.3、redis 2.10.6 和 channels 1.1.8。

如果你仍然有问题,也许检查你的路由和消费者的 django 频道也是一个好主意。

【讨论】:

您好先生,您对代码更改没有任何问题,如果您重新启动主管服务器仍然没有更新? 正好我在服务器DEBUG=True模式下忘记更新,然后立即设置为False。经过几次 supervisor/ngix 重启后,django 应用程序仍处于调试模式。 :// @Roel 恐怕我不明白你的问题,基本上当我对我的 Django 代码进行更改并想要重新部署它时,我重新启动主管、nginx 和 uwsgi 以让它们反映在那里,希望这对你有帮助。 我很抱歉,碰巧主管没有阅读 .env 所以它默认为开发设置而不是生产,这就是为什么我仍然得到一个调试模式站点。【参考方案2】:

您的 nginx 需要 wss 请求而不是 ws 请求。

【讨论】:

【参考方案3】:

我使用 Django + Daphne + Nginx + SSL,这是我的 nginx mysite.conf。您的 conf 文件因处理 /ws 请求而丢失。并且 ws 和 wss 将使用此参数进行处理。请确保你有一个像 Daphne 这样的后端套接字服务器(我知道你有),并在 bash 中运行这个服务器并接受 8443 中的请求(这很重要,因为大多数服务器只允许在这个套接字中)。并享受它..

location /ws 
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

proxy_pass http://127.0.0.1:8443;

【讨论】:

如何将 Daphe 作为服务运行?系统化?导师?我也很想看看那个配置文件

以上是关于使用 SSL 使用 Daphne + NGINX 部署 Django 通道的主要内容,如果未能解决你的问题,请参考以下文章

在 nginx 后面使用 Daphne

使用 nginx 和 daphne 部署 django、channels 和 websockets

使用 nginx、django、daphne 部署到 docker

使用 Daphne 和 Nginx 部署 django 频道的问题

Django 通道 websocket 连接和断开连接(Nginx + Daphne + Django + Channels)

带有 Daphne 的 Nginx 给出 502 Bad Gateway