NGINX Unit est un serveur d’applications entièrement dynamique, capable de prendre en charge plusieurs langages ainsi que plusieurs versions de chacun d’eux. Il est dynamique en ce sens que vous utilisez l’API JSON RESTful pour modifier sa configuration en mémoire, sans interruption de service ni rechargement de la configuration.
Lors de ma présentation à la NGINX Conf 2018 en octobre, j’ai montré comment configurer une nouvelle application dans un environnement de production existant. Plus précisément, alors que WordPress s’exécutait sous PHP, j’ai déployé une application Python utilisant le framework Django. J’ai également montré comment charger la configuration à partir d’un fichier ou en la spécifiant comme argument d’un appel d’API.
Cet article de blog contient toutes les commandes et tout le code de configuration que j’ai utilisés dans la démonstration, afin de vous permettre de les adapter plus facilement à votre propre déploiement.
Prérequis
Pour la démonstration à la NGINX Conf, j’avais installé les logiciels suivants :
- Ubuntu 16.04
- NGINX Plus, mais vous pouvez utiliser NGINX Open Source, sauf indication contraire
- NGINX Unit avec tous les modules de langage installés
- Python 3
- Django (non configuré – c’est justement le sujet de la démo et de cet article de blog)
rootprivilège, ou un accès équivalent viasudo(que nous utilisons lorsque nécessaire)
J’avais également installé PHP et WordPress pour l’application existante.
Création du projet Django
- Accédez au répertoire dans lequel nous allons créer notre projet Django :
$ cd /var/www/- Utilisez la commande «
django-adminstartproject» pour initialiser le nouveau projet. Nous l’appellerons « djapp ».
$ sudo django-admin startproject djapp- Accédez au répertoire du projet :
$ cd djapp- Utilisez le script «
manage.py» pour migrer la base de données du projet, ce qui est nécessaire pour un projet nouvellement créé. Django utilise SQLite par défaut, et je conserve ce choix dans la démonstration, mais vous pouvez utiliser toute base de données répondant aux besoins de votre projet. Le script «manage.py» est installé par la commande «django-admin» que nous avons exécutée à l’étape 2 ; il exécute les mêmes commandes et accepte les mêmes arguments que «django-admin», mais détermine et utilise automatiquement certains paramètres propres au projet, ce qui est pratique. Pour plus de détails, consultez la documentation de Django.
$ sudo python3 manage.py migrate- Bien que cela ne soit pas strictement nécessaire pour un exemple de projet comme celui-ci, nous vous recommandons de créer une identité de superutilisateur Django :
$ sudo python3 manage.py createsuperuser- Accédez au sous-répertoire contenant le fichier settings.py, qui a été créé par la commande
django-adminstartprojectà l’étape 2.
$ cd /var/www/djapp/djapp- À l’aide de votre éditeur de texte préféré, ouvrez « settings.py ». Ici, nous utilisons
nano:
$ sudo nano settings.py- Recherchez la ligne «
ALLOWED_HOSTS» et ajoutez-y le nom de domaine, nom d’hôte ou adresse IP de l’application :
ALLOWED_HOSTS = ['domain-name']- Ajoutez également la ligne suivante à la fin du fichier afin d’indiquer le nom du répertoire qui contient tout le contenu statique servi par l’application (voir l’étape 9).
STATIC_ROOT = '/var/www/djapp/djapp/static'- Revenez dans le répertoire principal du projet (où se trouve manage.py).
$ cd ..- Exécutez la commande «
manage.pycollectstatic» pour collecter tous les fichiers statiques du projet Django et les placer dans l’emplacementSTATIC_ROOTdéfini à l’étape 7.
$ sudo python3 manage.py collectstaticConfiguration de NGINX
Par défaut, Django diffuse lui-même le contenu statique d’un projet, mais NGINX Open Source et NGINX Plus offrent de meilleures performances. Nous configurons ici NGINX Plus, mais vous pouvez utiliser NGINX Open Source, à l’exception d’une fonctionnalité indiquée ci-dessous.
- Accédez au répertoire /etc/nginx/conf.d, l’emplacement habituel des fichiers de configuration HTTP propres à une fonction (ou, dans notre cas, à une application) :
$ cd /etc/nginx/conf.d- Créez un fichier nommé « django.conf » (là encore, nous utilisons
nano) :
$ sudo nano django.conf- Insérez la configuration suivante, qui active la mise en cache. Cette configuration comprend également deux fonctionnalités exclusives à NGINX Plus. Décommentez les directives correspondantes si vous utilisez NGINX Plus et souhaitez profiter de ces fonctionnalités. À noter que, lors de la démonstration à NGINX Conf, j’ai indiqué l’adresse IP de ma machine locale comme deuxième argument de la directive
proxy_set_header. Dans un environnement de production, il est plus judicieux d’utiliser la variable$host, comme indiqué ci-dessous.
# Upstream group for the backend (NGINX Unit running the Python application)
upstream django_unit {
zone django_unit 64k;
server 127.0.0.1:8000;
}
server {
listen 8080;
# Uncomment to collect metrics if using NGINX Plus and the NGINX Plus API
#status_zone django;
# enable caching
proxy_cache django_cache;
proxy_cache_valid 200 60m;
# root directory for static files
root /var/www/djapp/djapp;
# proxy to the NGINX Unit backend
location / {
proxy_pass http://django_unit;
# Second argument must match your production hostname and the value of
# ALLOWED_HOSTS in settings.py
proxy_set_header Host $host;
# Uncomment to enable active health checks if using NGINX Plus
#health_check;
}
# Location for the static files collected from Django and served by
# NGINX Plus; can be empty (as here), because it inherits the value of the
# 'root' directive from its parent block
location /static {
}
}- Collecte étendue des métriques, activée pour ce serveur virtuel par la directive «
status_zone». Je suppose que l’API NGINX Plus est activée ailleurs dans la configuration. - Contrôles d’intégrité actifs, activés par la directive
health_check.
- Vérifiez la validité syntaxique de la configuration :
$ sudo nginx –t- Après avoir corrigé les éventuelles erreurs, rechargez la configuration :
$ sudo nginx -s reloadConfiguration de NGINX Unit
Pour terminer, nous devons configurer NGINX Unit afin qu’il transmette les requêtes à l’application.
- Exécutez cette commande
curlpour afficher la configuration actuelle de NGINX Unit, qui correspond à WordPress exécuté avec PHP. Je n’affiche pas le résultat ici, mais la configuration de WordPress apparaît à l’étape 6 ci-dessous, avec celle de l’application Python que nous allons ajouter. Notez que j’utilisesudopour la commandecurl, ce qui n’est généralement pas nécessaire pour la plupart des commandescurl. Ici, c’est indispensable, car l’accès au socket UNIX nécessite les droits de lecture et d’écriture dont disposeroot.
$ sudo curl --unix-socket /run/control.unit.sock http://localhost/config/- Accédez au répertoire contenant les fichiers de configuration de NGINX Unit. Gardez à l’esprit que ces fichiers sont facultatifs et constituent simplement un moyen pratique de charger des ensembles de paramètres de configuration sans avoir à saisir toutes les données comme argument lors d’un appel à l’API de NGINX Unit. Comme le contenu des fichiers est chargé via l’API (à l’instar de toutes les données de configuration), NGINX Unit ne connaît pas l’emplacement des fichiers et ne peut pas les lire automatiquement au démarrage (contrairement à NGINX Open Source et NGINX Plus). NGINX Unit enregistre plutôt son état d’exécution dans un répertoire distinct.
$ cd /etc/unit- Créez un fichier nommé « django.config » (là encore, nous utilisons
nano):
$ sudo nano django.config- Ajoutez le JSON suivant, qui représente notre application Python.
{
"type": "python",
"processes": 5,
"module": "djapp.wsgi",
"path": "/var/www/djapp"
}- Exécutez cette commande
curlpour charger le JSON contenu dans django.config en tant que nouvel objet d’application nommé djapp et géré par NGINX Unit :
$ sudo curl -X PUT --data-binary @/etc/unit/django.config --unix-socket /run/control.unit.sock http://localhost/config/applications/djapp- Dans cette commande :
- La méthode HTTP «
PUT» crée un nouvel objet de configuration NGINX Unit à l’emplacement indiqué par le dernier argument (l’URL). Consultez la dernière puce ci-dessous. - L’argument «
--data-binary» indique àcurlde charger le contenu de django.config exactement tel quel, en préservant les sauts de ligne et les retours chariot, sans effectuer aucun traitement. - L’argument «
--unix-socket» définit l’emplacement où l’API NGINX Unit est à l’écoute. (Nous utilisons la commande «sudo» parce que nous utilisons le propriétaire par défaut du socket, «root».) - Le dernier argument indique l’emplacement et le nom du nouvel objet d’application à renseigner avec les données de configuration au format JSON contenues dans django.config :
configest l’objet de configuration de niveau supérieur de NGINX Unit,applicationsl’objet parent des objets d’application etdjapple nom du nouvel objet d’application.
- La méthode HTTP «
- Définissez l’objet d’écoute de l’application. Au lieu de charger un fichier de données de configuration comme à l’étape 4, définissez les données directement dans la ligne de commande
curl, en indiquant que l’applicationdjappécoute sur le port 8000.
$ sudo curl -X PUT --data-binary '{"application":"djapp"}' --unix-socket /run/control.unit.sock 'http://localhost/config/listeners/*:8000'- Répétez la commande «
curl» de l’étape 1 pour afficher la configuration de NGINX Unit, qui inclut désormais notre application Python, djapp, surlignée en orange :
$ sudo curl --unix-socket /run/control.unit.sock http://localhost/config/{
"listeners": {
"127.0.0.1:8090": {
"application": "script_index_php"
},
"127.0.0.1:8091": {
"application": "direct_php"
},
"*:8000": { "application": "djapp" }
},
"applications": {
"script_index_php": {
"type": "php",
"processes": {
"max": 20,
"spare": 5
},
"user": "www-data",
"group": "www-data",
"root": "/var/www/wordpress",
"script": "index.php"
},
"direct_php": {
"type": "php",
"processes": {
"max": 5,
"spare": 0
},
"user": "www-data",
"group": "www-data",
"root": "/var/www/wordpress",
"index": "index.php"
},
"djapp": { "type": "python", "processes": 5, "module": "djapp.wsgi", "path": "/var/www/djapp" }
}
}Résumé
Dans cet article, nous sommes partis de NGINX Unit exécutant en production des applications PHP pour WordPress, puis nous avons ajouté une application Python. Dans la démonstration, j’utilise le tableau de bord de NGINX Plus pour montrer que l’ajout d’une nouvelle application ne perturbe pas les applications existantes, mais vous pouvez utiliser à cette fin n’importe quel outil de supervision du système, comme la commande ps par exemple. La nature dynamique de la configuration de NGINX Unit permet d’économiser les ressources de vos applications en cours d’exécution, tout en garantissant l’absence d’interruption de service lors des nouveaux déploiements et une transition fluide entre les versions des applications.
Pour en savoir plus, consultez unit.nginx.org.
À propos de l’auteur
Articles de blog associés

