Blog

gunicorn

Python e Django: deploy di un progetto con Nginx

Guide

Python e Django: deploy di un progetto con Nginx

Questa guida nasce con lo scopo di aiutare tutti coloro che vogliono rendere disponibile il loro sito, realizzato con Django, al pubblico.

Mettere in produzione un sito realizzato con Django non è difficile, anzi! Risulta comunque meno immediato rispetto all’host di qualche semplice file .php, questo va riconosciuto.

Il problema

Abbiamo realizzato il nostro sito con Python e Django sul nostro PC locale e adesso vorremmo renderlo disponibile al pubblico.

Quindi si parte da zero, punto di partenza: il progetto sul tuo PC!

La soluzione

L’unico requisito per proseguire in questa guida è conoscere le basi di Linux e del suo terminale: sarà necessario infatti connettersi tramite SSH a un Server Virtuale.

Iniziamo: come prima cosa dobbiamo acquistare un VPS (cos’è un VPS). Il prezzo di un VPS è generalmente basso, spesso si trovano a €2/3 al mese da provider come Aruba o OVH. Durante la procedura di acquisto e configurazione assicuriamoci di selezionare come sistema operativo Ubuntu Server.

Adesso dobbiamo acquistare un domino per il nostro sito web (cos’è un dominio). Anche in questo caso il prezzo è piuttosto basso (con Aruba per esempio troviamo offerte da €0.99 all’anno).

Dobbiamo inoltre “puntare” il nostro nuovo dominio all’indirizzo IP del nostro server: ecco un esempio di come farlo con Aruba. La procedura è comunque piuttosto simile con tutti i provider. Le modifiche ai DNS possono richiedere qualche ora per essere applicate.

A questo punto segui questa guida per configurare il Web Server sulla tua nuova VPS: configurare Nginx su VPS.

Adesso segui anche quest’altra guida per abilitare l’HTTPS sul tuo sito: HTTPS con Nginx.

Bene, hai tutto quello che ti occorre per proseguire.

Copia il tuo progetto nel tuo VPS, nella directory che preferisci.

Ricordati anche di creare un ambiente virtuale Python per il tuo progetto:

sudo pip3 install virtualenv
virtualenv -p python3 venv

Adesso dobbiamo installare e configurare il database per il nostro progetto. In generale, in produzione, è meglio evitare di utilizzare il SQLite (database di Django predefinito).

In questa guida procederemo con la configurazione di MySQL: rechiamoci nella directory dove abbiamo posizionato il nostro progetto e il nostro ambiente virtuale poi installiamo il necessario:

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

Assicuriamoci che il MySQL sia correttamente in funzione:

sudo systemctl status mysql.service

Bene, è arrivato il momento di entrare nel MySQL e creare l’utente e il database per il nostro progetto:

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

Non rimane che configurare il database anche all’interno del nostro progetto Django: andiamo nel settings.py del nostro progetto e sostituiamo la configurazione del database corrente con quella di seguito:

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

Come vedi nella configurazione si fa riferimento a un file di configurazione: “/etc/mysql/progetto.cnf“.

Andiamo quindi a creare il file:

sudo nano /etc/mysql/progetto.cnf

All’interno del file scriviamo la seguente configurazione:

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

Andiamo ad applicare tutte le configurazioni:

sudo systemctl restart mysql
venv/bin/python progetto/manage.py makemigrations
venv/bin/python progetto/manage.py migrate

Avviamo anche il progetto per assicurarci che non si siano errori:

venv/bin/python progetto/manage.py runserver 0.0.0.0:8010

Se non sono presenti errori apriamo il browser del nostro PC e andiamo al seguente indirizzo: “IP_DEL_SERVER:8010”. Dovresti vedere il tuo sito!

Adesso che abbiamo provato la corretta esecuzione del codice Python non rimane che configurare il progetto per girare dietro Web Server e terminare quindi il deploy.

Modifichiamo le seguenti variabili nel settings.py come mostrato di seguito:

ALLOWED_HOSTS = ['domino_o_ip'] 
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')

Adesso lanciamo il seguente comando per collezionare tutti i file statici del progetto nella cartella specificata di sopra (STATIC_ROOT):

venv/bin/python progetto/manage.py collectstatic

Ora dobbiamo installare il software che sarà in grado di eseguire il nostro codice Python e passare le richieste HTTP al Web Server Nginx a Django.

La configurazione finale avrà infatti una struttura di questo tipo:
Django <–> Gunicorn <–> Nginx <–> Browser (Google Chrome, Firefox..)

I file statici saranno invece forniti direttamente dal Web Server:
Cartella (STATIC_ROOT) <–> Nginx <–> Browser (Google Chrome, Firefox..)

Installiamo il software Gunicorn e assicuriamoci che sia in grado di eseguire il nostro progetto senza errori:

venv/bin/pip install gunicorn
venv/bin/gunicorn --bind 0.0.0.0:8000 progetto.wsgi

Se non abbiamo errori possiamo proseguire.

Creiamo il file di configurazione SystemD per il nostro progetto:

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

Popoliamo quindi il file come mostrato di seguito:

[Unit]
Description=Progetto
After=network.target

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

[Install]
WantedBy=multi-user.target

Salviamo il file e ricarichiamo i file di configurazione di SystemD, per poi abilitare il nostro progetto:

sudo systemctl daemon-reload
sudo systemctl enable progetto

Adesso saremo in grado, in modo semplicissimo, di avviare, stoppare e vedere lo status del nostro progetto rispettivamente con i seguenti comandi:

sudo systemctl start progetto
sudo systemctl stop progetto
sudo systemctl status progetto

Il seguente comando permette invece di vedere tutto l’output del progetto (errori, eccezioni, print, log…):

sudo journalctl –b –u progetto

Ogni volta che il progetto verrà modificato sarà necessario effettuare un reload o un restart:

sudo systemctl restart progetto

Semplice no? Abbiamo praticamente finito! Non rimane che configurare il Web Server.

Apriamo il file di configurazione del nostro Server Block di Nginx e aggiungiamo le seguenti righe alla configurazione:

....
location /static/ {
        alias /home/utente/progetto/static/;
    }

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

La prima istruzione non fa altro che istruire Nginx su dove prendere i file statici: le richieste HTTP che iniziano con “/static/” (STATIC_URL del settings.py) devono ricevere come risposta un file nella directory “/home/utente/progetto/static/” (STATIC_ROOT, dove abbiamo messo i file statici tramite il comando collectstatic).

La seconda istruzione invece istruisce Nginx su tutte le altre richieste HTTP, che iniziano quindi con “/“, in modo da indirizzare le richieste al socket di Gunicorn: “/home/utente/progetto/progetto.sock“.

Notiamo come Nginx elabora la configurazione in modo sequenziale: ecco il motivo per il quale l’istruzione per i file statici viene posizionata prima di quella per il Gunicorn (le richieste che iniziano con “/static/” iniziano anche con “/“, se quindi l’istruzione per i file statici fosse posizionata sotto l’altra non servirebbe a nulla).

Abbiamo finito! Controlliamo che non siano presenti errori nella configurazione di Nginx, per poi riavviarlo:

sudo nginx –t
sudo systemctl restart nginx

Avviamo infine il nostro progetto Django:

sudo systemctl start progetto

Bene, andando su tuodomino.it vedrai il tuo nuovo sito web disponibile al pubblico!

Se hai dubbi o domande chiedi pure qui sotto o nel nostro forum ufficiale.

Fonte: DigitalOcean

Immagine non utilizzabile esternamente.