Comment configurer Django avec Postgres, Nginx et Gunicorn sur Debian 8

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 Debian 8 pour prendre en charge et servir les 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 vers Gunicorn, nous donnant ainsi accès à ses fonctionnalités de sécurité et de performances pour servir nos applications.

Prérequis et objectifs

Afin de compléter ce guide, vous devriez avoir une nouvelle instance de serveur Debian 8 avec un utilisateur non root avec les privilèges + sudo + configurés. Vous pouvez apprendre à configurer cela en parcourant notre initial initial guide de configuration du serveur.

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 requêtes client en 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.

Installer les paquets à partir des référentiels Debian

Pour commencer le processus, nous téléchargerons et installerons tous les éléments nécessaires dans les référentiels Debian. Nous utiliserons le gestionnaire de paquets Python + pip + pour installer des composants supplémentaires un peu plus tard.

Nous devons mettre à jour l’index local du paquet + apt + puis télécharger et installer les paquetages. Les packages que nous installons dépendent de la version de Python que votre projet utilisera.

Si vous utilisez * Python 2 *, tapez:

sudo apt-get update
sudo apt-get install python-pip python-dev libpq-dev postgresql postgresql-contrib nginx

Si vous utilisez * Python 3 *, tapez:

sudo apt-get update
sudo apt-get install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx

Cela installera + pip +, les fichiers de développement Python nécessaires à la construction ultérieure de Gunicorn, le système de base de données Postgres et les bibliothèques nécessaires pour interagir avec celui-ci, ainsi que le serveur Web Nginx.

Créer la base de données et 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 valide de Postgres, 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. Nous devons utiliser cet utilisateur pour effectuer des tâches administratives. Nous pouvons utiliser sudo et transmettre 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:

Note

CREATE DATABASE ;
OutputCREATE DATABASE

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  WITH PASSWORD '';
OutputCREATE ROLE

Nous allons ensuite 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 le codage par défaut sur UTF-8, ce à quoi Django s’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, vos projets Django seront configurés pour utiliser + UTC. Toutes ces recommandations proviennent de du projet Django lui-même:

ALTER ROLE  SET client_encoding TO 'utf8';
ALTER ROLE  SET default_transaction_isolation TO 'read committed';
ALTER ROLE  SET timezone TO 'UTC';
OutputALTER ROLE
ALTER ROLE
ALTER ROLE

Maintenant, nous pouvons donner à notre nouvel utilisateur l’accès pour administrer notre nouvelle base de données:

GRANT ALL PRIVILEGES ON DATABASE  TO ;
OutputGRANT

Lorsque vous avez terminé, quittez l’invite de PostgreSQL en tapant:

\q

Vous devriez être retourné à votre session shell.

Créer 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 avoir accès à la commande + virtualenv +. Nous pouvons l’installer avec + pip +.

Si vous utilisez * Python 2 *, tapez:

sudo pip install virtualenv

Si vous utilisez * Python 3 *, tapez:

sudo pip3 install virtualenv

Avec + virtualenv + 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 ~/
cd ~/

Dans le répertoire du projet, créez un environnement virtuel Python en tapant:

virtualenv

Cela créera un répertoire appelé ` dans votre répertoire `. À l’intérieur, il installera une version locale de Python et une version locale de + pip +. 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 /bin/activate

Votre invite devrait changer pour indiquer que vous travaillez maintenant dans un environnement virtuel Python. Cela ressemblera à quelque chose comme ceci: + () @: ~ / $ +.

Avec votre environnement virtuel actif, installez Django, Gunicorn et l’adaptateur PostgreSQL + psycopg2 + avec l’instance locale de + pip +:

Note

pip install django gunicorn psycopg2

Ces composants seront installés dans notre environnement virtuel, isolés de nos packages globaux.

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éer le projet Django

Comme nous avons déjà un répertoire de projet, nous demanderons à Django d’installer les fichiers ici. Nous pouvons maintenant démarrer un projet Django dans notre répertoire + myproject +. Cela créera un répertoire enfant du même nom qui contiendra le code lui-même et créera un script de gestion dans le répertoire actuel:

django-admin.py startproject  .

Votre structure de répertoire actuelle devrait ressembler à ceci:

.
└── ./myproject/
   ├── manage.py
   ├── myproject/
   │   ├── __init__.py
   │   ├── settings.py
   │   ├── urls.py
   │   └── wsgi.py
   └── venv/
       └── . . .

Comme vous pouvez le constater, nous avons un répertoire de projet parent contenant un script + manage.py, un répertoire de projet interne et le répertoire d’environnement virtuel` + venv` 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 ~///settings.py

