Come configurare Django con Postgres, Nginx e Gunicorn su Ubuntu
introduzione
Django è un potente framework web che può aiutarti a far decollare la tua applicazione o il tuo sito web Python. Django include un server di sviluppo semplificato per testare il codice localmente, ma per qualsiasi cosa, anche leggermente correlata alla produzione, è richiesto un server web più sicuro e potente.
In questa guida installerai e configurerai alcuni componenti su Ubuntu 22.04 (o qualsiasi altra versione di Ubuntu supportata) per supportare e servire le applicazioni Django. Configurarai un database PostgreSQL invece di utilizzare il database SQLite predefinito. Configurerai il server delle applicazioni Gunicorn per interfacciarsi con le tue applicazioni. Configurarai quindi Nginx per il proxy inverso a Gunicorn, dandoti accesso alle sue funzionalità di sicurezza e prestazioni per servire le tue app.
Distribuisci le tue applicazioni da GitHub utilizzando la piattaforma app DigitalOcean. Lascia che DigitalOcean si concentri sulla scalabilità della tua app.
Installerai Django all'interno di un ambiente virtuale. L'installazione di Django in un ambiente specifico per il tuo progetto consentirà di gestire separatamente i tuoi progetti e i loro requisiti.
Una volta che il database e l'applicazione sono attivi e funzionanti, installerai e configurerai il server delle applicazioni Gunicorn. Questo servirà da interfaccia per la nostra applicazione, traducendo le richieste del client da HTTP a chiamate Python che la nostra applicazione può elaborare. Configurerai quindi Nginx davanti a Gunicorn per sfruttare i suoi meccanismi di gestione della connessione ad alte prestazioni e le sue funzionalità di sicurezza facili da implementare.
Iniziamo.
Prerequisiti
Se utilizzi la versione 16.04 o precedente di Ubuntu, ti consigliamo di eseguire l'aggiornamento a una versione più recente poiché Ubuntu non supporta più queste versioni. Questa raccolta di guide ti aiuterà ad aggiornare la tua versione di Ubuntu.
Per completare questa guida, hai bisogno di un server che esegua Ubuntu, insieme a un utente non root con privilegi sudo
e un firewall attivo. Per indicazioni su come configurarli, scegli la tua distribuzione da questo elenco e segui la nostra Guida alla configurazione iniziale del server.
Passaggi per configurare Django, Nginx e Gunicorn
- Installa i pacchetti dai repository Ubuntu
- Creazione del database e dell'utente PostgreSQL
- Crea un ambiente virtuale Python per Project
- Crea e configura un nuovo progetto Django
- Completa la configurazione del progetto Django
- Metti alla prova la capacità di Gunicorn di servire il progetto
- Creazione di socket e file di servizio systemd Gunicorn
- Controllare il file socket Gunicorn
- Test dell'attivazione del socket
- Configura Nginx per Proxy Passa a Gunicorn
- Risoluzione dei problemi di Nginx e Gunicorn
Passaggio 1: installazione dei pacchetti dai repository Ubuntu
Per iniziare il processo, scaricherai e installerai tutti gli elementi necessari dai repository di Ubuntu. Successivamente utilizzerai il gestore pacchetti Python pip
per installare componenti aggiuntivi.
Per prima cosa devi aggiornare l'indice locale dei pacchetti apt
e poi scaricare e installare i pacchetti. I pacchetti che installi dipendono dalla versione di Python che utilizzerà il tuo progetto.
Se utilizzi Django con Python 3, digita:
sudo apt update
sudo apt install python3-venv python3-dev libpq-dev postgresql postgresql-contrib nginx curl
Questo comando installerà uno strumento per creare ambienti virtuali per i tuoi progetti Python, i file di sviluppo Python necessari per creare Gunicorn in seguito, il sistema di database Postgres e le librerie necessarie per interagire con esso e il server web Nginx.
Passaggio 2: creazione del database e dell'utente PostgreSQL
Ora puoi iniziare subito e creare un database e un utente del database per la nostra applicazione Django.
Per impostazione predefinita, Postgres utilizza uno schema di autenticazione chiamato “autenticazione peer” per le connessioni locali. Fondamentalmente, ciò significa che se il nome utente del sistema operativo dell'utente corrisponde a un nome utente Postgres valido, quell'utente può accedere senza ulteriore autenticazione.
Durante l'installazione di Postgres, è stato creato un utente del sistema operativo denominato postgres
per corrispondere all'utente amministrativo postgres
PostgreSQL. È necessario utilizzare questo utente per eseguire attività amministrative. Puoi usare sudo e passare il nome utente con l'opzione -u
.
Accedi a una sessione interattiva di Postgres digitando:
sudo -u postgres psql
Ti verrà fornito un prompt PostgreSQL in cui potrai impostare i nostri requisiti.
Innanzitutto, crea un database per il tuo progetto:
CREATE DATABASE myproject;
Nota: ogni istruzione Postgres deve terminare con un punto e virgola, quindi assicurati che il tuo comando termini con uno se riscontri problemi.
Successivamente, crea un utente del database per il nostro progetto. Assicurati di selezionare una password sicura:
CREATE USER myprojectuser WITH PASSWORD 'password';
Successivamente, modificherai alcuni parametri di connessione per l'utente che hai appena creato. Ciò velocizzerà le operazioni del database in modo che non sia necessario interrogare e impostare i valori corretti ogni volta che viene stabilita una connessione.
Imposterai la codifica dei caratteri predefinita su UTF-8
, che Django si aspetta. Stai anche impostando lo schema di isolamento delle transazioni predefinito su "read commit", che blocca le letture dalle transazioni senza commit. Infine, stai impostando il fuso orario. Per impostazione predefinita, i progetti Django verranno impostati per utilizzare UTC
. Queste sono tutte raccomandazioni del progetto Django stesso:
ALTER ROLE myprojectuser SET client_encoding TO 'utf8';
ALTER ROLE myprojectuser SET default_transaction_isolation TO 'read committed';
ALTER ROLE myprojectuser SET timezone TO 'UTC';
Ora puoi concedere al nuovo utente l'accesso per amministrare il nuovo database:
GRANT ALL PRIVILEGES ON DATABASE myproject TO myprojectuser;
Una volta terminato, esci dal prompt di PostgreSQL digitando:
\q
Postgres è ora configurato in modo che Django possa connettersi e gestire le informazioni del proprio database.
Passaggio 3: creazione di un ambiente virtuale Python per il tuo progetto
Ora che hai un database pronto, puoi iniziare a ottenere il resto dei requisiti del tuo progetto. Installerai i requisiti Python all'interno di un ambiente virtuale per una gestione più semplice.
Innanzitutto, crea e modifica una directory in cui puoi conservare i file di progetto:
mkdir ~/myprojectdir
cd ~/myprojectdir
All'interno della directory del progetto, crea un ambiente virtuale Python digitando:
python3 -m venv myprojectenv
Verrà creata una directory chiamata myprojectenv
all'interno della directory myprojectdir
. All'interno installerà una versione locale di Python e una versione locale di pip
per gestire i pacchetti. Puoi utilizzare questa struttura di ambiente virtuale per installare e configurare un ambiente Python isolato per qualsiasi progetto che desideri creare.
Prima di installare i requisiti Python del tuo progetto, dovrai attivare l'ambiente virtuale. Puoi farlo digitando:
source myprojectenv/bin/activate
Il tuo messaggio dovrebbe cambiare per indicare che ora stai operando all'interno di un ambiente virtuale Python. Sarà simile a questo: (myprojectenv)utente@host:~/myprojectdir$< /codice>.
Con il tuo ambiente virtuale attivo, installa Django, Gunicorn e l'adattatore PostgreSQL psycopg2
con l'istanza locale di pip
:
Nota: quando l'ambiente virtuale è attivato (quando il prompt è preceduto da (myprojectenv)
), utilizza pip
invece di pip3
, anche se stai utilizzando Python 3. La copia dello strumento nell'ambiente virtuale è sempre denominata pip
, indipendentemente dalla versione di Python.
pip install django gunicorn psycopg2-binary
Ora dovresti avere tutto il software necessario per avviare un progetto Django.
Passaggio 4: creazione e configurazione di un nuovo progetto Django
Con i componenti Python installati, ora puoi creare i file di progetto Django effettivi.
Dato che hai già una directory di progetto, dirai a Django di installare i file qui. Creerà una directory di secondo livello con il codice effettivo, il che è normale, e inserirà uno script di gestione in questa directory. La chiave di ciò è che stai definendo la directory in modo esplicito invece di consentire a Django di prendere decisioni relative alla nostra directory corrente:
django-admin startproject myproject ~/myprojectdir
A questo punto, la directory del tuo progetto (~/myprojectdir
in questo caso di esempio) dovrebbe avere il seguente contenuto:
~/myprojectdir/manage.py
: uno script di gestione del progetto Django.~/myprojectdir/myproject/
: il pacchetto del progetto Django. Dovrebbe contenere__init__.py
,settings.py
,urls.py
,asgi.py
e < filewsgi.py.~/myprojectdir/myprojectenv/
: la directory dell'ambiente virtuale creata in precedenza.
La prima cosa che dovresti fare con i file di progetto appena creati è regolare le impostazioni. Apri il file delle impostazioni nel tuo editor di testo:
nano ~/myprojectdir/myproject/settings.py
Inizia individuando la direttiva ALLOWED_HOSTS
. Ciò definisce un elenco di indirizzi del server o nomi di dominio che possono essere utilizzati per connettersi all'istanza di Django. Qualsiasi richiesta in entrata con un'intestazione Host non presente in questo elenco genererà un'eccezione. Django richiede che tu lo imposti per prevenire una certa classe di vulnerabilità della sicurezza.
Tra parentesi quadre, elenca gli indirizzi IP o i nomi di dominio associati al tuo server Django. Ogni elemento deve essere elencato tra virgolette con voci separate da una virgola. Se desideri richieste per un intero dominio ed eventuali sottodomini, anteponi un punto all'inizio della voce. Nello snippet seguente, ci sono alcuni esempi commentati utilizzati per dimostrare:
Nota: assicurati di includere localhost
come una delle opzioni poiché eseguirai il proxy delle connessioni tramite un'istanza Nginx locale.
. . .
# The simplest case: just add the domain name(s) and IP addresses of your Django server
# ALLOWED_HOSTS = [ 'example.com', '203.0.113.5']
# To respond to 'example.com' and any subdomains, start the domain with a dot
# ALLOWED_HOSTS = ['.example.com', '203.0.113.5']
ALLOWED_HOSTS = ['your_server_domain_or_IP', 'second_domain_or_IP', . . ., 'localhost']
Successivamente, trova la sezione che configura l'accesso al database. Inizierà con DATABASES
. La configurazione nel file è per un database SQLite. Hai già creato un database PostgreSQL per il nostro progetto, quindi devi modificare le impostazioni.
Modifica le impostazioni con le informazioni del tuo database PostgreSQL. Dici a Django di utilizzare l'adattatore psycopg2
che hai installato con pip
. È necessario fornire il nome del database, il nome utente del database, la password dell'utente del database, quindi specificare che il database si trova sul computer locale. Puoi lasciare l'impostazione PORT
come una stringa vuota:
. . .
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'myproject',
'USER': 'myprojectuser',
'PASSWORD': 'password',
'HOST': 'localhost',
'PORT': '',
}
}
. . .
Successivamente, spostati fino alla fine del file e aggiungi un'impostazione che indica dove posizionare i file statici. Ciò è necessario affinché Nginx possa gestire le richieste per questi elementi. La riga seguente dice a Django di inserirli in una directory chiamata static
nella directory del progetto di base:
. . .
STATIC_URL = 'static/'
# Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
import os
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
Salva e chiudi il file quando hai finito.
Passaggio 5: completamento della configurazione iniziale del progetto
Ora puoi migrare lo schema del database iniziale nel nostro database PostgreSQL utilizzando lo script di gestione:
~/myprojectdir/manage.py makemigrations
~/myprojectdir/manage.py migrate
Crea un utente amministrativo per il progetto digitando:
~/myprojectdir/manage.py createsuperuser
Dovrai selezionare un nome utente, fornire un indirizzo email e scegliere e confermare una password.
Puoi raccogliere tutto il contenuto statico nel percorso della directory configurato digitando:
~/myprojectdir/manage.py collectstatic
Dovrai confermare l'operazione. I file statici verranno quindi inseriti in una directory chiamata static
all'interno della directory del progetto.
Se hai seguito la guida alla configurazione iniziale del server, dovresti avere un firewall UFW che protegge il tuo server. Per testare il server di sviluppo, devi consentire l'accesso alla porta che utilizzerai.
Crea un'eccezione per la porta 8000 digitando:
sudo ufw allow 8000
Infine, puoi testare il tuo progetto avviando il server di sviluppo Django con questo comando:
~/myprojectdir/manage.py runserver 0.0.0.0:8000
Nel tuo browser web, visita il nome di dominio o l'indirizzo IP del tuo server seguito da :8000
:
http://server_domain_or_IP:8000
Dovresti ricevere la pagina indice Django predefinita:
Se aggiungi /admin
alla fine dell'URL nella barra degli indirizzi, ti verranno richiesti il nome utente e la password amministrativi che hai creato con il comando createsuperuser
:
Dopo l'autenticazione, puoi accedere all'interfaccia di amministrazione di Django predefinita:
Una volta terminata l'esplorazione, premi CTRL-C nella finestra del terminale per spegnere il server di sviluppo.
Passaggio 6: testare la capacità di Gunicorn di servire il progetto
L'ultima cosa che devi fare prima di lasciare il tuo ambiente virtuale è testare Gunicorn per assicurarti che possa servire l'applicazione. Puoi farlo accedendo alla directory del progetto e utilizzando gunicorn
per caricare il modulo WSGI del progetto:
cd ~/myprojectdir
gunicorn --bind 0.0.0.0:8000 myproject.wsgi
Ciò avvierà Gunicorn sulla stessa interfaccia su cui era in esecuzione il server di sviluppo Django. Puoi tornare indietro e testare nuovamente l'app nel tuo browser.
Nota: all'interfaccia di amministrazione non verrà applicato nessuno stile poiché Gunicorn non sa come trovare il contenuto CSS statico responsabile di ciò.
Hai passato a Gunicorn un modulo specificando il percorso della directory relativa al file wsgi.py
di Django, che è il punto di ingresso alla tua applicazione, utilizzando la sintassi del modulo Python. All'interno di questo file è definita una funzione chiamata application
, che viene utilizzata per comunicare con l'applicazione. Per saperne di più sulle specifiche WSGI, fare clic qui.
Una volta terminato il test, premi CTRL-C nella finestra del terminale per arrestare Gunicorn.
Ora hai finito di configurare la tua applicazione Django. Puoi uscire dal nostro ambiente virtuale digitando:
deactivate
L'indicatore dell'ambiente virtuale nel tuo prompt verrà rimosso.
Passaggio 7: creazione di socket systemd e file di servizio per Gunicorn
Hai testato che Gunicorn può interagire con la nostra applicazione Django, ma ora dovresti implementare un modo più efficace per avviare e arrestare il server delle applicazioni. Per raggiungere questo obiettivo, creerai servizi systemd e file socket.
Il socket Gunicorn verrà creato all'avvio e ascolterà le connessioni. Quando si verifica una connessione, systemd avvierà automaticamente il processo Gunicorn per gestire la connessione.
Inizia creando e aprendo un file socket systemd per Gunicorn con privilegi sudo
:
sudo nano /etc/systemd/system/gunicorn.socket
All'interno, creerai una sezione [Unit]
per descrivere il socket, una sezione [Socket]
per definire la posizione del socket e una sezione [Install]
sezione per assicurarti che il socket venga creato al momento giusto:
[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/run/gunicorn.sock
[Install]
WantedBy=sockets.target
Salva e chiudi il file quando hai finito.
Successivamente, crea e apri un file di servizio systemd per Gunicorn con privilegi sudo
nel tuo editor di testo. Il nome file del servizio deve corrispondere al nome file del socket ad eccezione dell'estensione:
sudo nano /etc/systemd/system/gunicorn.service
Inizia con la sezione [Unit]
, utilizzata per specificare metadati e dipendenze. Inserisci qui una descrizione del servizio e comunica al sistema init di avviarlo solo dopo aver raggiunto l'obiettivo di rete. Poiché il tuo servizio si basa sul socket del file socket, devi includere una direttiva Requires
per indicare tale relazione:
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
Successivamente, aprirai la sezione [Service]
. Specificare l'utente e il gruppo con cui si desidera eseguire l'elaborazione. Darai al tuo account utente normale la proprietà del processo poiché possiede tutti i file rilevanti. Darai la proprietà del gruppo al gruppo www-data
in modo che Nginx possa comunicare facilmente con Gunicorn.
Quindi mapperai la directory di lavoro e specificherai il comando da utilizzare per avviare il servizio. In questo caso, devi specificare il percorso completo dell'eseguibile Gunicorn, che viene installato nel nostro ambiente virtuale. Quindi collegherai il processo al socket Unix che hai creato nella directory /run
in modo che il processo possa comunicare con Nginx. Tutti i dati vengono registrati nell'output standard in modo che il processo journald
possa raccogliere i log Gunicorn. Puoi anche specificare eventuali modifiche opzionali a Gunicorn qui. Ad esempio, in questo caso hai specificato 3 processi di lavoro:
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myprojectdir
ExecStart=/home/sammy/myprojectdir/myprojectenv/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/run/gunicorn.sock \
myproject.wsgi:application
Infine, aggiungerai una sezione [Installa]
. Questo dirà a systemd a cosa collegare questo servizio se lo abiliti all'avvio all'avvio. Vuoi che questo servizio venga avviato quando il normale sistema multiutente è attivo e funzionante:
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myprojectdir
ExecStart=/home/sammy/myprojectdir/myprojectenv/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/run/gunicorn.sock \
myproject.wsgi:application
[Install]
WantedBy=multi-user.target
Con ciò, il tuo file di servizio systemd è completo. Salvalo e chiudilo adesso.
Ora puoi avviare e abilitare il socket Gunicorn. Questo creerà il file socket in /run/gunicorn.sock
ora e all'avvio. Quando viene stabilita una connessione a quel socket, systemd avvierà automaticamente gunicorn.service
per gestirlo:
sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket
È possibile verificare che l'operazione sia andata a buon fine controllando il file socket.
Passaggio 8: controllo del file socket Gunicorn
Controlla lo stato del processo per scoprire se è stato possibile avviarlo:
sudo systemctl status gunicorn.socket
Dovresti ricevere un output come questo:
● gunicorn.socket - gunicorn socket
Loaded: loaded (/etc/systemd/system/gunicorn.socket; enabled; vendor preset: enabled)
Active: active (listening) since Mon 2022-04-18 17:53:25 UTC; 5s ago
Triggers: ● gunicorn.service
Listen: /run/gunicorn.sock (Stream)
CGroup: /system.slice/gunicorn.socket
Apr 18 17:53:25 django systemd[1]: Listening on gunicorn socket.
Successivamente, controlla l'esistenza del file gunicorn.sock
all'interno della directory /run
:
file /run/gunicorn.sock
/run/gunicorn.sock: socket
Se il comando systemctl status
indica che si è verificato un errore o se non trovi il file gunicorn.sock
nella directory, significa che il socket Gunicorn non è stato in grado di essere creato correttamente. Controlla i log del socket Gunicorn digitando:
sudo journalctl -u gunicorn.socket
Dai un'altra occhiata al tuo file /etc/systemd/system/gunicorn.socket
per risolvere eventuali problemi prima di continuare.
Passaggio 9: test dell'attivazione del socket
Attualmente, se hai avviato solo l'unità gunicorn.socket
, il gunicorn.service
non sarà ancora attivo poiché il socket non ha ancora ricevuto alcuna connessione. Puoi verificarlo digitando:
sudo systemctl status gunicorn
○ gunicorn.service - gunicorn daemon
Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled)
Active: inactive (dead)
TriggeredBy: ● gunicorn.socket
Per testare il meccanismo di attivazione del socket, puoi inviare una connessione al socket tramite curl
digitando:
curl --unix-socket /run/gunicorn.sock localhost
Dovresti ricevere l'output HTML dalla tua applicazione nel terminale. Ciò indica che Gunicorn è stato avviato ed è stato in grado di servire la tua applicazione Django. Puoi verificare che il servizio Gunicorn sia in esecuzione digitando:
sudo systemctl status gunicorn
● gunicorn.service - gunicorn daemon
Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled)
Active: active (running) since Mon 2022-04-18 17:54:49 UTC; 5s ago
TriggeredBy: ● gunicorn.socket
Main PID: 102674 (gunicorn)
Tasks: 4 (limit: 4665)
Memory: 94.2M
CPU: 885ms
CGroup: /system.slice/gunicorn.service
├─102674 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application
├─102675 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application
├─102676 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application
└─102677 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application
Apr 18 17:54:49 django systemd[1]: Started gunicorn daemon.
Apr 18 17:54:49 django gunicorn[102674]: [2022-04-18 17:54:49 +0000] [102674] [INFO] Starting gunicorn 20.1.0
Apr 18 17:54:49 django gunicorn[102674]: [2022-04-18 17:54:49 +0000] [102674] [INFO] Listening at: unix:/run/gunicorn.sock (102674)
Apr 18 17:54:49 django gunicorn[102674]: [2022-04-18 17:54:49 +0000] [102674] [INFO] Using worker: sync
Apr 18 17:54:49 django gunicorn[102675]: [2022-04-18 17:54:49 +0000] [102675] [INFO] Booting worker with pid: 102675
Apr 18 17:54:49 django gunicorn[102676]: [2022-04-18 17:54:49 +0000] [102676] [INFO] Booting worker with pid: 102676
Apr 18 17:54:50 django gunicorn[102677]: [2022-04-18 17:54:50 +0000] [102677] [INFO] Booting worker with pid: 102677
Apr 18 17:54:50 django gunicorn[102675]: - - [18/Apr/2022:17:54:50 +0000] "GET / HTTP/1.1" 200 10697 "-" "curl/7.81.0"
Se l'output di curl
o l'output di systemctl status
indica che si è verificato un problema, controlla i log per ulteriori dettagli:
sudo journalctl -u gunicorn
Controlla se ci sono problemi nel tuo file /etc/systemd/system/gunicorn.service
. Se apporti modifiche al file /etc/systemd/system/gunicorn.service
, ricarica il demone per rileggere la definizione del servizio e riavvia il processo Gunicorn digitando:
sudo systemctl daemon-reload
sudo systemctl restart gunicorn
Assicurati di risolvere i problemi di cui sopra prima di continuare.
Passaggio 10: configura Nginx per Proxy Passa a Gunicorn
Ora che Gunicorn è configurato, devi configurare Nginx per passare il traffico al processo.
Inizia creando e aprendo un nuovo blocco server nella directory sites-available
di Nginx:
sudo nano /etc/nginx/sites-available/myproject
All'interno, apri un nuovo blocco server. Inizierai specificando che questo blocco dovrebbe essere in ascolto sulla normale porta 80 e che dovrebbe rispondere al nome di dominio o all'indirizzo IP del tuo server:
server {
listen 80;
server_name server_domain_or_IP;
}
Successivamente, dirai a Nginx di ignorare eventuali problemi con la ricerca di una favicon. Gli dirai anche dove trovare le risorse statiche che hai raccolto nella tua directory ~/myprojectdir/static
. Tutti questi file hanno un prefisso URI standard “/static”, quindi puoi creare un blocco di posizione per soddisfare tali richieste:
server {
listen 80;
server_name server_domain_or_IP;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/sammy/myprojectdir;
}
}
Infine, crea un blocco location/{}
per soddisfare tutte le altre richieste. All'interno di questa posizione, includerai il file proxy_params
standard incluso nell'installazione di Nginx e quindi passerai il traffico direttamente al socket Gunicorn:
server {
listen 80;
server_name server_domain_or_IP;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/sammy/myprojectdir;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
}
Salva e chiudi il file quando hai finito. Ora puoi abilitare il file collegandolo alla directory sites-enabled
:
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
Verifica la presenza di errori di sintassi nella tua configurazione Nginx digitando:
sudo nginx -t
Se non vengono segnalati errori, vai avanti e riavvia Nginx digitando:
sudo systemctl restart nginx
Infine, devi aprire il tuo firewall al traffico normale sulla porta 80. Poiché non hai più bisogno dell'accesso al server di sviluppo, puoi rimuovere la regola per aprire anche la porta 8000:
sudo ufw delete allow 8000
sudo ufw allow 'Nginx Full'
Ora dovresti essere in grado di accedere al dominio o all'indirizzo IP del tuo server per visualizzare la tua applicazione.
Nota: dopo aver configurato Nginx, il passaggio successivo dovrebbe essere quello di proteggere il traffico verso il server utilizzando SSL/TLS. Questo è importante perché senza di esso tutte le informazioni, comprese le password, vengono inviate in rete in formato testo normale.
Se hai un nome di dominio, il modo più semplice per ottenere un certificato SSL per proteggere il tuo traffico è utilizzare Let's Encrypt. Segui questa guida per Ubuntu 22.04/Ubuntu 20.04/Ubuntu 18.04 per configurare Let's Encrypt with Nginx su Ubuntu 22.04. Segui la procedura utilizzando il blocco server Nginx che hai creato in questa guida.
Passaggio 11: risoluzione dei problemi di Nginx e Gunicorn
Se quest'ultimo passaggio non mostra la tua applicazione, dovrai risolvere i problemi di installazione.
Nginx mostra la pagina predefinita invece dell'applicazione Django
Se Nginx visualizza la pagina predefinita invece di eseguire il proxy verso la tua applicazione, in genere significa che devi modificare il server_name
all'interno di /etc/nginx/sites-available/myproject
file in modo che punti all'indirizzo IP o al nome di dominio del tuo server.
Nginx utilizza server_name
per determinare quale blocco server utilizzare per rispondere alle richieste. Se ricevi la pagina Nginx predefinita, significa che Nginx non è stato in grado di abbinare esplicitamente la richiesta a un blocco del server, quindi ricorre al blocco predefinito definito in /etc/nginx/sites-available/ predefinito.
Per essere selezionato, il nome_server
nel blocco server del tuo progetto deve essere più specifico di quello nel blocco server predefinito.
Nginx visualizza un errore 502 Bad Gateway invece dell'applicazione Django
Un errore 502 indica che Nginx non è in grado di eseguire correttamente il proxy della richiesta. Un'ampia gamma di problemi di configurazione si esprime con un errore 502, quindi sono necessarie ulteriori informazioni per risolverli correttamente.
Il posto principale in cui cercare ulteriori informazioni è nei log degli errori di Nginx. Generalmente, questo ti dirà quali condizioni hanno causato problemi durante l'evento di proxy. Segui i log degli errori di Nginx digitando:
sudo tail -F /var/log/nginx/error.log
Ora, fai un'altra richiesta nel tuo browser per generare un nuovo errore (prova ad aggiornare la pagina). Dovresti ricevere un nuovo messaggio di errore scritto nel registro. Se guardi il messaggio, dovrebbe aiutarti a restringere il problema.
Potresti ricevere il seguente messaggio:
connect() to unix:/run/gunicorn.sock failed (2: No such file or directory)
Ciò indica che Nginx non è riuscito a trovare il file gunicorn.sock
nella posizione specificata. Dovresti confrontare la posizione proxy_pass
definita nel file /etc/nginx/sites-available/myproject
con la posizione effettiva del file gunicorn.sock
generato dall'unità systemd gunicorn.socket
.
Se non riesci a trovare un file gunicorn.sock
nella directory /run
, generalmente significa che il file socket systemd non è stato in grado di crearlo. Torna alla sezione sulla verifica del file socket Gunicorn per seguire i passaggi di risoluzione dei problemi per Gunicorn.
connect() to unix:/run/gunicorn.sock failed (13: Permission denied)
Ciò indica che Nginx non è riuscito a connettersi al socket Gunicorn a causa di problemi di permessi. Ciò può accadere quando la procedura viene seguita utilizzando l'utente root anziché un utente sudo
. Sebbene systemd sia in grado di creare il file socket Gunicorn, Nginx non è in grado di accedervi.
Questo può succedere se ci sono permessi limitati in qualsiasi punto tra la directory root (/
) e il file gunicorn.sock
. Puoi rivedere i permessi e i valori di proprietà del file socket e di ciascuna delle sue directory principali passando il percorso assoluto del file socket al comando namei
:
namei -l /run/gunicorn.sock
f: /run/gunicorn.sock
drwxr-xr-x root root /
drwxr-xr-x root root run
srw-rw-rw- root root gunicorn.sock
L'output visualizza le autorizzazioni di ciascuno dei componenti della directory. Osservando i permessi (prima colonna), il proprietario (seconda colonna) e il proprietario del gruppo (terza colonna), puoi capire quale tipo di accesso è consentito al file socket.
Nell'esempio sopra, il file socket e ciascuna delle directory che portano al file socket hanno permessi di lettura ed esecuzione a livello mondiale (la colonna dei permessi per le directory termina con r-x
invece di --- ). Il processo Nginx dovrebbe essere in grado di accedere correttamente al socket.
Se una qualsiasi delle directory che portano al socket non dispone dell'autorizzazione di lettura ed esecuzione mondiale, Nginx non sarà in grado di accedere al socket senza consentire le autorizzazioni di lettura ed esecuzione mondiale o assicurarsi che la proprietà del gruppo sia assegnata a un gruppo di cui Nginx fa parte Di.
Viene visualizzato Django: "impossibile connettersi al server: connessione rifiutata"
Un messaggio che potresti ricevere da Django quando tenti di accedere a parti dell'applicazione nel browser web è:
OperationalError at /admin/login/
could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 5432?
Ciò indica che Django non è in grado di connettersi al database Postgres. Assicurati che l'istanza Postgres sia in esecuzione digitando:
sudo systemctl status postgresql
In caso contrario, puoi avviarlo e abilitarlo all'avvio automatico all'avvio (se non è già configurato per farlo) digitando:
sudo systemctl start postgresql
sudo systemctl enable postgresql
Se i problemi persistono, assicurati che le impostazioni del database definite nel file ~/myprojectdir/myproject/settings.py
siano corrette.
Ulteriore risoluzione dei problemi
Per un'ulteriore risoluzione dei problemi, i registri possono aiutare a restringere le cause principali. Controlla ciascuno di essi a turno e cerca i messaggi che indicano le aree problematiche.
I seguenti log potrebbero essere utili:
- Controlla i log del processo Nginx digitando:
sudo journalctl -u nginx
- Controlla i log di accesso di Nginx digitando:
sudo less /var/log/nginx/access.log
- Controlla i log degli errori di Nginx digitando:
sudo less /var/log/nginx/error.log
- Controlla i log dell'applicazione Gunicorn digitando:
sudo journalctl -u gunicorn
- Controlla i log del socket Gunicorn digitando:
sudo journalctl -u gunicorn.socket
Quando aggiorni la configurazione o l'applicazione, probabilmente dovrai riavviare i processi per adattarli alle modifiche.
Se aggiorni la tua applicazione Django, puoi riavviare il processo Gunicorn per applicare le modifiche digitando:
sudo systemctl restart gunicorn
Se modifichi il socket Gunicorn o i file di servizio, ricarica il demone e riavvia il processo digitando:
sudo systemctl daemon-reload
sudo systemctl restart gunicorn.socket gunicorn.service
Se modifichi la configurazione del blocco server Nginx, testa la configurazione e poi Nginx digitando:
sudo nginx -t && sudo systemctl restart nginx
Questi comandi sono utili per apportare modifiche mentre modifichi la configurazione.
Conclusione
In questa guida, configuri un progetto Django nel proprio ambiente virtuale. Hai configurato Gunicorn per tradurre le richieste dei client in modo che Django possa gestirle. Successivamente, imposti Nginx in modo che agisca come proxy inverso per gestire le connessioni client e servire il progetto corretto in base alla richiesta del client.
Django semplifica la creazione di progetti e applicazioni fornendo molti degli elementi comuni, consentendoti di concentrarti sugli elementi unici. Sfruttando la catena di strumenti generale descritta in questo articolo, puoi servire facilmente le applicazioni create da un singolo server.