introduction
Django est un puissant framework Web 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 légèrement lié à la production, un serveur Web plus sécurisé et plus puissant est requis.
Dans ce guide, nous montrerons comment installer et configurer certains composants sous Ubuntu 18.04 pour prendre en charge et servir des applications Django. Nous allons configurer une base de données PostgreSQL au lieu d'utiliser la base de données SQLite par défaut. Nous allons configurer le serveur d’applications Gunicorn pour l’interface avec nos applications. Nous allons ensuite configurer Nginx pour inverser le proxy sur Gunicorn, nous donnant ainsi accès à ses fonctionnalités de sécurité et de performances pour servir nos applications.
Prérequis et objectifs
Pour compléter ce guide, vous devez avoir une nouvelle instance de serveur Ubuntu 18.04 avec un pare-feu de base et un utilisateur non root avec les privilègessudo
configurés. Vous pouvez apprendre comment configurer cela en parcourant nosinitial server setup guide.
Nous installerons Django dans un environnement virtuel. L'installation de Django dans un environnement spécifique à votre projet permettra à vos projets et à leurs exigences d'être traités séparément.
Une fois que notre base de données et notre application seront opérationnelles, nous installerons et configurerons le serveur d’applications Gunicorn. Cela servira d'interface avec notre application, traduisant les demandes des clients HTTP en appels Python que notre application peut traiter. Nous installerons ensuite Nginx devant Gunicorn pour tirer parti de ses mécanismes de traitement des connexions hautes performances et de ses fonctionnalités de sécurité faciles à mettre en œuvre.
Commençons.
Installation des packages à partir des référentiels Ubuntu
Pour commencer le processus, nous allons télécharger et installer tous les éléments dont nous avons besoin à partir des référentiels Ubuntu. Nous utiliserons le gestionnaire de packages Pythonpip
pour installer des composants supplémentaires un peu plus tard.
Nous devons mettre à jour l'index local des packagesapt
, puis télécharger et installer les packages. Les packages que nous installons dépendent de la version de Python que votre projet utilisera.
Si vous utilisez Django avecPython 3, tapez:
sudo apt update
sudo apt install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx curl
Django 1.11 est la dernière version de Django qui supportera Python 2. Si vous démarrez de nouveaux projets, il est fortement recommandé de choisir Python 3. Si vous devez toujours utiliserPython 2, tapez:
sudo apt update
sudo apt install python-pip python-dev libpq-dev postgresql postgresql-contrib nginx curl
Cela installerapip
, les fichiers de développement Python nécessaires pour construire Gunicorn plus tard, le système de base de données Postgres et les bibliothèques nécessaires pour interagir avec lui, et le serveur Web Nginx.
Création de la base de données et de l'utilisateur PostgreSQL
Nous allons 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 homologue» pour les connexions locales. En gros, 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 PostgreSQL depostgres
. Nous devons utiliser cet utilisateur pour effectuer des tâches administratives. Nous pouvons utiliser sudo et passer le nom d'utilisateur avec l'option-u
.
Connectez-vous à une session interactive Postgres en tapant:
sudo -u postgres psql
Vous recevrez une invite PostgreSQL dans laquelle nous pourrons configurer nos exigences.
Commencez par créer une base de données pour votre projet:
CREATE DATABASE myproject;
[.note] #Note: Chaque instruction Postgres doit se terminer par un point-virgule, assurez-vous donc 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, nous allons modifier quelques paramètres de connexion pour l'utilisateur que nous venons de créer. Cela accélérera les opérations de la base de données, de sorte qu'il ne sera plus nécessaire de rechercher les valeurs correctes et de les définir à chaque fois qu'une connexion sera établie.
Nous définissons l'encodage par défaut surUTF-8
, ce que Django attend. Nous définissons également le schéma d'isolation de transaction par défaut sur «lecture validée», ce qui bloque les lectures des transactions non validées. Enfin, nous établissons le fuseau horaire. Par défaut, nos projets Django seront configurés pour utiliserUTC
. Ce sont toutes les recommandations dethe Django project itself:
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';
Maintenant, nous pouvons donner à notre nouvel utilisateur un accès pour administrer notre nouvelle base de données:
GRANT ALL PRIVILEGES ON DATABASE myproject TO myprojectuser;
Lorsque vous avez terminé, quittez l'invite de PostgreSQL en tapant:
\q
Postgres est maintenant configuré pour que Django puisse se connecter et gérer ses informations de base de données.
Création d'un environnement virtuel Python pour votre projet
Maintenant que nous avons notre base de données, nous pouvons commencer à préparer le reste des exigences de notre projet. Nous allons installer nos exigences Python dans un environnement virtuel pour une gestion plus facile.
Pour ce faire, nous devons d'abord accéder à la commandevirtualenv
. Nous pouvons l'installer avecpip
.
Si vous utilisezPython 3, mettez à niveaupip
et installez le package en tapant:
sudo -H pip3 install --upgrade pip
sudo -H pip3 install virtualenv
Si vous utilisezPython 2, mettez à niveaupip
et installez le package en tapant:
sudo -H pip install --upgrade pip
sudo -H pip install virtualenv
Avecvirtualenv
installé, nous pouvons commencer à former notre projet. Créez et déplacez-vous dans un répertoire où nous pouvons conserver nos fichiers de projet:
mkdir ~/myprojectdir
cd ~/myprojectdir
Dans le répertoire du projet, créez un environnement virtuel Python en tapant:
virtualenv myprojectenv
Cela créera un répertoire appelémyprojectenv
dans votre répertoiremyprojectdir
. À l'intérieur, il installera une version locale de Python et une version locale depip
. Nous pouvons l'utiliser pour installer et configurer un environnement Python isolé pour notre projet.
Avant d’installer les exigences Python de notre projet, nous devons activer l’environnement virtuel. Vous pouvez le faire en tapant:
source myprojectenv/bin/activate
Votre invite devrait changer pour indiquer que vous travaillez maintenant dans un environnement virtuel Python. Cela ressemblera à quelque chose comme ceci:(myprojectenv)user@host:~/myprojectdir$
.
Avec votre environnement virtuel actif, installez Django, Gunicorn et l'adaptateur PostgreSQLpsycopg2
avec l'instance locale depip
:
[.note] #Note: Lorsque l'environnement virtuel est activé (lorsque votre invite est précédée de(myprojectenv)
), utilisezpip
au lieu depip3
, même si vous utilisez Python 3. La copie de l’environnement virtuel de l’outil est toujours nomméepip
, quelle que soit la version de Python.
#
pip install django gunicorn psycopg2-binary
Vous devriez maintenant avoir tous les logiciels nécessaires pour démarrer un projet Django.
Créer et configurer un nouveau projet Django
Avec nos composants Python installés, nous pouvons créer les fichiers de projet Django réels.
Création du projet Django
Comme nous avons déjà un répertoire de projet, nous demanderons à Django d’installer les fichiers ici. Il créera un répertoire de second niveau avec le code réel, ce qui est normal, et placera un script de gestion dans ce répertoire. La clé de ceci est que nous définissons explicitement le répertoire au lieu de permettre à Django de prendre des décisions relatives à notre répertoire actuel:
django-admin.py startproject myproject ~/myprojectdir
À ce stade, votre répertoire de projet (~/myprojectdir
dans notre cas) doit avoir le contenu suivant:
-
~/myprojectdir/manage.py
: un script de gestion de projet Django. -
~/myprojectdir/myproject/
: le package du projet Django. Il doit contenir les fichiers__init__.py
,settings.py
,urls.py
etwsgi.py
. -
~/myprojectdir/myprojectenv/
: le répertoire d'environnement virtuel que nous avons créé précédemment.
Ajuster les paramètres du projet
La première chose à faire avec nos 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 directiveALLOWED_HOSTS
. Ceci définit une liste des adresses du serveur ou des noms de domaines pouvant être utilisés pour se connecter à l’instance de Django. Toute demande entrante avec un en-têteHost qui n'est pas dans cette liste lèvera une exception. Django exige que vous définissiez cela pour empêcher une certaine classe de vulnérabilité de sécurité.
Entre les crochets, répertoriez les adresses IP ou les noms de domaine associés à votre serveur Django. Chaque élément doit être répertorié dans des citations avec des entrées séparées par une virgule. Si vous souhaitez des demandes pour un domaine entier et des sous-domaines, ajoutez une période au début de l'entrée. L'extrait ci-dessous contient quelques exemples commentés utilisés pour illustrer:
[.note] #Note: Assurez-vous d'inclurelocalhost
comme l'une des options car nous ferons un proxy des connexions via une instance Nginx locale.
#
~/myprojectdir/myproject/settings.py
. . .
# 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 parDATABASES
. La configuration dans le fichier concerne une base de données SQLite. Nous avons déjà créé une base de données PostgreSQL pour notre projet, nous devons donc ajuster les paramètres.
Modifiez les paramètres avec les informations de votre base de données PostgreSQL. Nous disons à Django d'utiliser l'adaptateurpsycopg2
que nous avons installé avecpip
. Nous devons donner 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ètrePORT
sous forme de chaîne vide:
~/myprojectdir/myproject/settings.py
. . .
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'myproject',
'USER': 'myprojectuser',
'PASSWORD': 'password',
'HOST': 'localhost',
'PORT': '',
}
}
. . .
Ensuite, déplacez-vous vers le bas du fichier et ajoutez un paramètre indiquant l'emplacement des fichiers statiques. Cela est nécessaire pour que Nginx puisse gérer les demandes relatives à ces éléments. La ligne suivante indique à Django de les placer dans un répertoire appeléstatic
dans le répertoire du projet de base:
~/myprojectdir/myproject/settings.py
. . .
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
Enregistrez et fermez le fichier lorsque vous avez terminé.
Fin de la configuration initiale du projet
Maintenant, nous pouvons migrer le schéma de base de données initial vers notre base de données PostgreSQL en utilisant le 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 électronique, puis choisir et confirmer un mot de passe.
Nous pouvons collecter tout le contenu statique dans l’emplacement du répertoire que nous avons 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 devez disposer d’un pare-feu UFW protégeant votre serveur. Pour tester le serveur de développement, nous devons autoriser l’accès au port que nous allons utiliser.
Créez une exception pour le port 8000 en tapant:
sudo ufw allow 8000
Enfin, vous pouvez tester votre projet en lançant le serveur de développement Django avec cette commande:
~/myprojectdir/manage.py runserver 0.0.0.0:8000
Dans votre navigateur Web, accédez au nom de domaine ou à l’adresse IP de votre serveur suivi de:8000
:
http://server_domain_or_IP:8000
Vous devriez voir la page d'index par défaut de Django:
Si vous ajoutez/admin
à la fin de l'URL dans la barre d'adresse, vous serez invité à entrer le nom d'utilisateur et le mot de passe administratifs que vous avez créés avec la commandecreatesuperuser
:
Après authentification, vous pouvez accéder à l'interface d'administration par défaut de Django:
Lorsque vous avez terminé l'exploration, appuyez surCTRL-C dans la fenêtre du terminal pour arrêter le serveur de développement.
Tester la capacité de Gunicorn à servir le projet
La dernière chose que nous voulons faire avant de quitter notre environnement virtuel est de tester Gunicorn pour s’assurer qu’il peut servir l’application. Nous pouvons le faire en entrant notre répertoire de projet et en utilisantgunicorn
pour charger le module WSGI du projet:
cd ~/myprojectdir
gunicorn --bind 0.0.0.0:8000 myproject.wsgi
Ceci lancera Gunicorn sur la même interface que celle utilisée par le serveur de développement Django. Vous pouvez revenir en arrière et tester à nouveau l'application.
[.note] #Note: L'interface d'administration n'aura aucun style appliqué car Gunicorn ne sait pas comment trouver le contenu CSS statique responsable de cela.
#
Nous avons transmis à Gunicorn un module en spécifiant le chemin du répertoire relatif au fichierwsgi.py
de Django, qui est le point d’entrée de notre application, en utilisant la syntaxe du module de Python. À l'intérieur de ce fichier, une fonction appeléeapplication
est définie, qui est utilisée pour communiquer avec l'application. Pour en savoir plus sur la spécification WSGI, cliquez surhere.
Lorsque vous avez terminé les tests, appuyez surCTRL-C dans la fenêtre du terminal pour arrêter Gunicorn.
Nous avons maintenant fini de configurer notre application Django. Nous pouvons revenir en arrière de notre environnement virtuel en tapant:
deactivate
L'indicateur d'environnement virtuel de votre invite sera supprimé.
Création de fichiers de socket et de service systemd pour Gunicorn
Nous avons testé la capacité de Gunicorn à interagir avec notre application Django, mais nous devrions implémenter une méthode plus robuste de démarrage et d’arrêt du serveur d’applications. Pour ce faire, nous allons créer des fichiers de service et de socket Systemd.
Le socket Gunicorn sera créé au démarrage et écoutera les connexions. Lorsqu'une connexion est établie, systemd lance automatiquement le processus Gunicorn pour gérer la connexion.
Commencez par créer et ouvrir un fichier socket systemd pour Gunicorn avec les privilègessudo
:
sudo nano /etc/systemd/system/gunicorn.socket
À l'intérieur, nous allons créer une section[Unit]
pour décrire le socket, une section[Socket]
pour définir l'emplacement du socket, et une section[Install]
pour s'assurer que le socket est créé au bon moment:
/etc/systemd/system/gunicorn.socket
[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ègessudo
dans votre éditeur de texte. Le nom de fichier du service doit correspondre au nom de 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. Nous allons mettre ici une description de notre service et dire au système init de ne le démarrer que lorsque la cible réseau aura été atteinte. Comme notre service repose sur la socket du fichier socket, nous devons inclure une directiveRequires
pour indiquer cette relation:
/etc/systemd/system/gunicorn.service
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
Ensuite, nous allons ouvrir la section[Service]
. Nous spécifierons l’utilisateur et le groupe sous lesquels nous voulons traiter. Nous allons donner à notre compte utilisateur habituel la propriété du processus puisqu'il possède tous les fichiers pertinents. Nous donnerons la propriété du groupe au groupewww-data
afin que Nginx puisse communiquer facilement avec Gunicorn.
Nous allons ensuite mapper le répertoire de travail et spécifier la commande à utiliser pour démarrer le service. Dans ce cas, nous devrons spécifier le chemin complet de l’exécutable Gunicorn, qui est installé dans notre environnement virtuel. Nous lierons le processus au socket Unix que nous avons créé dans le répertoire/run
afin que le processus puisse communiquer avec Nginx. Nous enregistrons toutes les données sur la sortie standard afin que le processusjournald
puisse collecter les journaux Gunicorn. Nous pouvons également spécifier ici tous les réglages optionnels de Gunicorn. Par exemple, nous avons spécifié 3 processus de travail dans ce cas:
/etc/systemd/system/gunicorn.service
[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, nous ajouterons une section[Install]
. Cela indiquera à systemd à quoi lier ce service si nous lui permettons de démarrer au démarrage. Nous voulons que ce service démarre lorsque le système multi-utilisateurs normal est opérationnel:
/etc/systemd/system/gunicorn.service
[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, notre fichier de service systemd est complet. Enregistrez et fermez-le maintenant.
Nous pouvons maintenant démarrer et activer le socket Gunicorn. Cela créera le fichier socket à/run/gunicorn.sock
maintenant et au démarrage. Lorsqu'une connexion est établie à ce socket, systemd démarrera automatiquement lesgunicorn.service
pour le gérer:
sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket
Nous pouvons confirmer que l'opération a réussi en vérifiant le fichier de socket.
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
Ensuite, vérifiez l'existence du fichiergunicorn.sock
dans le répertoire/run
:
file /run/gunicorn.sock
Output/run/gunicorn.sock: socket
Si la commandesystemctl status
a indiqué qu'une erreur s'est produite ou si vous ne trouvez pas le fichiergunicorn.sock
dans le répertoire, cela indique que le socket Gunicorn n'a pas pu être créé correctement. Vérifiez les journaux de la prise Gunicorn en tapant:
sudo journalctl -u gunicorn.socket
Examinez à nouveau votre fichier/etc/systemd/system/gunicorn.socket
pour résoudre les problèmes avant de continuer.
Test de l'activation des sockets
Actuellement, si vous n’avez démarré que l’unitégunicorn.socket
, lesgunicorn.service
ne seront pas encore actifs car le socket n’a pas encore reçu de connexion. Vous pouvez vérifier cela en tapant:
sudo systemctl status gunicorn
Output● gunicorn.service - gunicorn daemon
Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Pour tester le mécanisme d'activation du socket, nous pouvons envoyer une connexion au socket viacurl
en tapant:
curl --unix-socket /run/gunicorn.sock localhost
Vous devriez voir la sortie HTML de votre application dans le terminal. Cela indique que Gunicorn a été lancé et a pu servir votre application Django. Vous pouvez vérifier que le service Gunicorn est en cours d'exécution en tapant:
sudo systemctl status gunicorn
Output● gunicorn.service - gunicorn daemon
Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled)
Active: active (running) since Mon 2018-07-09 20:00:40 UTC; 4s ago
Main PID: 1157 (gunicorn)
Tasks: 4 (limit: 1153)
CGroup: /system.slice/gunicorn.service
├─1157 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application
├─1178 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application
├─1180 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application
└─1181 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock myproject.wsgi:application
Jul 09 20:00:40 django1 systemd[1]: Started gunicorn daemon.
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1157] [INFO] Starting gunicorn 19.9.0
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1157] [INFO] Listening at: unix:/run/gunicorn.sock (1157)
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1157] [INFO] Using worker: sync
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1178] [INFO] Booting worker with pid: 1178
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1180] [INFO] Booting worker with pid: 1180
Jul 09 20:00:40 django1 gunicorn[1157]: [2018-07-09 20:00:40 +0000] [1181] [INFO] Booting worker with pid: 1181
Jul 09 20:00:41 django1 gunicorn[1157]: - - [09/Jul/2018:20:00:41 +0000] "GET / HTTP/1.1" 200 16348 "-" "curl/7.58.0"
Si la sortie decurl
ou la sortie desystemctl status
indique qu'un problème est survenu, consultez les journaux pour plus de détails:
sudo journalctl -u gunicorn
Vérifiez votre fichier/etc/systemd/system/gunicorn.service
pour des problèmes. 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.
Configurer Nginx to Proxy Pass to Gunicorn
Maintenant que Gunicorn est configuré, nous devons configurer Nginx pour transférer le trafic au processus.
Commencez par créer et ouvrir un nouveau bloc de serveur dans le répertoiresites-available
de Nginx:
sudo nano /etc/nginx/sites-available/myproject
À l'intérieur, ouvrez un nouveau bloc de serveur. Nous allons commencer par spécifier 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 notre serveur:
/etc/nginx/sites-available/myproject
server {
listen 80;
server_name server_domain_or_IP;
}
Ensuite, nous dirons à Nginx d’ignorer tout problème lié à la recherche d’un favicon. Nous lui indiquerons également où trouver les actifs statiques que nous avons collectés dans notre répertoire~/myprojectdir/static
. Tous ces fichiers ont un préfixe d'URI standard «/ static». Nous pouvons donc créer un bloc d'emplacement correspondant à ces demandes:
/etc/nginx/sites-available/myproject
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, nous allons créer un bloclocation / {}
pour correspondre à toutes les autres requêtes. À l'intérieur de cet emplacement, nous allons inclure le fichier standardproxy_params
inclus avec l'installation de Nginx, puis nous passerons le trafic directement au socket Gunicorn:
/etc/nginx/sites-available/myproject
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, nous pouvons activer le fichier en le liant au répertoiresites-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, redémarrez Nginx en tapant:
sudo systemctl restart nginx
Enfin, nous devons ouvrir notre pare-feu au trafic normal sur le port 80. Comme nous n'avons plus besoin d'accéder au serveur de développement, nous pouvons également supprimer la règle pour ouvrir le 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]##
Note: Après avoir configuré Nginx, l'étape suivante devrait être la sécurisation du trafic vers le serveur à l'aide de SSL / TLS. Ceci est important car sans lui, toutes les informations, y compris les mots de passe, sont envoyées sur le réseau en texte brut.
Si vous avez un nom de domaine, le moyen le plus simple d'obtenir un certificat SSL pour sécuriser votre trafic est d'utiliser Let’s Encrypt. Suivezthis guide pour configurer Let’s Encrypt avec Nginx sur Ubuntu 18.04. Suivez la procédure à l'aide du bloc serveur Nginx que nous avons créé dans ce guide.
Si vous n'avez pas de nom de domaine, vous pouvez toujours sécuriser votre site pour les tests et l'apprentissage avec unself-signed SSL certificate. Encore une fois, suivez le processus en utilisant le bloc serveur Nginx que nous avons créé dans ce didacticiel.
Dépannage de Nginx et Gunicorn
Si cette dernière étape ne montre pas votre application, vous devrez résoudre 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 fournir un proxy à votre application, cela signifie généralement que vous devez ajuster lesserver_name
dans le fichier/etc/nginx/sites-available/myproject
pour pointer vers l'adresse IP ou le nom de domaine de votre serveur.
Nginx utilise lesserver_name
pour déterminer le bloc serveur à utiliser pour répondre aux requêtes. Si vous voyez 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 retombe donc sur le bloc par défaut défini dans/etc/nginx/sites-available/default
.
Lesserver_name
du bloc serveur de votre projet doivent être plus spécifiques que celui du bloc serveur par défaut à sélectionner.
Nginx affiche une erreur de passerelle 502 incorrecte au lieu de l'application Django
Une erreur 502 indique que Nginx ne parvient pas à proxyer la demande. Une large gamme de problèmes de configuration s’expriment avec une erreur 502; il est donc nécessaire de disposer de plus d’informations pour résoudre correctement les problèmes.
Le principal endroit où rechercher plus d’informations est dans les journaux d’erreur de Nginx. En règle générale, cela vous indiquera quelles conditions ont causé des problèmes lors de l'événement de proxy. Suivez les journaux d’erreur Nginx en tapant:
sudo tail -F /var/log/nginx/error.log
Maintenant, faites une autre demande dans votre navigateur pour générer une nouvelle erreur (essayez d'actualiser la page). Vous devriez voir un nouveau message d'erreur écrit dans le journal. Si vous regardez le message, il devrait vous aider à cerner le problème.
Vous pourriez voir certains des messages suivants:
connect () à unix: /run/gunicorn.sock a échoué (2: aucun fichier ou répertoire de ce type)
Cela indique que Nginx n'a pas pu trouver le fichiergunicorn.sock
à l'emplacement donné. Vous devez comparer l'emplacement deproxy_pass
défini dans le fichier/etc/nginx/sites-available/myproject
à l'emplacement réel du fichiergunicorn.sock
généré par l'unité systemdgunicorn.socket
.
Si vous ne trouvez pas un fichiergunicorn.sock
dans le répertoire/run
, cela signifie généralement que le fichier socket systemd n'a pas pu le créer. Revenez auxsection on checking for the Gunicorn socket file pour parcourir les étapes de dépannage de Gunicorn.
connect () à unix: /run/gunicorn.sock a échoué (13: Autorisation refusée)
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 utilisateursudo
. Bien que systemd puisse 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 fichiergunicorn.sock
. Nous pouvons voir les autorisations et les valeurs de propriété du fichier socket et de chacun de ses répertoires parents en passant le chemin absolu de notre fichier socket à la commandenamei
:
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
La sortie affiche les autorisations de chacun des composants du répertoire. En examinant les autorisations (première colonne), le propriétaire (deuxième colonne) et le propriétaire du groupe (troisième colonne), nous pouvons déterminer le type d'accès autorisé au fichier de socket.
Dans l'exemple ci-dessus, le fichier socket et chacun des répertoires menant au fichier socket ont des droits de lecture et d'exécution universels (la colonne des permissions pour les répertoires se termine parr-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 des droits de lecture et d'exécution du monde, Nginx ne pourra pas accéder au socket sans autoriser les permissions de lecture et d'exécution du monde ou s'assurer que la propriété du groupe est attribuée à un groupe dont Nginx fait partie. de.
Django affiche: «impossible de se connecter au serveur: connexion refusée»
Un message que Django peut voir lorsque vous tentez d'accéder à certaines parties de l'application dans le navigateur Web est le suivant:
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 est incapable de se connecter à la base de données Postgres. Assurez-vous que l'instance de 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 l'activer pour qu'il démarre 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 à réduire les causes profondes. Vérifiez chacune d’elles à tour de rôle et recherchez les messages indiquant les zones à problèmes.
Les journaux suivants peuvent être utiles:
-
Vérifiez les journaux de 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 du socket Gunicorn en tapant:
sudo journalctl -u gunicorn.socket
Lors de la mise à jour de votre configuration ou de 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 prendre en compte les modifications en tapant:
sudo systemctl restart gunicorn
Si vous modifiez les fichiers de socket ou 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 de bloc du serveur Nginx, testez-la, puis Nginx en tapant:
sudo nginx -t && sudo systemctl restart nginx
Ces commandes sont utiles pour prendre en compte les modifications lorsque vous ajustez votre configuration.
Conclusion
Dans ce guide, nous avons configuré un projet Django dans son propre environnement virtuel. Nous avons configuré Gunicorn pour traduire les demandes des clients afin que Django puisse les prendre en charge. Ensuite, nous avons configuré Nginx pour qu’il agisse en tant que proxy inverse pour gérer les connexions client et servir le projet approprié en fonction de la demande du client.
Django facilite la création de projets et d'applications en fournissant de nombreux éléments communs, vous permettant de vous concentrer sur des éléments uniques. En exploitant la chaîne d'outils générale décrite dans cet article, vous pouvez facilement desservir les applications que vous créez à partir d'un seul serveur.