Commencez par localiser la directive + ALLOWED_HOSTS +. Ceci définit une liste blanche d’adresses ou de noms de domaines pouvant être utilisés pour se connecter à l’instance de Django. Toute demande entrante avec un en-tête * Host * qui ne figure pas dans cette liste déclenchera 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é * entre guillemets * avec des entrées * séparées par une virgule *. Si vous souhaitez répondre aux demandes d’un domaine et de tout sous-domaine, ajoutez une période au début de l’entrée. Dans l’extrait de code ci-dessous, quelques exemples commentés sont utilisés pour illustrer la manière correcte de formater les entrées:

~ / monprojet / monprojet / 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 = ['', '', ]

Ensuite, recherchez la section qui configure l’accès à la base de données. Il commencera par + DATABASES +. 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’adaptateur + psycopg2 + que nous avons installé avec + pip +. 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ètre + PORT + sous forme de chaîne vide:

~ / monprojet / monprojet / settings.py

. . .

DATABASES = {
   'default': {
       'ENGINE': 'django.db.backends.',
       'NAME': '',
       'USER': '',
       '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 traiter les demandes relatives à ces éléments. La ligne suivante indique à Django de les placer dans un répertoire appelé + statique + dans le répertoire du projet de base:

~ / monprojet / monprojet / settings.py

. . .

STATIC_URL = '/static/'

Enregistrez et fermez le fichier lorsque vous avez terminé.

Terminer 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:

cd ~/
./manage.py makemigrations
./manage.py migrate

Créez un utilisateur administratif pour le projet en tapant:

./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:

./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.

Enfin, vous pouvez tester votre projet en lançant le serveur de développement Django avec cette commande:

./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://:8000

Vous devriez voir la page d’index par défaut de Django:

image: https: //assets.digitalocean.com/articles/django_gunicorn_nginx_1404/django_index.png [page d’index de Django]

Si vous ajoutez + / admin + à la fin de l’URL dans la barre d’adresse, le nom d’utilisateur et le mot de passe administrateur que vous avez créés à l’aide de la commande + createuperuser + vous seront demandés:

image: https: //assets.digitalocean.com/articles/django_gunicorn_nginx_1404/admin_login.png [Connexion à l’administrateur Django]

Après authentification, vous pouvez accéder à l’interface d’administration par défaut de Django:

image: https: //assets.digitalocean.com/articles/django_gunicorn_nginx_1404/admin_interface.png [Interface d’administration Django]

Lorsque vous avez terminé, appuyez sur CTRL-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 facilement en tapant:

cd ~/
gunicorn --bind 0.0.0.0:8000 .wsgi:application

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.

Nous avons passé un module à Gunicorn en spécifiant le chemin de répertoire relatif au fichier + wsgi.py + de Django, qui constitue le point d’entrée de notre application, à l’aide de la syntaxe du module de Python. À l’intérieur de ce fichier, une fonction appelée + application + est définie, utilisée pour communiquer avec l’application. Pour en savoir plus sur les spécifications WSGI, cliquez sur https://www.digitalocean.com/community/tutorials/how-to-set-up-uwsgi-and-nginx-to-serve-python-apps-on-ubuntu-14. -04 # définitions-et-concepts [ici].

Lorsque vous avez terminé les tests, appuyez sur CTRL-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

Le préfixe de l’environnement virtuel doit être supprimé de votre invite de shell, indiquant que vous ne vous trouvez plus dans l’environnement virtuel.

Créer un fichier de service Gunicorn systemd

Nous avons testé que Gunicorn pouvait interagir avec notre application Django, mais nous devrions implémenter un moyen plus robuste de démarrer et d’arrêter le serveur d’applications. Pour ce faire, nous allons créer un fichier de service Systemd.

Créez et ouvrez un fichier de service systemd pour Gunicorn avec les privilèges + sudo + dans votre éditeur de texte:

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

Commencez par la section + [Unit] +, utilisée pour spécifier les métadonnées et les dépendances. Nous allons mettre une description de notre service ici et dire au système init de ne le démarrer que lorsque la cible réseau aura été atteinte:

/etc/systemd/system/gunicorn.service

[Unit]
Description=gunicorn daemon
After=network.target

Ensuite, nous ouvrirons 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 allons donner la propriété du groupe + www-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 allons le lier à un Unix socket dans le répertoire du projet puisque Nginx est installé sur le même ordinateur. C’est plus sûr et plus rapide que d’utiliser un port réseau. 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
After=network.target

[Service]
User=
Group=www-data
WorkingDirectory=/home//
ExecStart=/home////bin/gunicorn --workers 3 --bind unix:/home///.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
After=network.target

[Service]
User=
Group=www-data
WorkingDirectory=/home//
ExecStart=/home////bin/gunicorn --workers 3 --bind unix:/home///.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 le service Gunicorn que nous avons créé et l’activer pour qu’il démarre au démarrage:

sudo systemctl start gunicorn
sudo systemctl enable gunicorn
OutputCreated symlink from /etc/systemd/system/multi-user.target.wants/gunicorn.service to /etc/systemd/system/gunicorn.service.

Vérifiez l’état du service en tapant:

sudo systemctl status gunicorn
Output● gunicorn.service - gunicorn daemon
  Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled)
   since Wed 2016-12-21 21:05:07 UTC; 49s ago
Main PID: 10154 (gunicorn)
  CGroup: /system.slice/gunicorn.service
          ├─10154 /home/sammy/myproject/venv/bin/python3 /home/sammy/myproject/venv/bin/gunicorn --workers 3 --bind unix:/home/sammy/myproject/myproject.sock myproject.wsgi:application
          ├─10157 /home/sammy/myproject/venv/bin/python3 /home/sammy/myproject/venv/bin/gunicorn --workers 3 --bind unix:/home/sammy/myproject/myproject.sock myproject.wsgi:application
          ├─10158 /home/sammy/myproject/venv/bin/python3 /home/sammy/myproject/venv/bin/gunicorn --workers 3 --bind unix:/home/sammy/myproject/myproject.sock myproject.wsgi:application
          └─10159 /home/sammy/myproject/venv/bin/python3 /home/sammy/myproject/venv/bin/gunicorn --workers 3 --bind unix:/home/sammy/myproject/myproject.sock myproject.wsgi:application

Dec 21 21:05:07 debian-512mb-nyc3-01 systemd[1]: Started gunicorn daemon.
Dec 21 21:05:07 debian-512mb-nyc3-01 gunicorn[10154]: [2016-12-21 21:05:07 +0000] [10154] [INFO] Starting gunicorn 19.6.0
Dec 21 21:05:07 debian-512mb-nyc3-01 gunicorn[10154]: [2016-12-21 21:05:07 +0000] [10154] [INFO] Listening at: unix:/home/sammy/myproject/myproject.sock (10154)
Dec 21 21:05:07 debian-512mb-nyc3-01 gunicorn[10154]: [2016-12-21 21:05:07 +0000] [10154] [INFO] Using worker: sync
Dec 21 21:05:07 debian-512mb-nyc3-01 gunicorn[10154]: [2016-12-21 21:05:07 +0000] [10157] [INFO] Booting worker with pid: 10157
Dec 21 21:05:07 debian-512mb-nyc3-01 gunicorn[10154]: [2016-12-21 21:05:07 +0000] [10158] [INFO] Booting worker with pid: 10158
Dec 21 21:05:07 debian-512mb-nyc3-01 gunicorn[10154]: [2016-12-21 21:05:07 +0000] [10159] [INFO] Booting worker with pid: 10159

La chose la plus importante à rechercher est que l’unité est active.

C’est également le bon moment pour vérifier que le fichier de socket a bien été créé. Si vous listez le contenu de votre répertoire + ~ / +, vous devriez voir le fichier de socket Unix:

ls -l ~/
Outputtotal 16
-rwxr-xr-x 1 sammy sammy     807 Dec 21 20:46 manage.py
drwxr-xr-x 3 sammy sammy    4096 Dec 21 20:54 myproject

drwxr-xr-x 3 sammy sammy    4096 Dec 21 20:54 static
drwxr-xr-x 5 sammy sammy    4096 Dec 21 20:41 venv

Comme vous pouvez le constater, le socket est présent et le groupe + www-data a la propriété du groupe.

Configurer Nginx to Proxy Pass to Gunicorn

Maintenant que Gunicorn est configuré, nous devons 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/

À 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 ;
}

