• questa e' una vecchia guida scritta attorno al 2018, quando usavo Django da appena qualche mese;
  • la guida spiega l'installazione diretta del progetto sulla macchina. In futuro, forse, scrivero' la versione con Docker;
  • anche se installi direttamente sulla macchina, meglio evitare l'interprete Python di sistema: usa un ambiente virtuale;
  • la guida e' pensata per far capire il processo in modo semplice, non per un deploy in un ambiente professionale;
  • non e' una guida esaustiva, soprattutto per ambienti di produzione pubblici o ad alto traffico.

Installare Nginx

Come prima cosa, installare il web server Nginx sulla macchina:

sudo apt-get update
sudo apt-get install nginx

Una volta installato, verificare che stia girando correttamente:

sudo systemctl status nginx

Se sta girando correttamente, aprire una pagina in incognito e visitare http://<ip della tua VPS>.

Creare un percorso sul server dove poter mettere un file personalizzato da far servire al virtual host di Nginx:

sudo mkdir -p /var/www/example.com/html
sudo chown -R $USER:$USER /var/www/example.com/html
sudo chmod -R 755 /var/www
cd /var/www/example.com/html
nano index.html

Creare il server block

Procedere con la creazione del primo file per il server block:

sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/example.com

Svuotare il file e scrivere una configurazione come questa:

server {
    listen 80;
    listen [::]:80;

    root /var/www/example.com/html;
    index index.html index.htm index.nginx-debian.html;

    server_name example.com www.example.com;

    location / {
        try_files $uri $uri/ =404;
    }
}

Abilitare il nuovo server block di Nginx:

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/

Aprire il file di configurazione principale di Nginx:

sudo nano /etc/nginx/nginx.conf

Aggiungere alla configurazione un parametro per evitare problemi futuri riguardanti i server blocks:

http {
    ...
    server_names_hash_bucket_size 64;
    ...
}

Controllare che non ci siano errori di sintassi nei file di configurazione e riavviare il web server:

sudo nginx -t
sudo systemctl restart nginx

HTTPS con Certbot

Installare Certbot:

sudo add-apt-repository ppa:certbot/certbot
sudo apt install python-certbot-nginx

Certbot richiede che sia configurato un server block con una direttiva server_name:

server_name example.com www.example.com;

A questo punto utilizzare Certbot per creare i certificati per i domini specificati:

sudo certbot --nginx -d example.com -d www.example.com

Il software si occupera' anche di aggiungere uno script di rinnovo. E' possibile testarlo con:

sudo certbot renew --dry-run

Infine riavviare Nginx:

sudo systemctl restart nginx

Database e progetto Django

Installare il necessario:

sudo apt-get install python3-dev libmysqlclient-dev mysql-server
pip install mysqlclient

Accertarsi che MySQL stia girando in modo corretto:

sudo systemctl status mysql.service

Entrare nel terminale MySQL, creare un nuovo database e creare un utente con tutti i permessi:

CREATE DATABASE progetto_db;
GRANT ALL
ON progetto_db.*
TO 'utente_db'@'localhost'
IDENTIFIED BY '1234567';

Configurare il progetto per usare il database appena creato:

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.mysql",
        "OPTIONS": {
            "read_default_file": "/etc/mysql/progetto.cnf",
        },
    }
}

Creare il file di configurazione:

sudo nano /etc/mysql/progetto.cnf

Scrivere i parametri necessari:

[client]
database = progetto_db
user = utente_db
password = 1234567
default-character-set = utf8

Riavviare MySQL e provare il progetto:

sudo systemctl daemon-reload
sudo systemctl restart mysql
python manage.py makemigrations
python manage.py migrate
python manage.py runserver 0.0.0.0:8010

Aggiustare gli host consentiti e definire dove collezionare i file statici:

ALLOWED_HOSTS = ["dominio_o_ip"]
STATIC_ROOT = os.path.join(BASE_DIR, "static/")

Collezionare tutti i file statici:

python manage.py collectstatic

Accertarsi che Gunicorn sia in grado di servire il progetto:

gunicorn --bind 0.0.0.0:8000 progetto.wsgi

Systemd e Gunicorn

Creare il file systemd:

sudo nano /etc/systemd/system/progetto.service

Inserire una configurazione di questo tipo:

[Unit]
Description=Progetto
After=network.target

[Service]
User=utente
Group=www-data
WorkingDirectory=/directory/del/progetto
ExecStart=gunicorn --access-logfile - --workers 3 --bind unix:/home/utente/progetto/progetto.sock progetto.wsgi:application

[Install]
WantedBy=multi-user.target

Abilitare il processo e avviarlo:

sudo systemctl daemon-reload
sudo systemctl start progetto
sudo systemctl enable progetto
sudo systemctl status progetto

Per vedere l'output del progetto:

sudo journalctl -b -u progetto

Ogni volta che il progetto verra' modificato sara' necessario effettuare un restart:

sudo systemctl restart progetto

Configurare Nginx per Gunicorn

Nel server block del sito inserire una configurazione di questo tipo:

location /static/ {
    alias /path/to/staticfiles/here/;
}

location / {
    include proxy_params;
    proxy_pass http://unix:/home/utente/progetto/progetto.sock;
}

Infine riavviare Nginx:

sudo nginx -t
sudo systemctl restart nginx

Visto che l'app e' online ed esposta al pubblico, esegui anche la deployment checklist di Django.