Trying to get Django running in a vhost

Hi, I’m having no luck getting Django to work in a virtual host on a Linux server (Apache 2.4.62 / Debian 12 / Django 5.1.5; all freshly installed). I’ve followed various online guides, but nothing seems to work properly.

One thing that strikes me as slightly odd is that although running django-admin startproject web on the command line always creates nested directories both called web, the official documentation on using Django with Apache doesn’t seem to acknowledge this at all. Should I perhaps be creating Django projects some other way?

I’ve set WSGScriptAlias to web/web/wsgi.py in the Apache config file. I replaced the contents of this file with the hello world application from the mod_wsgi documentation, it works just fine. But with the actual wsgi.py file, I just get a 500 Internal Server Error page and a note in the log file that says ModuleNotFoundError: No module named ‘web’.

Can anyone see where I’m going wrong here? I’ve tried juggling the directory structure and config files, but nothing works.

This is how files are currently arranged at the vhost root (/var/www/sites/example.com):

.
├── env
│   ├── bin
│   │   ├── activate
│   │   ├── activate.csh
│   │   ├── activate.fish
│   │   ├── Activate.ps1
│   │   ├── django-admin
│   │   ├── pip
│   │   ├── pip3
│   │   ├── pip3.11
│   │   ├── python -> python3
│   │   ├── python3 -> /usr/bin/python3
│   │   ├── python3.11 -> python3
│   │   └── sqlformat
│   ├── include
│   │   └── python3.11
│   ├── lib
│   │   └── python3.11
│   ├── lib64 -> lib
│   └── pyvenv.cfg
└── web
    ├── manage.py
    └── web
        ├── asgi.py
        ├── __init__.py
        ├── settings.py
        ├── urls.py
        └── wsgi.py

The Apache conf file for this vhost looks like this:

<IfModule mod_ssl.c>
<VirtualHost *:443>

    ServerName example.com
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/sites/example.com/

    <Directory /var/www/sites/example.com>
        Require all granted
    </Directory>

    WSGIDaemonProcess example.com processes=2 threads=15 user=django_user group=www-data socket-user=#1001 python-path=/var/www/sites/example.com/env/bin python-home=/var/www/sites/example.com/env
    WSGIProcessGroup example.com

    WSGIScriptAlias / /var/www/sites/example.com/web/web/wsgi.py

    AssignUserID django_user www-data

    LogLevel info ssl:warn
    ErrorLog ${APACHE_LOG_DIR}/example.com.error.log
    CustomLog ${APACHE_LOG_DIR}/example.com.access.log combined

SSLCertificateFile /etc/letsencrypt/live/myserver.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/myserver.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

Never mind, I seem to have got something working at last!

Looks like the main problem was with the WSGIDaemonProcess directive, which was wrong in various ways. I’ll put the Apache conf file and directory tree here for reference in case anyone else might find it useful. I also needed to add the domain name to ALLOWED_HOSTS in settings.py, and there are no doubt several other things I need to sort out. But I think I’m back on track here :smiley:

Apache vhost configuration file:

<IfModule mod_ssl.c>
<VirtualHost *:443>

    ServerName example.com
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/sites/example.com/web/web

    <Directory /var/www/sites/example.com>
        Require all granted
    </Directory>

    WSGIDaemonProcess example.com python-path=/var/www/sites/example.com/web:/var/www/sites/example.com/web/env/lib/python3.11/site-packages python-home=/var/www/sites/example.com/web/env
    WSGIProcessGroup example.com
    WSGIScriptAlias / /var/www/sites/example.com/web/web/wsgi.py
    AssignUserID django_user www-data
    LogLevel info ssl:warn

    ErrorLog ${APACHE_LOG_DIR}/example.com.error.log
    CustomLog ${APACHE_LOG_DIR}/example.com.access.log combined

SSLCertificateFile /etc/letsencrypt/live/myserver.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/myserver.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

Directory structure (/var/www/sites/example.com):

.
└── web
    ├── db.sqlite3
    ├── env
    │   ├── bin
    │   ├── include
    │   ├── lib
    │   ├── lib64 -> lib
    │   └── pyvenv.cfg
    ├── manage.py
    ├── static
    │   └── admin
    └── web
        ├── asgi.py
        ├── __init__.py
        ├── __pycache__
        ├── settings.py
        ├── urls.py
        └── wsgi.py