Ensuite, nous pouvons dire à Nginx d’ignorer les erreurs si aucun favicon ne peut être trouvé. Nous lui indiquerons également où trouver les actifs statiques que nous avons collectés dans notre répertoire + ~ // 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 ;

   location = /favicon.ico { access_log off; log_not_found off; }
   location /static/ {
       root /home//;
   }
}

Enfin, nous allons créer un bloc + location / {} + pour correspondre à toutes les autres demandes. À l’intérieur de cet emplacement, nous inclurons le fichier + proxy_params + standard inclus dans l’installation de Nginx, puis nous transmettrons le trafic au socket créé par notre processus Gunicorn:

/ etc / nginx / sites-available / myproject

server {
   listen 80;
   server_name ;

   location = /favicon.ico { access_log off; log_not_found off; }
   location /static/ {
       root /home//;
   }

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

Enregistrez et fermez le fichier lorsque vous avez terminé. Maintenant, nous pouvons activer le fichier en le reliant au répertoire + sites-enabled +:

sudo ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled

Testez votre configuration Nginx pour les erreurs de syntaxe en tapant:

sudo nginx -t
Outputnginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Si aucune erreur n’est signalée, redémarrez Nginx en tapant:

sudo systemctl restart nginx

Vous devriez maintenant pouvoir accéder au domaine ou à l’adresse IP de votre serveur pour afficher votre application sans spécifier de port.

Note

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.