Deploy django-channels with Apache2 and Daphne - django

I'm trying to learn to use django-channels and have worked through both the tutorial and this multichat example. I am now trying to deploy it on a Digital Ocean droplet using Apache and Daphne. I would happily use Daphne by itself but I do not understand how to.
So this is my Apache conf file:
<VirtualHost *:80>
ServerAdmin webmaster#mysite.co.uk
ServerName multichat.mysite.co.uk
ServerAlias www.multichat.mysite.co.uk
DocumentRoot /var/www/multichat
WSGIDaemonProcess multichat python-path=/var/www/multichat python-home=/var/www/multichat/env
WSGIProcessGroup multichat
WSGIScriptAlias / /var/www/multichat/multichat/wsgi.py
Alias /robots.txt /var/www/multichat/static/robots.txt
Alias /favicon.ico /var/www/multichat/static/favicon.ico
Alias /media/ /var/www/multichat/media/
Alias /static/ /var/www/multichat/static/
<Directory /var/www/multichat/static>
Require all granted
</Directory>
<Directory /var/www/multichat/media>
Require all granted
</Directory>
WSGIScriptAlias / /var/www/multichat/multichat/wsgi.py
<Directory /var/www/multichat/multichat>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
I've installed Redis and have it up and running.
I've included this file in /etc/systemd/system/daphne.service
[Unit]
Description=daphne daemon for multichat
After=network.target
[Service]
User=root
Group=www-data
WorkingDirectory=/var/www/multichat/multichat
ExecStart=/var/www/multichat/env/bin/daphne -b 0.0.0.0 -p 8001 multichat.asgi:application
# Not sure if should use 'on-failure' or 'always'.
Restart=on-failure
[Install]
WantedBy=multi-user.target
Although the webpage comes up and I can login etc, when it comes to a chatroom I have the following error in console:
WebSocket connection to 'ws://multichat.mysite.co.uk/chat/stream/'
failed: Error during WebSocket handshake: Unexpected response code:
404
I'm clearly not setting up something correctly but I don't know where to turn. I would happily scrape Apache if I can get a pointer on how to use just Daphne, but I've tried and got nowhere with that either

You've configured Apache to serve Django content using WSGI protocol, but WSGI doesn't support web sockets. That is why Daphne is here. It doesn't use WSGI to serve Django content, so you can use it with web sockets.
To use Daphne instead, you should remove WSGI settings from apache file and put ProxyPass instead, which should point to your daphne server. The proper line should look like this:
<Location />
ProxyPass http://127.0.0.1:8001/
</Location>
As your daphne server is running on the same server, but on port 8001.

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]
<Location />
ProxyPass http://127.0.0.1:8001/
</Location>
#And load the next modules in the main file config:
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_module modules/mod_proxy.so
#remove WSGI settings

Related

What could be wrong with this virtual host file in Apache?

I am trying to route an application to a sub route on an internal server, using Gunicorn with my Django app. My virtual host file looks like this:
LoadModule proxy_module /usr/lib64/apache2/mod_proxy.so
LoadModule proxy_http_module /usr/lib64/apache2/mod_proxy_http.so
<VirtualHost *:80>
ServerName 172.16.1.81
<Location "/mycustomapp">
ProxyPreserveHost On
ProxyPass http://127.0.0.1:9090
ProxyPassReverse http://127.0.0.1:9090
</Location>
</VirtualHost>
When I navigate to 172.16.1.81/mycustomapp , I keep getting a 404 not found error when trying to navigate to the application on that route. Is there something else I am doing wrong here?
Okay, I figured it out. For anyone running into this type of problem in the future, the solution lies in using the ServerPath directive inside your VirtualHost configuration. So for example, if you wanted to have an application be served at 172.15.1.20/app1 and another application served at 172.15.1.20/app2 (via port forwarding to a process listening on a port) the virtual host configuration would like the following:
LoadModule proxy_module /usr/lib64/apache2/mod_proxy.so
LoadModule proxy_http_module /usr/lib64/apache2/mod_proxy_http.so
<VirtualHost *:80>
ServerName 172.15.1.20
ProxyPreserveHost On
ProxyPass /app1 http://127.0.0.1:9090
ProxyPassReverse /app1 http://127.0.0.1:9090
ProxyPass /app2 http://127.0.0.1:9080
ProxyPassReverse /app2 http://127.0.0.1:9080
</VirtualHost>

Django Elasticbeanstalk Application returns 404 during autoscale

I have a django application running on elastic beanstalk. The application deploys and works fine when I deploy from the command line.
However, during an autoscale, healthcheck on the new instance created always return 404 from the access_logs.
"GET /health/ HTTP/1.1" 404 221 "-" "ELB-HealthChecker/1.0"
Interestingly, the application eventually loads after about 20 minutes.
See my wsgi.conf file below.
Is there something I am doing wrong?
LoadModule wsgi_module modules/mod_wsgi.so
WSGIPythonHome /opt/python/run/baselinenv
WSGISocketPrefix run/wsgi
WSGIRestrictEmbedded On
<VirtualHost *:80>
Alias /static/ /opt/python/current/app/staticfiles/
<Directory /opt/python/current/app/staticfiles/>
Require all granted
</Directory>
WSGIScriptAlias / /opt/python/current/app/myapp/wsgi.py
<Directory /opt/python/current/app/>
Require all granted
</Directory>
Header always set Access-Control-Allow-Methods "POST,GET,OPTIONS,PUT,DELETE, PATCH"
Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, Accept, origin, authorization, accept, client-security-token, Authorization"
WSGIDaemonProcess wsgi processes=3 threads=20 display-name=%{GROUP} \
python-path=/opt/python/current/app:/opt/python/run/venv/lib/python2.7/site-packages:/opt/python/run/venv/lib64/python2.7/site-packages user=wsgi group=wsgi \
home=/opt/python/current/app
WSGIProcessGroup wsgi
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule !/api/v1.0/church/health/ https://%{SERVER_NAME}%{REQUEST_URI} [L,R=301]
</VirtualHost>
WSGIPassAuthorization On
I have the check of the health just for production and the url I use is the /login
Have a look in configuration>health in your EBT dashboard.
I have the suspect that your url /health is not managed by django.