Tendances actuelles des technologies cloud natives, de l’ingénierie de plateforme et de l’IA
Découvrez les principaux enseignements tirés des réponses à l’enquête annuelle F5 NGINX sur les dernières tendances en matière de technologies cloud natives, de sécurité, d’ingénierie de plateforme et d’IA.
Quels contrôleurs Ingress NGINX sont affectés par les vulnérabilités CVE-2022-4886, CVE-2023-5043 et CVE-2023-5044 ?
Lorsque de nouvelles CVE sont signalées, il est facile de ne plus savoir si elles concernent un outil de contrôleur Ingress NGINX particulier, car il existe plusieurs projets. Cet article présente les CVE et explique comment distinguer les différents projets de contrôleurs Ingress afin de dissiper toute confusion.
Votre API est-elle en temps réel ? Testez sa latence avec l’outil rtapi de NGINX
Votre API répond-elle aux requêtes en moins de 30 ms ? Si ce n’est pas le cas, il ne s’agit pas d’une API en temps réel offrant la faible latence exigée par la grande majorité des organisations. Mesurez la latence de votre API avec l’outil rtapi de NGINX et découvrez comment NGINX peut l’aider à offrir une réactivité en temps réel.

Un testeur d’expressions régulières pour NGINX et NGINX Plus
Le testeur d’expressions régulières (regex) pour NGINX et NGINX Plus vous évite de tâtonner en vous indiquant si une expression régulière utilisée dans un bloc location ou map correspond aux valeurs comme prévu. Il génère la configuration appropriée et affiche les valeurs des groupes de capture.
Caches partagés avec les clusters de cache NGINX Plus, partie 1
Optimisez la capacité de votre cache web en le répartissant entre plusieurs serveurs de cache web NGINX ou NGINX Plus. Découvrez comment procéder dans cet article.
Introduction aux microservices
Les microservices suscitent actuellement beaucoup d’intérêt. Cet article de blog est le premier d’une série de sept consacrée à la conception, au développement et au déploiement de microservices.