Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deploy django channels with Apache and Daphne?

I am trying to deploy this django app which uses channels. I use Apache for regular HTTP requests and want to forward the web socket requests to Daphne.

Here are some of my important files:

apache config:

<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC,OR]
RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC]
RewriteRule .* ws://127.0.0.1:8001%{REQUEST_URI} [P,QSA,L]

Alias /static /home/user/mock/static
<Directory /home/user/mock/static>
Require all granted
</Directory>

Alias /media /home/user/mock/media
<Directory /home/user/mock/media>
Require all granted
</Directory>

<Directory /home/user/mock/mock>
<Files wsgi.py>
Require all granted
</Files>
</Directory>

WSGIScriptAlias / /home/user/mock/mock/wsgi.py
WSGIDaemonProcess django_app python-path=/home/user/mock python-home=/home/mock/mock/venv
WSGIProcessGroup django_app

</VirtualHost>

Last few lines of settings.py:

ASGI_APPLICATION = 'mock.routing.application'

CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [('127.0.0.1', 8001)],
},
},
}

asgi.py

import os
import django
from channels.routing import get_default_application

from django.core.asgi import get_asgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mock.settings')
django.setup()
application = get_default_application()

With these in place, I run daphne -p 8001 mock.asgi:application and then sudo service apache2 reload. Finally, when testing the websocket in my page here's what happens:

websocket.js:4 WebSocket connection to 'ws://192.168.0.57/ws/chat/8/' failed: Error during WebSocket handshake: Unexpected response code: 403

This error 403 happens whether or not I'm running daphne.

What am I doing wrong here? Note: the app works as expected when using Django's development server and docker for the channel layer, the problem is with my Apache config, I think.

like image 929
dhsdshdhk Avatar asked Sep 11 '25 03:09

dhsdshdhk


2 Answers

I figured it out. To enable apache to redirect, we need to:

sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_wstunnel

One of these was not enabled which caused the 403 Forbidden.

like image 78
dhsdshdhk Avatar answered Sep 12 '25 20:09

dhsdshdhk


  1. Add this string in your virtualhost:

    ProxyPass /ws ws://localhost:8000/path/to/websocket
    ProxyPassReverse /ws ws://localhost:8000/path/to/websocket
    
  2. Add this string to Apache http.conf:

    LoadModule proxy_wstunnel_module 
    modules/mod_proxy_wstunnel.so
    
  3. Run django python.manage.py runserver

  4. JavaScript code:

    new WebSocket('wss://you.url.com/ws');
    

This works in my project.

like image 38
Anuar Bibulatov Avatar answered Sep 12 '25 21:09

Anuar Bibulatov