Come configurare Django con Postgres, Nginx e Gunicorn su Debian 11
introduzione
Django è un potente framework web che può aiutarti a far decollare la tua applicazione Python o il tuo sito web. Django include un server di sviluppo per testare il tuo codice localmente, ma per qualsiasi cosa anche leggermente correlata alla produzione, è necessario un server web più sicuro e potente.
In questa guida installerai e configurerai alcuni componenti su Debian 11 per supportare e servire le applicazioni Django. Verrà configurato un database PostgreSQL invece di utilizzare il database SQLite predefinito. Configura il server delle applicazioni Gunicorn per interfacciarsi con le tue applicazioni. Quindi configurerai Nginx per invertire il proxy su Gunicorn, dandoti accesso alle sue funzionalità di sicurezza e prestazioni per servire le tue app.
Prerequisiti e obiettivi
Per completare questa guida, dovresti avere una nuova istanza del server Debian 11 con un firewall di base e un utente non root con privilegi sudo
configurati. Puoi imparare come configurarlo eseguendo la nostra guida alla configurazione iniziale del server.
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 fungerà da interfaccia per la nostra applicazione, traducendo le richieste del client da HTTP a chiamate Python che la nostra applicazione può elaborare. Quindi configurerai Nginx davanti a Gunicorn per sfruttare i suoi meccanismi di gestione delle connessioni ad alte prestazioni e le sue funzionalità di sicurezza.
Iniziamo.
Installazione dei pacchetti dai repository Debian
Per iniziare il processo, scaricherai e installerai tutti gli elementi di cui hai bisogno dai repository Debian. Successivamente utilizzerai il gestore di pacchetti Python pip
per installare componenti aggiuntivi.
Per prima cosa devi aggiornare l'indice locale dei pacchetti apt
e quindi scaricare e installare i pacchetti.
- 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 costruire successivamente Gunicorn, il sistema di database Postgres e le librerie necessarie per interagire con esso e il server web Nginx.
Creazione del database e dell'utente PostgreSQL
Ora puoi entrare subito e creare un database e un utente di 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 amministratore PostgreSQL postgres
. È 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 puoi 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.
Quindi, crea un utente del database per il nostro progetto. Assicurati di selezionare una password sicura:
- CREATE USER myprojectuser WITH PASSWORD 'password';
Successivamente, modificherai alcuni dei parametri di connessione per l'utente che hai appena creato. Ciò velocizzerà le operazioni del database in modo che i valori corretti non debbano essere interrogati e impostati 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 da transazioni non salvate. Infine, stai impostando il fuso orario. Per impostazione predefinita, i progetti Django saranno 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;
Quando hai finito, esci dal prompt di PostgreSQL digitando:
- \q
Postgres è ora impostato in modo che Django possa connettersi e gestire le informazioni del suo database.
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.
Innanzitutto, crea e modifica in una directory in cui puoi conservare i file del tuo progetto:
- mkdir ~/myprojectdir
- cd ~/myprojectdir
All'interno della directory del progetto, crea un ambiente virtuale Python digitando:
- python3 -m venv myprojectenv
Questo creerà una directory chiamata myprojectenv
all'interno della tua 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 prompt dovrebbe cambiare per indicare che stai operando all'interno di un ambiente virtuale Python. Sarà simile a questo: (myprojectenv)user@host:~/myprojectdir$< /codice>.
Con il tuo ambiente virtuale attivo, installa Django, Gunicorn e l'adattatore psycopg2
PostgreSQL con l'istanza locale di pip
:
Nota: quando l'ambiente virtuale è attivato (quando il tuo prompt è preceduto da (myprojectenv)
), usa pip
invece di pip3
, anche se stanno usando Python 3. La copia dello strumento dell'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.
Creazione e configurazione di un nuovo progetto Django
Con i tuoi componenti Python installati, ora puoi creare i file di progetto Django effettivi.
Creazione del progetto Django
Dato che hai già una directory del progetto, dirai a Django di installare i file qui. Creerà una directory di secondo livello con il codice effettivo, 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
ewsgi.py
.~/myprojectdir/myprojectenv/
: la directory dell'ambiente virtuale che hai creato in precedenza.
Regolazione delle impostazioni del progetto
La prima cosa da fare con i file di progetto appena creati è regolare le impostazioni. Apri il file delle impostazioni usando nano
o il tuo editor di testo preferito:
- nano ~/myprojectdir/myproject/settings.py
Inizia individuando la direttiva ALLOWED_HOSTS
. Questo definisce un elenco di indirizzi del server o nomi di dominio che possono essere utilizzati per connettersi all'istanza di Django. Qualsiasi richiesta in arrivo con un'intestazione Host non presente in questo elenco solleverà un'eccezione. Django richiede di impostarlo 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 richiedere un intero dominio ed eventuali sottodomini, anteponi un punto all'inizio della voce. Nello snippet qui sotto, ci sono alcuni esempi commentati usati per dimostrare:
Nota: assicurati di includere localhost
come una delle opzioni poiché eseguirai il proxy delle connessioni tramite un'istanza Nginx locale.
. . .
ALLOWED_HOSTS = ['your_server_domain_or_IP', 'second_domain_or_IP', . . ., 'localhost']
Quindi, 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 regolare le impostazioni.
Modifica le impostazioni con le informazioni del tuo database PostgreSQL. Dici a Django di usare 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 e 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 in fondo al file e aggiungi un'impostazione che indichi dove posizionare i file statici. Ciò è necessario affinché Nginx possa gestire le richieste per questi elementi. La seguente riga dice a Django di metterli 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. Se stai usando nano
, premi Ctrl+X
, quindi, quando richiesto, Y
e poi Invio.
Completamento della configurazione iniziale del progetto
Ora puoi migrare lo schema del database iniziale al 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 e-mail e scegliere e confermare una password.
È possibile raccogliere tutto il contenuto statico nella posizione della directory configurata 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 disporre di un firewall UFW a protezione del 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 verrà richiesto il nome utente e la password dell'amministratore che hai creato con il comando createsuperuser
:

