Comment servir les applications de flacon avec uWSGI et Nginx sur CentOS 7

introduction

Dans ce guide, nous allons configurer une application Python simple à l’aide du micro-framework Flask sur CentOS 7. La majeure partie de cet article portera sur la configuration du serveur d’applications uWSGI pour le lancement de l’application et sur Nginx pour qu’il agisse en tant que proxy inverse frontal.

Conditions préalables

Avant de commencer ce guide, vous devez avoir un utilisateur non root configuré sur votre serveur. Cet utilisateur doit disposer des privilèges sudo + pour pouvoir exécuter des tâches administratives. Pour savoir comment configurer cela, suivez notre initial initial server server guide de configuration.

Pour en savoir plus sur uWSGI, notre serveur d’applications et la spécification WSGI, vous pouvez consulter la section liée de 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 [ce guide]. Comprendre ces concepts rendra ce guide plus facile à suivre.

Lorsque vous êtes prêt à continuer, lisez la suite.

Installer les composants des référentiels CentOS et EPEL

Notre première étape consistera à installer toutes les pièces dont nous avons besoin des référentiels. Nous devrons ajouter le référentiel EPEL, qui contient des packages supplémentaires, afin d’installer certains des composants dont nous avons besoin.

Vous pouvez activer le référentiel EPEL en tapant:

sudo yum install epel-release

Une fois que l’accès au référentiel EPEL est configuré sur notre système, nous pouvons commencer à installer les packages dont nous avons besoin. Nous allons installer + pip +, le gestionnaire de paquets Python, afin d’installer et de gérer nos composants Python. Nous aurons également un compilateur et les fichiers de développement Python nécessaires à la création de uWSGI. Nous allons également installer Nginx.

Vous pouvez installer tous ces composants en tapant:

sudo yum install python-pip python-devel gcc nginx

Créer un environnement virtuel Python

Nous allons ensuite configurer un environnement virtuel afin d’isoler notre application Flask des autres fichiers Python du système.

Commencez par installer le paquet + virtualenv en utilisant` + pip`:

sudo pip install virtualenv

Nous pouvons maintenant créer un répertoire parent pour notre projet Flask. Déplacez-vous dans le répertoire après l’avoir créé:

mkdir ~/
cd ~/

Nous pouvons créer un environnement virtuel pour stocker les exigences Python de notre projet Flask en tapant:

virtualenv

Cela installera une copie locale de Python et + pip + dans un répertoire appelé ++ dans votre répertoire de projet.

Avant d’installer des applications dans l’environnement virtuel, nous devons l’activer. Vous pouvez le faire en tapant:

source /bin/activate

Votre invite changera pour indiquer que vous travaillez maintenant dans l’environnement virtuel. Cela ressemblera à quelque chose comme ceci + () @: ~ / $ +.

Configurer une application de flacon

Maintenant que vous êtes dans votre environnement virtuel, nous pouvons installer Flask et uWSGI et commencer à concevoir notre application:

Installer Flask et uWSGI

Nous pouvons utiliser l’instance locale de + pip + pour installer Flask et uWSGI. Tapez les commandes suivantes pour obtenir ces deux composants:

pip install uwsgi flask

Créer un exemple d’application

Maintenant que Flask est disponible, nous pouvons créer une application simple. Flask est un micro-cadre. Il n’inclut pas la plupart des outils que pourraient implémenter des infrastructures plus complètes, et existe principalement sous forme de module que vous pouvez importer dans vos projets pour vous aider à initialiser une application Web.

Bien que votre application soit peut-être plus complexe, nous allons créer notre application Flask dans un seul fichier, que nous appellerons + myproject.py +:

nano ~//.py

Dans ce fichier, nous placerons notre code d’application. Fondamentalement, nous devons importer un flacon et instancier un objet Flask. Nous pouvons utiliser cela pour définir les fonctions à exécuter lorsqu’un itinéraire spécifique est demandé. Nous appellerons notre application Flask dans le code + application + pour répliquer les exemples que vous avez trouvés dans la spécification WSGI:

from flask import Flask
application = Flask(__name__)

@application.route("/")
def hello():
   return "<h1 style='color:blue'>Hello There!</h1>"

if __name__ == "__main__":
   application.run(host='0.0.0.0')

Cela définit essentiellement le contenu à présenter lors de l’accès au domaine racine. Enregistrez et fermez le fichier lorsque vous avez terminé.

Vous pouvez tester votre application Flask en tapant:

python .py

Accédez au nom de domaine ou à l’adresse IP de votre serveur, suivi du numéro de port spécifié dans la sortie du terminal (vraisemblablement +: 5000 +) dans votre navigateur Web. Vous devriez voir quelque chose comme ça:

image: https: //assets.digitalocean.com/articles/nginx_uwsgi_wsgi_1404/test_app.png [Exemple d’application en flacon]

Lorsque vous avez terminé, appuyez plusieurs fois sur CTRL-C dans la fenêtre de votre terminal pour arrêter le serveur de développement Flask.

Créer le point d’entrée WSGI

Nous allons ensuite créer un fichier qui servira de point d’entrée pour notre application. Cela indiquera à notre serveur uWSGI comment interagir avec l’application.

