uwsgi

Basic testing

apt install uwsgi uwsgi-plugin-python python-django apache2 libapache2-mod-proxy-uwsgi

# Simple app with direct http server
cat <<'EOF' >> test.py
def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    #return [b"Hello World"] # python3
    return ["Hello World"] # python2
EOF
uwsgi_python27 --http-socket :8000 --wsgi-file test.py
sensible-browser http://localhost:8000/

# Django app with direct http server
django-admin startproject mysite
cd mysite/
echo "ALLOWED_HOSTS = ['*']" >> mysite/settings.py
./manage.py migrate
./manage.py createsuperuser
uwsgi_python27 --http-socket :8000 --module mysite.wsgi
sensible-browser http://localhost:8000/

# Django app with uwsgi server
a2enmod proxy proxy_uwsgi
$EDITOR /etc/apache2/sites-available/000-default.conf
# ProxyPass /uwsgi-pp uwsgi://localhost:8001/
# ProxyPass /uwsgi-pps/ uwsgi://localhost:8001/
# ProxyPassMatch ^/admin uwsgi://localhost:8001/

# Alias /static /usr/share/python-django-common/django/contrib/admin/static/
service apache2 restart
uwsgi_python27 --socket :8001 --module mysite.wsgi
sensible-browser http://localhost/uwsgi-pp
sensible-browser http://localhost/uwsgi-pps/
sensible-browser http://localhost/admin

For reference / behavior comparison, bookworm config differences:

apt install uwsgi-plugin-python3

uwsgi_python3 --socket :8001 --module mysite.wsgi

Alias /static /usr/lib/python3/dist-packages/django/contrib/admin/static/
<Directory /usr/lib/python3/dist-packages/django/contrib/admin/static/>
  Require all granted
</Directory>

See also https://uwsgi.readthedocs.io/en/latest/tutorials/Django_and_nginx.html

Copyright (C) 2021 Sylvain Beucler