This talk explains how to install and setup multiple Django applications on a single server.
The general principle is to setup a systend service for each application that runs in nginx and gunicorn on Ubunto 20 LTS. This results in a lightweight installation that requires only a few and small configuration files that is well integrated in the existing tool chain around systemd.
2. Goals
●
A Django application runs on a Ubuntu 20 LTS.
●
The application automatically starts on reboot.
●
The application can be controlled with systemctl.
●
Web content is served using the lightweight nginx server
(no Apache2 bloat).
●
The application uses HTTPS with its own (free) certificate.
●
Multiple applications can run on the same physical server.
3. Advantages
Pros
●
Works with Ubuntu 20 LTS
standard packages
●
Minimal intrusion
●
Minimal resource overhead
●
Transparent and relatively
easy to understand
Cons
●
You need to build something
for deployment yourself
(script with ssh/scp, git
pull, ...)
●
Doesn’t make you feel as
powerful as container
orchestration approaches.
4. Example
We want a Django application that:
●
Has the application code stored in
/var/www/<environment>/example/ with <environment> being
test, stage, production, ...
●
Can be accessed using the domain www.example.com
●
Uses HTTPS with its own free certificate
●
Redirects HTTP to HTTPS
5. Install required packages
●
Upgrade to current packages:
sudo apt-get -y upgrade
●
Install nginx, python3 and certbot:
sudo apt-get -y install certbot python3-certbot-nginx
(Note: The dependencies ensure that nginx and python3 are
installed with this automatically.)
6. Setup additional directories
●
Assumption: For now, we want to setup the example application in
the test environment.
→ The application will reside in /var/www/test/example/
●
For a simple installation, you can choose to serve static and media
files via nginx → Create the required directories:
sudo mkdir -p "/var/www/test/example/media"
sudo mkdir -p "/var/www/test/example/static"
7. Install your Django application
●
Copy your code to /var/www/test/example/
●
Set up a virtual environment using whatever venv tool is in fashion,
for example:
sudo apt-get -y install python3-venv
cd /var/www/test/example/
sudo python3 -m venv venv
. venv/bin/activate
●
Install dependent python packages, including gunicorn
8. Service architecture
nginx gunicorn
Django
application
Socket WSGI
●
WSGI: “Web Server Gateway Interface”, to forward requests to web services written in
Python
●
gunicorn: Python WSGI HTTP Server for UNIX; “simply implemented, light on server
resources, and fairly speedy”
11. /etc/systemd/system/example.service
[Unit]
Description=gunicorn daemon for example
Requires=example.socket
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/test/example
ExecStart=/var/www/test/example/venv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/example.sock example.wsgi:application
[Install]
WantedBy=multi-user.target
Change to as many
processes as needed.
Standard user
for web service
Wait for socket
service from before.
gunicorn in venv
from before
13. /etc/nginx/sites-available/www.example.com
server {
listen 80;
server_name www.example.com;
location = /favicon.ico {
access_log off;
log_not_found off;
}
location /static/ {
root /var/www/test/example;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/example.sock;
}
} socket service
from before.
Our domain
For now, use
plain HTTP
Serve static files
14. Activate nginx configuration
●
Activation is done by linking the enabled configuration to the
available one:
sudo ln -s /etc/nginx/sites-available/www.example.com
/etc/nginx/sites-enabled
●
Because this is a link and not a copy, changes in the available
configuration also reflect on the enabled one.
●
After changes restart nginx:
sudo systemctl restart nginx
15. Common tasks
●
Restart the service (e.g. after deployment)
sudo systemctl daemon-reload
sudo systemctl restart example
●
Analyze possible errors when starting the application:
sudo journalctl -u example
●
Analyze log files:
sudo tail -f /var/log/nginx/error.log
sudo tail -f /var/log/nginx/access.log
16. Easy mode for most files
●
nubops from https://github.com/roskakori/nubops
(from gamer slang: nub → noob → newbie)
●
Generate most of the files by running:
sudo nubops nginx-django test example www.example.com
●
Available on PyPI soon.