Nous appellerons le fichier + wsgi.py +:

nano ~//wsgi.py

Le fichier est incroyablement simple, nous pouvons simplement importer l’instance Flask de notre application puis l’exécuter:

from  import application

if __name__ == "__main__":
   application.run()

Enregistrez et fermez le fichier lorsque vous avez terminé.

Configurer uWSGI

Notre application est maintenant écrite et notre point d’entrée établi. Nous pouvons maintenant passer à uWSGI.

Tester UWSGI Serving

La première chose que nous ferons est de tester pour nous assurer que uWSGI peut servir notre application.

Nous pouvons le faire en lui donnant simplement le nom de notre point d’entrée. Nous allons également spécifier le socket afin qu’il soit démarré sur une interface publique et le protocole afin qu’il utilise HTTP au lieu du protocole binaire + uwsgi +:

uwsgi --socket 0.0.0.0:8000 --protocol=http -w wsgi

Si vous visitez le nom de domaine ou l’adresse IP de votre serveur avec «+: 8000 +» ajouté à la fin de votre navigateur Web, vous devriez voir une page qui ressemble à ceci:

image: https: //assets.digitalocean.com/articles/nginx_uwsgi_wsgi_1404/test_app.png [Exemple d’application en flacon]

Une fois que vous avez vérifié qu’il fonctionne correctement, appuyez sur CTRL-C dans la fenêtre de votre terminal.

Nous en avons terminé avec notre environnement virtuel. Nous pouvons donc le désactiver:

deactivate

Toutes les opérations maintenant seront effectuées sur l’environnement Python du système.

Création d’un fichier de configuration uWSGI

Nous avons testé la capacité de uWSGI à servir notre application, mais nous voulons quelque chose de plus robuste pour une utilisation à long terme. Nous pouvons créer un fichier de configuration uWSGI avec les options souhaitées.

Placez-le dans notre répertoire de projet et appelez-le + myproject.ini +:

nano ~//.ini

A l’intérieur, nous commencerons par l’en-tête + [uwsgi] + afin que uWSGI sache appliquer les paramètres. Nous spécifierons le module en nous référant à notre fichier + wsgi.py +, sans l’extension:

[uwsgi]
module = wsgi

Ensuite, nous dirons à uWSGI de démarrer en mode maître et d’engendrer cinq processus de travail pour répondre aux demandes réelles:

[uwsgi]
module = wsgi

master = true
processes = 5

Lors de nos tests, nous avons exposé uWSGI sur un port réseau. Cependant, nous allons utiliser Nginx pour gérer les connexions client réelles, qui transmettront ensuite les demandes à uWSGI. Étant donné que ces composants fonctionnent sur le même ordinateur, une prise Unix est préférable car elle est plus sécurisée et plus rapide. Nous allons appeler le socket + myproject.sock + et le placer dans ce répertoire.

Nous devrons également modifier les autorisations sur le socket. Nous attribuerons ultérieurement au groupe Nginx la propriété du processus uWSGI. Nous devons donc nous assurer que le propriétaire du groupe du socket peut lire les informations et écrire. Nous allons également nettoyer le socket lorsque le processus s’arrête en ajoutant l’option «vacuum»:

[uwsgi]
module = wsgi

master = true
processes = 5

socket = .sock
chmod-socket = 660
vacuum = true