Dopo l'autenticazione, puoi accedere all'interfaccia di amministrazione predefinita di Django:

Al termine dell'esplorazione, premi CTRL-C nella finestra del terminale per arrestare il server di sviluppo.
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 entrando nella directory del progetto e usando gunicorn
per caricare il modulo WSGI del progetto:
- cd ~/myprojectdir
- gunicorn --bind 0.0.0.0:8000 myproject.wsgi
Questo 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: l'interfaccia di amministrazione non avrà alcuno stile applicato 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, usando la sintassi del modulo di Python. All'interno di questo file è definita una funzione chiamata application
, che viene utilizzata per comunicare con l'applicazione. Per ulteriori informazioni sulla specifica WSGI, fare clic qui.
Quando hai finito di testare, premi CTRL-C nella finestra del terminale per fermare Gunicorn.
Ora hai finito di configurare la tua applicazione Django. Puoi uscire dal nostro ambiente virtuale digitando:
- deactivate
L'indicatore dell'ambiente virtuale nel prompt verrà rimosso.
Creazione di socket di sistema e file di servizio per Gunicorn
Hai verificato che Gunicorn può interagire con la nostra applicazione Django, ma ora dovresti implementare un modo più affidabile per avviare e arrestare il server delle applicazioni. Per fare ciò, creerai il servizio systemd e i 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 un [Install]
sezione per assicurarsi che il socket sia 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 i privilegi sudo
nel tuo editor di testo. Il nome del file del servizio deve corrispondere al nome del file del socket ad eccezione dell'estensione:
- sudo nano /etc/systemd/system/gunicorn.service
Inizia con la sezione [Unit]
, che viene utilizzata per specificare metadati e dipendenze. Inserisci qui una descrizione del servizio e comunica al sistema init di avviarlo solo dopo che l'obiettivo di rete è stato raggiunto. 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, scriverai la sezione [Service]
. Specificare l'utente e il gruppo con cui eseguire l'elaborazione. Darai al tuo normale account utente la proprietà del processo poiché possiede tutti i file pertinenti. Darai la proprietà del gruppo al gruppo www-data
in modo che Nginx possa comunicare 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 è installato all'interno del nostro ambiente virtuale. Quindi collegherai il processo al socket Unix che hai creato all'interno della directory /run
in modo che il processo possa comunicare con Nginx. Registra tutti i dati sullo standard output in modo che il processo journald
possa raccogliere i log di Gunicorn. Puoi anche specificare eventuali tweak Gunicorn opzionali 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 [Install]
. Questo dirà a systemd a cosa collegare questo servizio se lo abiliti per l'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. Salva e chiudi ora.
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 confermare che l'operazione è andata a buon fine controllando il file socket.
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:
Output● gunicorn.socket - gunicorn socket
Loaded: loaded (/etc/systemd/system/gunicorn.socket; enabled; vendor preset: enabled)
Active: active (listening) since Thu 2022-08-04 19:02:54 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, verifica l'esistenza del file gunicorn.sock
all'interno della directory /run
:
- file /run/gunicorn.sock
Output/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, è un'indicazione 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 correggere eventuali problemi prima di continuare.
Test di attivazione del socket
Attualmente, se hai avviato solo l'unità gunicorn.socket
, gunicorn.service
non sarà ancora attivo poiché il socket non ha ancora ricevuto alcuna connessione. Puoi verificarlo digitando:
- sudo systemctl status gunicorn
Output○ 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
Output● gunicorn.service - gunicorn daemon
Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled)
Active: active (running) since Thu 2022-08-04 19:03:51 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 il tuo file /etc/systemd/system/gunicorn.service
per eventuali problemi. 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.
Configura Nginx su Proxy Passa a Gunicorn
Ora che Gunicorn è configurato, devi configurare Nginx per trasferire 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 qualsiasi problema 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 di \/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
Testa la tua configurazione Nginx per errori di sintassi digitando:
- sudo nginx -t
Se non vengono segnalati errori, vai avanti e riavvia Nginx digitando:
- sudo systemctl restart nginx
Infine, è necessario aprire il firewall al normale traffico sulla porta 80. Poiché non è più necessario accedere al server di sviluppo, è possibile rimuovere anche la regola per aprire 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 la protezione del traffico verso il server tramite SSL/TLS. Questo è importante perché senza di esso tutte le informazioni, comprese le password, vengono inviate in rete in formato testo.
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 configurare Let's Encrypt con Nginx su Debian 11. Segui la procedura utilizzando il blocco del server Nginx che hai creato in questa guida.
Risoluzione dei problemi di Nginx e Gunicorn
Se quest'ultimo passaggio non mostra la tua applicazione, dovrai risolvere i problemi dell'installazione.
Nginx mostra la pagina predefinita invece dell'applicazione Django
Se Nginx visualizza la pagina predefinita invece di inviare un proxy alla tua applicazione, di solito significa che devi modificare server_name
all'interno di /etc/nginx/sites-available/myproject
in modo che punti all'indirizzo IP o al nome di dominio del tuo server.
Nginx utilizza il server_name
per determinare quale blocco del server utilizzare per rispondere alle richieste. Se ricevi la pagina Nginx predefinita, è un segno che Nginx non è stato in grado di abbinare la richiesta a un blocco server in modo esplicito, quindi sta ricadendo sul blocco predefinito definito in /etc/nginx/sites-available/ predefinito
.
Il nome_server
nel blocco server del tuo progetto deve essere più specifico di quello nel blocco server predefinito da selezionare.
Nginx mostra un errore 502 Bad Gateway invece dell'applicazione Django
Un errore 502 indica che Nginx non è in grado di inoltrare correttamente la richiesta. Un'ampia gamma di problemi di configurazione si esprime con un errore 502, pertanto sono necessarie ulteriori informazioni per una corretta risoluzione dei problemi.
Il posto principale in cui cercare ulteriori informazioni è nei log degli errori di Nginx. In genere, questo ti dirà quali condizioni hanno causato problemi durante l'evento 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() a unix:/run/gunicorn.sock fallito (2: Nessun file o 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
all'interno della directory /run
, generalmente significa che il file socket systemd non è stato in grado di crearlo. Torna alla sezione sul controllo del file socket Gunicorn per eseguire i passaggi di risoluzione dei problemi per Gunicorn.
connect() a unix:/run/gunicorn.sock fallito (13: Autorizzazione negata)
Ciò indica che Nginx non è stato in grado di connettersi al socket Gunicorn a causa di problemi di autorizzazione. Questo può accadere quando la procedura viene seguita utilizzando l'utente root invece di un utente sudo
. Sebbene systemd sia in grado di creare il file socket Gunicorn, Nginx non è in grado di accedervi.
Questo può accadere 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 tuo file socket al comando namei
:
- namei -l /run/gunicorn.sock
Outputf: /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 universali (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.
Django sta visualizzando: 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 di Postgres sia in esecuzione digitando:
- sudo systemctl status postgresql
Se non lo è, 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 possono essere utili:
- Controlla i log del processo Nginx digitando:
sudo journalctl -u nginx
- Controlla i log di accesso 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
Man mano che aggiorni la configurazione o l'applicazione, probabilmente dovrai riavviare i processi per adeguarti alle modifiche.
Se aggiorni la tua applicazione Django, puoi riavviare il processo Gunicorn per raccogliere 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 del server Nginx, prova la configurazione e quindi Nginx digitando:
- sudo nginx -t && sudo systemctl restart nginx
Questi comandi sono utili per rilevare le modifiche mentre modifichi la configurazione.
Conclusione
In questa guida, imposti 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 funga da proxy inverso per gestire le connessioni client e servire il progetto corretto in base alla richiesta del client.
Django aiuta a creare progetti e applicazioni fornendo molti dei pezzi comuni, permettendoti di concentrarti sugli elementi unici. Sfruttando la catena di strumenti generale descritta in questo articolo, puoi servire le applicazioni che crei da un singolo server.