IP based host not working on apache2

I am trying to run my Python Flask backend on apache2. My conf file looks like this:
<virtualhost 192.168.11.11:80>
ServerName travelhook
WSGIDaemonProcess travelhook group=www-data threads=5
WSGIScriptAlias / /var/www/TravelHookBE/travelhookBE.wsgi
<directory /var/www/TravelHookBE>
WSGIProcessGroup travelhook
WSGIApplicationGroup %{GLOBAL}
WSGIScriptReloading On
Order deny,allow
Allow from all
</directory>
</virtualhost>
But when i use 192.168.11.11:80 in my browser it doesn't work. I am running it on Ubuntu from the browser on the same machine

mod_wsgi apache and django configuration not working

*Using Django 1.5, mod_WSGI 3.3 and Apache 2.2*
The Mod_WSGI module has been successfully installed into Apache.
I have also created a very basic project using django-admin.py called "check"
So now according to the Django Documentation on how to configure mod_wsgi
I have entered the following code into the Apache httpd.conf where it looks like this -
<VirtualHost 192.254.132.95:80>
ServerName bangtestwsgi.mbox140.com
ServerAlias www.bangtestwsgi.mbox140.com
DocumentRoot /home/bangwsgi/public_html
ServerAdmin webmaster#bangtestwsgi.mbox140.com
UseCanonicalName Off
CustomLog /usr/local/apache/domlogs/bangtestwsgi.mbox140.com combined
CustomLog /usr/local/apache/domlogs/bangtestwsgi.mbox140.com-bytes_log "%{%s}t %I .\n%{%s}t %O ."
## User bangwsgi # Needed for Cpanel::ApacheConf
UserDir enabled bangwsgi
<IfModule mod_suphp.c>
suPHP_UserGroup bangwsgi bangwsgi
</IfModule>
<IfModule !mod_disable_suexec.c>
<IfModule !mod_ruid2.c>
SuexecUserGroup bangwsgi bangwsgi
</IfModule>
</IfModule>
WSGIScriptAlias / /home/bangwsgi/check/check/wsgi.py
WSGIPythonPath /home/bangwsgi/check
<Directory /home/bangwsgi/check/check>
<Files wsgi.py>
Order deny,allow
Require all granted
</Files>
</Directory>
</VirtualHost>
Currently my DNS hasn't propagated so I am using 192.254.132.95/~bangwsgi/ to access the app (as told to me by Hostgator)
The thing is that nothing is happening. There is nothing in the Apache error log. There seems to be sign that the wsgi script is even running. Can someone tell me what I can do differently to make this work?
I'm not sure why you are going to /~bangwsgi/. Your WSGI app is being served at /, as defined by the first parameter to WSGIScriptAlias.
It works on removing the line
WSGIPythonPath /home/bangwsgi/check
And changing Require all granted
to Allow from all

Deploying a Django app on Apache + mod_wsgi with HTTP auth

Is it possible to deploy a Django app on Apache + mod_wsgi (the standard way) but with HTTP authentication in front of the whole thing?
Basically, I need an extra layer of HTTP security before any user, Django-authenticated or anonymous, is even able to reach the app.
Is this possible? If so, where do the Apache auth directives go?
Yes, it's possible.
With mod_wsgi on /, any resources to be provided by apache need to be listed as aliases.
Auth directives and host restrictions live in Location directives.
So I've disabled any apache access restrictions on things like css, and provided host/ip based access to another directory.
<VirtualHost *:80>
Servername app.domain.example
CustomLog logs/access_log combined
ErrorLog logs/error_log
DocumentRoot "/home/app/apache/app/html"
Alias /media/ /home/app/apache/app/html/media/
<Location />
Options None
AuthType Basic
AuthName "Login Prompt"
AuthUserFile /path/to/passwd.file
Require valid-user
</Location>
<Location /media>
Order allow,deny
Allow from all
Satisfy any
</Location>
WSGIDaemonProcess app user=app group=app processes=5 threads=1 display-name=app_WSGI
WSGIProcessGroup app
WSGIScriptAlias / /home/app/apache/app.wsgi
</VirtualHost>
Sure, here is example from one site:
<VirtualHost *:80>
ServerName djangoproject.domain.biz
DocumentRoot "/home/user/websites/djangoproject/website/"
WSGIDaemonProcess djangoproject python-path=/home/user/.virtualenvs/djangoproject/lib/python2
.6/site-packages/ user=user group=user threads=1
WSGIProcessGroup djangoproject
WSGIScriptAlias / /home/user/websites/djangoproject/website/django.wsgi
<Directory "/home/user/websites/djangoproject/website/">
Order deny,allow
Allow from all
AuthType Basic
AuthName "By Invitation Only"
AuthUserFile /etc/apache2/passwords
Require valid-user
</Directory>
</VirtualHost>