La dernière chose à faire est de définir l’option `+ die-on-term + '. Cela est nécessaire car le système Upstart init et uWSGI ont des idées différentes sur la signification des différents signaux de processus. Ce paramètre aligne les deux composants du système et implémente le comportement attendu:

[uwsgi]
module = wsgi

master = true
processes = 5

socket = .sock
chmod-socket = 660
vacuum = true

die-on-term = true

Vous avez peut-être remarqué que nous n’avions pas spécifié de protocole, contrairement à la ligne de commande. En effet, par défaut, uWSGI utilise le protocole + uwsgi +, un protocole binaire rapide conçu pour communiquer avec les autres serveurs. Nginx peut parler ce protocole de manière native, il est donc préférable de l’utiliser plutôt que de forcer la communication par HTTP.

Lorsque vous avez terminé, enregistrez et fermez le fichier.

Créer un fichier d’unité Systemd

Le fichier suivant de l’unité de service Systemd est le suivant. La création d’un fichier unité Systemd permettra au système init de CentOS de démarrer automatiquement uWSGI et de servir notre application Flask à chaque démarrage du serveur.

Créez un fichier unité se terminant par + .services dans le répertoire` + / etc / systemd / system` pour commencer:

sudo nano /etc/systemd/system/.service

A l’intérieur, nous commencerons par la section + [Unit] +, 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 qu’après avoir atteint la cible réseau:

[Unit]
Description=uWSGI instance to serve
After=network.target

Ensuite, nous ouvrirons la section + [Service] +. Nous spécifierons l’utilisateur et le groupe sous lesquels le processus doit s’exécuter. Nous allons donner à notre compte utilisateur habituel la propriété du processus puisqu’il possède tous les fichiers pertinents. Nous attribuerons la propriété du groupe d’utilisateurs Nginx afin qu’il puisse communiquer facilement avec les processus uWSGI.

Nous allons ensuite mapper le répertoire de travail et définir la variable d’environnement + PATH + de sorte que le système init sache où se trouvent les exécutables du processus (dans notre environnement virtuel). Nous allons ensuite spécifier le commandé pour démarrer le service. Systemd nécessite que nous donnions le chemin complet à l’exécutable uWSGI, qui est installé dans notre environnement virtuel. Nous allons passer le nom du fichier de configuration + .ini + que nous avons créé dans le répertoire de notre projet:

[Unit]
Description=uWSGI instance to serve
After=network.target

[Service]
User=
Group=nginx
WorkingDirectory=/home//
Environment="PATH=/home////bin"
ExecStart=/home////bin/uwsgi --ini .ini

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:

[Unit]
Description=uWSGI instance to serve
After=network.target

[Service]
User=
Group=nginx
WorkingDirectory=/home//
Environment="PATH=/home////bin"
ExecStart=/home////bin/uwsgi --ini .ini

[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 uWSGI que nous avons créé et l’activer pour qu’il démarre au démarrage:

sudo systemctl start
sudo systemctl enable

Configuration de Nginx en requêtes proxy

Notre serveur d’applications uWSGI devrait maintenant être opérationnel et attendre les demandes sur le fichier de socket dans le répertoire du projet. Nous devons configurer Nginx pour transmettre les requêtes Web à cette socket en utilisant le protocole + uwsgi +.

Commencez par ouvrir le fichier de configuration par défaut de Nginx:

sudo nano /etc/nginx/nginx.conf

Ouvrez un bloc serveur juste au-dessus de l’autre bloc + serveur {} + déjà présent dans le fichier:

http {
   . . .

   include /etc/nginx/conf.d/*.conf;




   server {
       listen 80 default_server;

       . . .

Nous allons mettre toute la configuration de notre application Flask à l’intérieur de ce nouveau bloc. Nous allons commencer par spécifier que ce bloc doit écouter sur le port 80 par défaut et qu’il doit répondre au nom de domaine ou à l’adresse IP de notre serveur:

server {
   listen 80;
   server_name ;
}

La seule autre chose que nous devons ajouter est un bloc d’emplacement qui correspond à chaque demande. Dans ce bloc, nous inclurons le fichier + uwsgi_params + qui spécifie certains paramètres uWSGI généraux à définir. Nous transmettrons ensuite les requêtes au socket que nous avons défini en utilisant la directive + uwsgi_pass +:

server {
   listen 80;
   server_name ;

   location / {
       include uwsgi_params;
       uwsgi_pass unix:/home///.sock;
   }
}

C’est tout ce dont nous avons besoin pour servir notre application. Enregistrez et fermez le fichier lorsque vous avez terminé.

L’utilisateur + nginx + doit avoir accès à notre répertoire d’application pour pouvoir y accéder au fichier de socket. Par défaut, CentOS verrouille de manière très restrictive le répertoire de base de chaque utilisateur. Nous allons donc ajouter l’utilisateur + nginx + à notre groupe d’utilisateurs afin de pouvoir ouvrir les autorisations minimales nécessaires pour accorder l’accès.

Vous pouvez ajouter l’utilisateur + nginx + à votre groupe d’utilisateurs à l’aide de la commande suivante. Remplacez votre propre nom d’utilisateur par le ++ dans la commande:

sudo usermod -a -G  nginx

Nous pouvons maintenant donner à votre groupe d’utilisateurs des autorisations d’exécution sur votre répertoire de base. Cela permettra au processus Nginx d’entrer et d’accéder au contenu dans:

chmod 710 /home/

Une fois les autorisations définies, nous pouvons tester notre fichier de configuration Nginx à la recherche d’erreurs de syntaxe:

sudo nginx -t

Si cela retourne sans indiquer de problème, nous pouvons démarrer et activer le processus Nginx afin qu’il démarre automatiquement au démarrage:

sudo systemctl start nginx
sudo systemctl enable nginx

Vous devriez maintenant pouvoir accéder au nom de domaine ou à l’adresse IP de votre serveur dans votre navigateur Web et voir votre application:

image: https: //assets.digitalocean.com/articles/nginx_uwsgi_wsgi_1404/test_app.png [Exemple d’application en flacon]

Conclusion

Dans ce guide, nous avons créé une application Flask simple dans un environnement virtuel Python. Nous créons un point d’entrée WSGI de sorte que tout serveur d’application compatible WSGI puisse s’interfacer avec ce dernier, puis avons configuré le serveur d’applications uWSGI pour fournir cette fonction. Nous avons ensuite créé un fichier d’unité de service Systemd pour lancer automatiquement le serveur d’application au démarrage. Nous avons créé un bloc de serveur Nginx qui transmet le trafic du client Web au serveur d’applications, en relayant les demandes externes.

Flask est un framework très simple, mais extrêmement flexible, destiné à fournir des fonctionnalités à vos applications sans être trop restrictif en termes de structure et de conception. Vous pouvez utiliser la pile générale décrite dans ce guide pour servir les applications de flacon que vous concevez.