Comment configurer Django avec Postgres, Nginx et Gunicorn sur Ubuntu
Introduction
Django est un framework Web puissant qui peut vous aider à faire décoller votre application ou votre site Web Python. Django inclut un serveur de développement simplifié pour tester votre code localement, mais pour tout ce qui est même légèrement lié à la production, un serveur Web plus sécurisé et plus puissant est requis.
Dans ce guide, vous installerez et configurerez certains composants sur Ubuntu 22.04 (ou toute autre version d'Ubuntu prise en charge) pour prendre en charge et servir les applications Django. Vous configurerez une base de données PostgreSQL au lieu d'utiliser la base de données SQLite par défaut. Vous configurerez le serveur d’applications Gunicorn pour qu’il s’interface avec vos applications. Vous configurerez ensuite Nginx pour inverser le proxy de Gunicorn, vous donnant accès à ses fonctionnalités de sécurité et de performances pour servir vos applications.
Déployez vos applications depuis GitHub à l'aide de DigitalOcean App Platform. Laissez DigitalOcean se concentrer sur la mise à l’échelle de votre application.
Vous installerez Django dans un environnement virtuel. Installer Django dans un environnement spécifique à votre projet permettra de gérer séparément vos projets et leurs exigences.
Une fois que votre base de données et votre application sont opérationnelles, vous installerez et configurerez le serveur d'applications Gunicorn. Cela servira d'interface à notre application, traduisant les demandes des clients de HTTP en appels Python que notre application peut traiter. Vous configurerez ensuite Nginx devant Gunicorn pour profiter de ses mécanismes de gestion de connexion hautes performances et de ses fonctionnalités de sécurité faciles à mettre en œuvre.
Commençons.
Conditions préalables
Si vous utilisez Ubuntu version 16.04 ou inférieure, nous vous recommandons de mettre à niveau vers une version plus récente car Ubuntu ne prend plus en charge ces versions. Cette collection de guides vous aidera à mettre à niveau votre version d'Ubuntu.
Pour compléter ce guide, vous avez besoin d'un serveur exécutant Ubuntu, ainsi que d'un utilisateur non root disposant des privilèges sudo
et d'un pare-feu actif. Pour obtenir des conseils sur la façon de les configurer, veuillez choisir votre distribution dans cette liste et suivre notre guide de configuration initiale du serveur.
Étapes pour configurer Django, Nginx et Gunicorn
- Installez les packages à partir des référentiels Ubuntu
- Création de la base de données PostgreSQL et de l'utilisateur
- Créer un environnement virtuel Python pour le projet
- Créer et configurer un nouveau projet Django
- Terminer la configuration du projet Django
- Testez la capacité de Gunicorn à servir le projet
- Création de fichiers de socket et de service Gunicorn systemd
- Vérifier le fichier de socket Gunicorn
- Test de l'activation du socket
- Configurer Nginx pour proxy passer à Gunicorn
- Dépannage de Nginx et Gunicorn
Étape 1 — Installation des packages à partir des référentiels Ubuntu
Pour commencer le processus, vous téléchargerez et installerez tous les éléments dont vous avez besoin à partir des référentiels Ubuntu. Plus tard, vous utiliserez le gestionnaire de packages Python pip
pour installer des composants supplémentaires.
Vous devez d’abord mettre à jour l’index du package apt
local, puis télécharger et installer les packages. Les packages que vous installez dépendent de la version de Python que votre projet utilisera.
Si vous utilisez Django avec Python 3, tapez :
sudo apt update
sudo apt install python3-venv python3-dev libpq-dev postgresql postgresql-contrib nginx curl
Cette commande installera un outil pour créer des environnements virtuels pour vos projets Python, les fichiers de développement Python nécessaires pour construire Gunicorn ultérieurement, le système de base de données Postgres et les bibliothèques nécessaires pour interagir avec lui, ainsi que le serveur Web Nginx.
Étape 2 — Création de la base de données PostgreSQL et de l'utilisateur
Vous pouvez maintenant vous lancer directement et créer une base de données et un utilisateur de base de données pour notre application Django.
Par défaut, Postgres utilise un schéma d'authentification appelé « authentification par les pairs » pour les connexions locales. Fondamentalement, cela signifie que si le nom d'utilisateur du système d'exploitation de l'utilisateur correspond à un nom d'utilisateur Postgres valide, cet utilisateur peut se connecter sans autre authentification.
Lors de l'installation de Postgres, un utilisateur du système d'exploitation nommé postgres
a été créé pour correspondre à l'utilisateur administratif postgres
PostgreSQL. Vous devez utiliser cet utilisateur pour effectuer des tâches administratives. Vous pouvez utiliser sudo et transmettre le nom d'utilisateur avec l'option -u
.
Connectez-vous à une session Postgres interactive en tapant :
sudo -u postgres psql
Vous recevrez une invite PostgreSQL où vous pourrez configurer nos exigences.
Tout d’abord, créez une base de données pour votre projet :
CREATE DATABASE myproject;
Remarque : Chaque instruction Postgres doit se terminer par un point-virgule, alors assurez-vous que votre commande se termine par un si vous rencontrez des problèmes.
Ensuite, créez un utilisateur de base de données pour notre projet. Assurez-vous de sélectionner un mot de passe sécurisé :
CREATE USER myprojectuser WITH PASSWORD 'password';
Ensuite, vous modifierez quelques paramètres de connexion pour l’utilisateur que vous venez de créer. Cela accélérera les opérations de la base de données afin que les valeurs correctes n'aient pas besoin d'être interrogées et définies à chaque fois qu'une connexion est établie.
Vous définirez le codage de caractères par défaut sur UTF-8
, ce que Django attend. Vous définissez également le schéma d'isolation des transactions par défaut sur « lecture validée », qui bloque les lectures des transactions non validées. Enfin, vous définissez le fuseau horaire. Par défaut, les projets Django seront configurés pour utiliser UTC
. Ce sont toutes des recommandations du projet Django lui-même :
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';
Vous pouvez désormais accorder au nouvel utilisateur l'accès pour administrer la nouvelle base de données :
GRANT ALL PRIVILEGES ON DATABASE myproject TO myprojectuser;
Lorsque vous avez terminé, quittez l'invite PostgreSQL en tapant :
\q
Postgres est désormais configuré pour que Django puisse se connecter et gérer les informations de sa base de données.
Étape 3 — Création d'un environnement virtuel Python pour votre projet
Maintenant que votre base de données est prête, vous pouvez commencer à répondre aux autres exigences de votre projet. Vous installerez les exigences Python dans un environnement virtuel pour une gestion plus facile.
Tout d'abord, créez et modifiez un répertoire dans lequel vous pouvez conserver vos fichiers de projet :
mkdir ~/myprojectdir
cd ~/myprojectdir
Dans le répertoire du projet, créez un environnement virtuel Python en tapant :
python3 -m venv myprojectenv
Cela créera un répertoire appelé myprojectenv
dans votre répertoire myprojectdir
. À l'intérieur, il installera une version locale de Python et une version locale de pip
pour gérer les packages. Vous pouvez utiliser cette structure d'environnement virtuel pour installer et configurer un environnement Python isolé pour tout projet que vous souhaitez créer.
Avant d'installer les exigences Python de votre projet, vous devrez activer l'environnement virtuel. Vous pouvez le faire en tapant :
source myprojectenv/bin/activate
Votre invite doit changer pour indiquer que vous travaillez désormais dans un environnement virtuel Python. Cela ressemblera à ceci : (myprojectenv)user@host:~/myprojectdir$
.
Avec votre environnement virtuel actif, installez Django, Gunicorn et l'adaptateur PostgreSQL psycopg2
avec l'instance locale de pip
:
Remarque : Lorsque l'environnement virtuel est activé (lorsque votre invite est précédée de (myprojectenv)
), utilisez pip
au lieu de pip3
, même si vous utilisez Python 3. La copie de l'outil dans l'environnement virtuel est toujours nommée pip
, quelle que soit la version de Python.
pip install django gunicorn psycopg2-binary
Vous devriez maintenant disposer de tous les logiciels nécessaires pour démarrer un projet Django.
Étape 4 — Création et configuration d'un nouveau projet Django
Une fois vos composants Python installés, vous pouvez maintenant créer les fichiers de projet Django réels.
Puisque vous disposez déjà d’un répertoire de projet, vous demanderez à Django d’installer les fichiers ici. Il créera un répertoire de deuxième niveau avec le code réel, ce qui est normal, et placera un script de gestion dans ce répertoire. La clé est que vous définissez explicitement le répertoire au lieu de permettre à Django de prendre des décisions relatives à notre répertoire actuel :
django-admin startproject myproject ~/myprojectdir
À ce stade, le répertoire de votre projet (~/myprojectdir
dans cet exemple) doit avoir le contenu suivant :
~/myprojectdir/manage.py
: Un script de gestion de projet Django.~/myprojectdir/myproject/
: Le package du projet Django. Celui-ci doit contenir les éléments__init__.py
,settings.py
,urls.py
,asgi.py
etwsgi.py
.~/myprojectdir/myprojectenv/
: le répertoire de l'environnement virtuel que vous avez créé précédemment.
La première chose que vous devez faire avec vos fichiers de projet nouvellement créés est d'ajuster les paramètres. Ouvrez le fichier de paramètres dans votre éditeur de texte :
nano ~/myprojectdir/myproject/settings.py
Commencez par localiser la directive ALLOWED_HOSTS
. Celui-ci définit une liste d'adresses du serveur ou de noms de domaine pouvant être utilisés pour se connecter à l'instance Django. Toute demande entrante avec un en-tête Host qui ne figure pas dans cette liste déclenchera une exception. Django nécessite que vous définissiez ceci pour éviter une certaine classe de vulnérabilité de sécurité.
Entre crochets, répertoriez les adresses IP ou les noms de domaine associés à votre serveur Django. Chaque élément doit être répertorié entre guillemets avec des entrées séparées par une virgule. Si vous souhaitez des demandes pour un domaine entier et des sous-domaines, ajoutez un point au début de l'entrée. Dans l'extrait ci-dessous, vous trouverez quelques exemples commentés utilisés pour démontrer :
Remarque : Assurez-vous d'inclure localhost
comme l'une des options, car vous effectuerez un proxy des connexions via une instance 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']
Ensuite, recherchez la section qui configure l'accès à la base de données. Il commencera par BASES DE DONNÉES
. La configuration dans le fichier concerne une base de données SQLite. Vous avez déjà créé une base de données PostgreSQL pour notre projet, vous devez donc ajuster les paramètres.
Modifiez les paramètres avec les informations de votre base de données PostgreSQL. Vous dites à Django d'utiliser l'adaptateur psycopg2
que vous avez installé avec pip
. Vous devez indiquer le nom de la base de données, le nom d'utilisateur de la base de données, le mot de passe de l'utilisateur de la base de données, puis spécifier que la base de données se trouve sur l'ordinateur local. Vous pouvez laisser le paramètre PORT
sous forme de chaîne vide :
. . .
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'myproject',
'USER': 'myprojectuser',
'PASSWORD': 'password',
'HOST': 'localhost',
'PORT': '',
}
}
. . .
Ensuite, descendez vers le bas du fichier et ajoutez un paramètre indiquant où les fichiers statiques doivent être placés. Cela est nécessaire pour que Nginx puisse gérer les demandes concernant ces éléments. La ligne suivante indique à Django de les placer dans un répertoire appelé static
dans le répertoire de base du projet :
. . .
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/')
Enregistrez et fermez le fichier lorsque vous avez terminé.
Étape 5 — Terminer la configuration initiale du projet
Vous pouvez désormais migrer le schéma de base de données initial vers notre base de données PostgreSQL à l'aide du script de gestion :
~/myprojectdir/manage.py makemigrations
~/myprojectdir/manage.py migrate
Créez un utilisateur administratif pour le projet en tapant :
~/myprojectdir/manage.py createsuperuser
Vous devrez sélectionner un nom d'utilisateur, fournir une adresse e-mail, puis choisir et confirmer un mot de passe.
Vous pouvez collecter tout le contenu statique dans l'emplacement du répertoire que vous avez configuré en tapant :
~/myprojectdir/manage.py collectstatic
Vous devrez confirmer l'opération. Les fichiers statiques seront ensuite placés dans un répertoire appelé static
dans le répertoire de votre projet.
Si vous avez suivi le guide de configuration initiale du serveur, vous devriez disposer d'un pare-feu UFW protégeant votre serveur. Afin de tester le serveur de développement, vous devez autoriser l'accès au port que vous utiliserez.
Créez une exception pour le port 8000 en tapant :
sudo ufw allow 8000
Enfin, vous pouvez tester votre projet en démarrant le serveur de développement Django avec cette commande :
~/myprojectdir/manage.py runserver 0.0.0.0:8000
Dans votre navigateur Web, visitez le nom de domaine ou l'adresse IP de votre serveur suivi de :8000
:
http://server_domain_or_IP:8000
Vous devriez recevoir la page d'index Django par défaut :
Si vous ajoutez /admin
à la fin de l'URL dans la barre d'adresse, vous serez invité à saisir le nom d'utilisateur et le mot de passe administratif que vous avez créés avec la commande createsuperuser
:
Après vous être authentifié, vous pouvez accéder à l'interface d'administration de Django par défaut :
Lorsque vous avez terminé l'exploration, appuyez sur CTRL-C dans la fenêtre du terminal pour arrêter le serveur de développement.
Étape 6 — Tester la capacité de Gunicorn à servir le projet
La dernière chose que vous devez faire avant de quitter votre environnement virtuel est de tester Gunicorn pour vous assurer qu'il peut servir l'application. Vous pouvez le faire en entrant dans le répertoire du projet et en utilisant gunicorn
pour charger le module WSGI du projet :
cd ~/myprojectdir
gunicorn --bind 0.0.0.0:8000 myproject.wsgi
Cela démarrera Gunicorn sur la même interface que celle sur laquelle le serveur de développement Django était exécuté. Vous pouvez revenir en arrière et tester à nouveau l'application dans votre navigateur.
Remarque : L'interface d'administration n'aura aucun style appliqué puisque Gunicorn ne sait pas comment trouver le contenu CSS statique responsable de cela.
Vous avez transmis un module à Gunicorn en spécifiant le chemin d'accès relatif au fichier wsgi.py
de Django, qui est le point d'entrée de votre application, en utilisant la syntaxe de module de Python. À l'intérieur de ce fichier, une fonction appelée application
est définie, qui est utilisée pour communiquer avec l'application. Pour en savoir plus sur la spécification WSGI, cliquez ici.
Lorsque vous avez terminé les tests, appuyez sur CTRL-C dans la fenêtre du terminal pour arrêter Gunicorn.
Vous avez maintenant terminé de configurer votre application Django. Vous pouvez quitter notre environnement virtuel en tapant :
deactivate
L'indicateur d'environnement virtuel dans votre invite sera supprimé.
Étape 7 — Création de fichiers de socket et de service systemd pour Gunicorn
Vous avez testé que Gunicorn peut interagir avec notre application Django, mais vous devez maintenant implémenter une manière plus robuste de démarrer et d'arrêter le serveur d'applications. Pour ce faire, vous créerez des fichiers de service et de socket systemd.
Le socket Gunicorn sera créé au démarrage et écoutera les connexions. Lorsqu'une connexion se produit, systemd démarrera automatiquement le processus Gunicorn pour gérer la connexion.
Commencez par créer et ouvrir un fichier de socket systemd pour Gunicorn avec les privilèges sudo
:
sudo nano /etc/systemd/system/gunicorn.socket
À l'intérieur, vous créerez une section [Unit]
pour décrire le socket, une section [Socket]
pour définir l'emplacement du socket et un [Install]
pour vous assurer que le socket est créé au bon moment :
[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/run/gunicorn.sock
[Install]
WantedBy=sockets.target
Enregistrez et fermez le fichier lorsque vous avez terminé.
Ensuite, créez et ouvrez un fichier de service systemd pour Gunicorn avec les privilèges sudo
dans votre éditeur de texte. Le nom du fichier de service doit correspondre au nom du fichier du socket, à l'exception de l'extension :
sudo nano /etc/systemd/system/gunicorn.service
Commencez par la section [Unit]
, qui est utilisée pour spécifier les métadonnées et les dépendances. Mettez une description du service ici et dites au système d'initialisation de ne le démarrer qu'une fois que la cible réseau a été atteinte. Étant donné que votre service s'appuie sur le socket du fichier socket, vous devez inclure une directive Requires
pour indiquer cette relation :
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
Ensuite, vous ouvrirez la section [Service]
. Spécifiez l'utilisateur et le groupe sous lesquels vous souhaitez exécuter le traitement. Vous donnerez à votre compte utilisateur habituel la propriété du processus puisqu’il possède tous les fichiers pertinents. Vous donnerez la propriété du groupe au groupe www-data
afin que Nginx puisse communiquer facilement avec Gunicorn.
Ensuite, vous tracerez le répertoire de travail et spécifierez la commande à utiliser pour démarrer le service. Dans ce cas, vous devez spécifier le chemin complet de l'exécutable Gunicorn, qui est installé dans notre environnement virtuel. Vous lierez ensuite le processus au socket Unix que vous avez créé dans le répertoire /run
afin que le processus puisse communiquer avec Nginx. Vous enregistrez toutes les données sur la sortie standard afin que le processus journald
puisse collecter les journaux Gunicorn. Vous pouvez également spécifier ici tous les ajustements facultatifs de Gunicorn. Par exemple, vous avez spécifié 3 processus de travail dans ce cas :
[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
Enfin, vous ajouterez une section [Install]
. Cela indiquera à systemd à quoi lier ce service si vous lui permettez de démarrer au démarrage. Vous souhaitez que ce service démarre lorsque le système multi-utilisateurs standard est opérationnel :
[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
Avec cela, votre fichier de service systemd est terminé. Enregistrez-le et fermez-le maintenant.
Vous pouvez maintenant démarrer et activer le socket Gunicorn. Cela créera le fichier socket sur /run/gunicorn.sock
maintenant et au démarrage. Lorsqu'une connexion est établie sur ce socket, systemd démarrera automatiquement gunicorn.service
pour la gérer :
sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket
Vous pouvez confirmer que l'opération a réussi en recherchant le fichier socket.
Étape 8 — Vérification du fichier de socket Gunicorn
Vérifiez l'état du processus pour savoir s'il a pu démarrer :
sudo systemctl status gunicorn.socket
Vous devriez recevoir une sortie comme celle-ci :
● 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.
Ensuite, vérifiez l'existence du fichier gunicorn.sock
dans le répertoire /run
:
file /run/gunicorn.sock
/run/gunicorn.sock: socket
Si la commande systemctl status
a indiqué qu'une erreur s'est produite ou si vous ne trouvez pas le fichier gunicorn.sock
dans le répertoire, c'est une indication que le socket Gunicorn n'a pas pu être créé correctement. Vérifiez les journaux du socket Gunicorn en tapant :
sudo journalctl -u gunicorn.socket
Examinez à nouveau votre fichier /etc/systemd/system/gunicorn.socket
pour résoudre tout problème avant de continuer.
Étape 9 - Test de l'activation du socket
Actuellement, si vous avez uniquement démarré l'unité gunicorn.socket
, le gunicorn.service
ne sera pas encore actif puisque le socket n'a encore reçu aucune connexion. Vous pouvez le vérifier en tapant :
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
Pour tester le mécanisme d'activation du socket, vous pouvez envoyer une connexion au socket via curl
en tapant :
curl --unix-socket /run/gunicorn.sock localhost
Vous devriez recevoir la sortie HTML de votre application dans le terminal. Cela indique que Gunicorn a été démarré et a pu servir votre application Django. Vous pouvez vérifier que le service Gunicorn est exécuté en tapant :
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"
Si la sortie de curl
ou la sortie de systemctl status
indique qu'un problème s'est produit, consultez les journaux pour plus de détails :
sudo journalctl -u gunicorn
Vérifiez votre fichier /etc/systemd/system/gunicorn.service
pour détecter tout problème. Si vous apportez des modifications au fichier /etc/systemd/system/gunicorn.service
, rechargez le démon pour relire la définition du service et redémarrez le processus Gunicorn en tapant :
sudo systemctl daemon-reload
sudo systemctl restart gunicorn
Assurez-vous de résoudre les problèmes ci-dessus avant de continuer.
Étape 10 — Configurer Nginx pour passer par proxy à Gunicorn
Maintenant que Gunicorn est configuré, vous devez configurer Nginx pour transmettre le trafic au processus.
Commencez par créer et ouvrir un nouveau bloc serveur dans le répertoire sites-available
de Nginx :
sudo nano /etc/nginx/sites-available/myproject
À l’intérieur, ouvrez un nouveau bloc de serveur. Vous commencerez par préciser que ce bloc doit écouter sur le port normal 80 et qu'il doit répondre au nom de domaine ou à l'adresse IP de votre serveur :
server {
listen 80;
server_name server_domain_or_IP;
}
Ensuite, vous demanderez à Nginx d’ignorer tout problème lié à la recherche d’un favicon. Vous lui indiquerez également où trouver les ressources statiques que vous avez collectées dans votre répertoire ~/myprojectdir/static
. Tous ces fichiers ont un préfixe URI standard de « /static », vous pouvez donc créer un bloc d'emplacement pour correspondre à ces requêtes :
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;
}
}
Enfin, créez un bloc location/{}
pour correspondre à toutes les autres requêtes. À l'intérieur de cet emplacement, vous inclurez le fichier standard proxy_params
inclus avec l'installation de Nginx, puis transmettrez le trafic directement au 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;
}
}
Enregistrez et fermez le fichier lorsque vous avez terminé. Maintenant, vous pouvez activer le fichier en le liant au répertoire sites-enabled
:
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
Testez votre configuration Nginx pour les erreurs de syntaxe en tapant :
sudo nginx -t
Si aucune erreur n'est signalée, continuez et redémarrez Nginx en tapant :
sudo systemctl restart nginx
Enfin, vous devez ouvrir votre pare-feu au trafic normal sur le port 80. Puisque vous n'avez plus besoin d'accéder au serveur de développement, vous pouvez également supprimer la règle d'ouverture du port 8000 :
sudo ufw delete allow 8000
sudo ufw allow 'Nginx Full'
Vous devriez maintenant pouvoir accéder au domaine ou à l’adresse IP de votre serveur pour afficher votre application.
Remarque : Après avoir configuré Nginx, l'étape suivante doit consister à sécuriser le trafic vers le serveur à l'aide de SSL/TLS. Ceci est important car sans cela, toutes les informations, y compris les mots de passe, sont envoyées sur le réseau en texte brut.
Si vous possédez un nom de domaine, le moyen le plus simple d’obtenir un certificat SSL pour sécuriser votre trafic consiste à utiliser Let’s Encrypt. Suivez ce guide pour Ubuntu 22.04/Ubuntu 20.04/Ubuntu 18.04 pour configurer Let's Encrypt avec Nginx sur Ubuntu 22.04. Suivez la procédure en utilisant le bloc serveur Nginx que vous avez créé dans ce guide.
Étape 11 — Dépannage de Nginx et Gunicorn
Si cette dernière étape n'affiche pas votre application, vous devrez dépanner votre installation.
Nginx affiche la page par défaut au lieu de l'application Django
Si Nginx affiche la page par défaut au lieu de proxy vers votre application, cela signifie généralement que vous devez ajuster le server_name
dans le /etc/nginx/sites-available/myproject
pour pointer vers l'adresse IP ou le nom de domaine de votre serveur.
Nginx utilise le server_name
pour déterminer quel bloc de serveur utiliser pour répondre aux requêtes. Si vous recevez la page Nginx par défaut, c'est un signe que Nginx n'a pas été en mesure de faire correspondre explicitement la demande à un bloc de serveur, il s'appuie donc sur le bloc par défaut défini dans /etc/nginx/sites-available/ par défaut
.
Le server_name
dans le bloc serveur de votre projet doit être plus spécifique que celui du bloc serveur par défaut pour être sélectionné.
Nginx affiche une erreur 502 Bad Gateway au lieu de l'application Django
Une erreur 502 indique que Nginx ne parvient pas à transmettre avec succès la requête par proxy. Un large éventail de problèmes de configuration s'expriment par une erreur 502, des informations supplémentaires sont donc nécessaires pour un dépannage correct.
Le principal endroit où rechercher plus d’informations se trouve dans les journaux d’erreurs de Nginx. Généralement, cela vous indiquera quelles conditions ont causé des problèmes lors de l'événement de proxy. Suivez les journaux d'erreurs Nginx en tapant :
sudo tail -F /var/log/nginx/error.log
Maintenant, faites une autre requête dans votre navigateur pour générer une nouvelle erreur (essayez de rafraîchir la page). Vous devriez recevoir un nouveau message d'erreur écrit dans le journal. Si vous regardez le message, cela devrait vous aider à cerner le problème.
Vous pourriez recevoir le message suivant :
connect() to unix:/run/gunicorn.sock failed (2: No such file or directory)
Cela indique que Nginx n'a pas pu trouver le fichier gunicorn.sock
à l'emplacement indiqué. Vous devez comparer l'emplacement proxy_pass
défini dans le fichier /etc/nginx/sites-available/myproject
à l'emplacement réel du fichier gunicorn.sock
généré par l'unité systemd gunicorn.socket
.
Si vous ne trouvez pas de fichier gunicorn.sock
dans le répertoire /run
, cela signifie généralement que le fichier socket systemd n'a pas pu le créer. Revenez à la section sur la vérification du fichier de socket Gunicorn pour suivre les étapes de dépannage pour Gunicorn.
connect() to unix:/run/gunicorn.sock failed (13: Permission denied)
Cela indique que Nginx n'a pas pu se connecter au socket Gunicorn en raison de problèmes d'autorisations. Cela peut se produire lorsque la procédure est suivie en utilisant l'utilisateur root au lieu d'un utilisateur sudo
. Bien que systemd soit capable de créer le fichier de socket Gunicorn, Nginx ne peut pas y accéder.
Cela peut se produire s'il existe des autorisations limitées à tout moment entre le répertoire racine (/
) et le fichier gunicorn.sock
. Vous pouvez consulter les autorisations et les valeurs de propriété du fichier socket et de chacun de ses répertoires parents en transmettant le chemin absolu de votre fichier socket à la commande 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
La sortie affiche les autorisations de chacun des composants de répertoire. En examinant les autorisations (première colonne), le propriétaire (deuxième colonne) et le propriétaire du groupe (troisième colonne), vous pouvez déterminer quel type d'accès est autorisé au fichier socket.
Dans l'exemple ci-dessus, le fichier socket et chacun des répertoires menant au fichier socket ont des autorisations mondiales de lecture et d'exécution (la colonne des autorisations pour les répertoires se termine par r-x
au lieu de ---
). Le processus Nginx devrait pouvoir accéder au socket avec succès.
Si l'un des répertoires menant au socket ne dispose pas d'autorisations mondiales de lecture et d'exécution, Nginx ne pourra pas accéder au socket sans autoriser les autorisations mondiales de lecture et d'exécution ou sans s'assurer que la propriété du groupe est accordée à un groupe dont Nginx fait partie. de.
Django affiche : « Impossible de se connecter au serveur : connexion refusée »
Un message que vous pouvez recevoir de Django lorsque vous tentez d'accéder à des parties de l'application dans le navigateur Web est :
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?
Cela indique que Django ne parvient pas à se connecter à la base de données Postgres. Assurez-vous que l'instance Postgres est en cours d'exécution en tapant :
sudo systemctl status postgresql
Si ce n'est pas le cas, vous pouvez le démarrer et lui permettre de démarrer automatiquement au démarrage (s'il n'est pas déjà configuré pour le faire) en tapant :
sudo systemctl start postgresql
sudo systemctl enable postgresql
Si vous rencontrez toujours des problèmes, assurez-vous que les paramètres de base de données définis dans le fichier ~/myprojectdir/myproject/settings.py
sont corrects.
Dépannage supplémentaire
Pour un dépannage supplémentaire, les journaux peuvent aider à identifier les causes profondes. Vérifiez chacun d’eux tour à tour et recherchez les messages indiquant les zones problématiques.
Les journaux suivants peuvent être utiles :
- Vérifiez les journaux du processus Nginx en tapant :
sudo journalctl -u nginx
- Vérifiez les journaux d'accès Nginx en tapant :
sudo less /var/log/nginx/access.log
- Vérifiez les journaux d'erreurs Nginx en tapant :
sudo less /var/log/nginx/error.log
- Vérifiez les journaux de l'application Gunicorn en tapant :
sudo journalctl -u gunicorn
- Vérifiez les journaux de socket Gunicorn en tapant :
sudo journalctl -u gunicorn.socket
Lorsque vous mettez à jour votre configuration ou votre application, vous devrez probablement redémarrer les processus pour vous adapter à vos modifications.
Si vous mettez à jour votre application Django, vous pouvez redémarrer le processus Gunicorn pour récupérer les modifications en tapant :
sudo systemctl restart gunicorn
Si vous modifiez le socket ou les fichiers de service Gunicorn, rechargez le démon et redémarrez le processus en tapant :
sudo systemctl daemon-reload
sudo systemctl restart gunicorn.socket gunicorn.service
Si vous modifiez la configuration du bloc serveur Nginx, testez la configuration puis Nginx en tapant :
sudo nginx -t && sudo systemctl restart nginx
Ces commandes sont utiles pour récupérer les modifications lorsque vous ajustez votre configuration.
Conclusion
Dans ce guide, vous configurez un projet Django dans son propre environnement virtuel. Vous avez configuré Gunicorn pour traduire les demandes des clients afin que Django puisse les gérer. Ensuite, vous configurez Nginx pour qu'il agisse comme un proxy inverse pour gérer les connexions client et servir le bon projet en fonction de la demande du client.
Django simplifie la création de projets et d'applications en fournissant de nombreux éléments communs, vous permettant ainsi de vous concentrer sur les éléments uniques. En tirant parti de la chaîne d’outils générale décrite dans cet article, vous pouvez facilement servir les applications que vous créez à partir d’un seul serveur.