Vincent's Site

Deploying Django with uWSGI

Date: 2024-12-19
Category: Tutorial

I've been playing with Django recently, and as such I needed to look into deploying these sites. I picked uWSGI because it seemed like the easyest way to do so. 

Installing uWSGI

There are two ways you can install uWSGI: From source, and as a system package. The documentation recomends to start with the source distribution, as each distribution might use a slightly difirent layout for configuration, this is what I'll use.

First, download the latest version of uWSGI from the official site to a location on your server (for example /usr/src)

cd /usr/src
wget https://files.pythonhosted.org/packages/24/c2/d58480aadc9a1f420dd96fc43cf0dcd8cb5ededb95cab53743529c23b6cd/uwsgi-2.0.28.tar.gz
tar xzf uwsgi-2.0.28.tar.gz
cd uwsgi-2.0.28/

Next, we'll need to install some basic dependencies and run the compilation

sudo apt install build-essential python3-dev
make

The compilation will take about 30 seconds, and will produce a binary called uwsgi in the current directory. Copy uwsgi to /usr/local/bin.

cp uwsgi /usr/local/bin/

Creating the uWSGI service

Next, we need to to create a service file, I want to run multiple sites so I'll use uwsgi's emperor mode. Create the file /etc/systemd/system/emperor.uwsgi.service and place the following inside it:

[Unit]
Description=uWSGI Emperor

[Service]
ExecStart=/usr/local/bin/uwsgi --ini /etc/uwsgi/emperor.ini
RuntimeDirectory=uwsgi
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all

[Install]
WantedBy=multi-user.target

Next, create the directory to house the configuration files

mkdir -p /etc/uwsgi/vassals

create /etc/uwsgi/emperor.ini and place the following content inside it

[uwsgi]
emperor = /etc/uwsgi/vassals

Where uid/gid are the uid/gid of the user you want to run your apps as.

Next, create the file for your app, for example /etc/uwsgi/vassals/vincent-blog.ini:

[uwsgi]
chdir=/var/www/vincent-blog/
module=mysite.wsgi:application
socket=/run/uwsgi-vincent-blog.sock
workers=2
harakiri=30
max-requests=5000
vacuum=true
home=/var/www/vincent-blog/.venv
uid=vincent
gid=vincent
chown-socket=www-data:www-data

Configuring our webserver

Nginx

With Nginx, you only need to add the following to your server block

location /media/ {
    root /path/to/media
}

location /static/ {
    root /path/to/static
}

location / {
    uwsgi_pass unix:///run/uwsgi-vincent-blog.sock;
    include uwsgi_params;
}

Apache

In Apache, you can enable mod_proxy and mod_proxy_uwsgi like so:

sudo a2enmod proxy proxy_uwsgi

Then add the following to your vhost

        # ... 
        Alias /static /var/www/vincent-blog/staticfiles
        Alias /media /var/www/vincent-blog/media

        ProxyPass "/static" !
        ProxyPass "/media" !
        ProxyPreserveHost On
        ProxyPass "/" "unix:/run/uwsgi-vincent-blog.sock|uwsgi://localhost:3030/"
        # ...

Then restart apache and your site should be up.

Previous post