Hosting a Django application with Apache’s mod_wsgi

  1. Install mod_wsgi: Obviously, this step depends on your package manager (which is usually determined by your distribution). On Arch Linux it goes something like this: sudo pacman -Sy mod_wsgi
  2. Adapt Apache’s configuration: In order to tell the Apache web server to interface with your Django WSGI app, a few directives need to be added to Apache’s configuration.
    Depending on how your distribution structures Apache’s configuration, there are places where it would make more or less sense to include the necessary directives. In my case, it made sense to include the WSGI directives inside the VirtualHost that should host my Django app:
# /etc/httpd/conf/httpd.conf
LoadModule wsgi_module modules/mod_wsgi.so
# /etc/httpd/conf/extra/httpd-vhosts.conf
<VirtualHost _default_:443>
    ServerName my_app.example.com

    # Make sure that wsgi.py can be accessed by the httpd process
    DocumentRoot /usr/share/webapps/my_app/my_app/
    <Directory /usr/share/webapps/my_app/my_app/>
        <Files wsgi.py>
            Require all granted
        </Files>
    </Directory>

    # Reference the app's WSGI script and define a WSGI daemon process group
    WSGIScriptAlias / /usr/share/webapps/my_app/my_app/wsgi.py
    WSGIDaemonProcess my_app.example.com python-home=/usr/share/webapps/my_app/venv python-path=/usr/share/webapps/my_app
    WSGIProcessGroup my_app.example.com

    # Serve the Django app's static files
    Alias /static /usr/share/webapps/my_app/static/
    <Directory /usr/share/webapps/my_app/static/>
        Require all granted
    </Directory>
</VirtualHost>
  1. Enable the right settings module: In case your Django app’s settings.py module deviates from the default location (such as when you manage your deployment environments via multiple settings modules), you need to adapt my_app/wsgi.py:
import os

from django.core.wsgi import get_wsgi_application

# Reference a non-standard settings module (e.g. your production settings)
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_app.settings.production")

application = get_wsgi_application()
  1. Allow requests to the app’s host system: Don’t forget to add the domain of the server you are deploying your Django app to to your ALLOWED_HOSTS list.
  2. Restart Apache: On a systemd host, you could use systemctl for that: sudo systemctl restart httpd
  3. Grab a cookie: Sometimes you have to treat yourself for your achievements.