Comment servir les applications en flacon avec Gunicorn 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 traitera de la configuration du serveur d’applications Gunicorn pour le lancement de l’application et de 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ègessudo pour pouvoir effectuer des fonctions administratives. Pour savoir comment configurer cela, suivez nosinitial server setup guide.

Pour en savoir plus sur la spécification WSGI que notre serveur d'application utilisera pour communiquer avec notre application Flask, vous pouvez lire la section liée dethis 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 à Gunicorn. 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 packagevirtualenv en utilisantpip:

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 ~/myproject
cd ~/myproject

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

virtualenv myprojectenv

Cela installera une copie locale de Python et depip dans un répertoire appelémyprojectenv dans le répertoire de votre projet.

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

source myprojectenv/bin/activate

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

Configurer une application de flacon

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

Installez Flask et Gunicorn

Nous pouvons utiliser l'instance locale depip pour installer Flask et Gunicorn. Tapez les commandes suivantes pour obtenir ces deux composants:

pip install gunicorn 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 plus complexe, nous créerons notre application Flask dans un seul fichier, que nous appelleronsmyproject.py:

nano ~/myproject/myproject.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 codeapplication pour reproduire les exemples que vous trouverez dans la spécification WSGI:

from flask import Flask
application = Flask(__name__)

@application.route("/")
def hello():
    return "

Hello There!

" 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 myproject.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 (très probablement:5000) dans votre navigateur Web. Vous devriez voir quelque chose comme ça:

Flask sample app

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 Gunicorn comment interagir avec l'application.

Nous appellerons le fichierwsgi.py:

nano ~/myproject/wsgi.py

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

from myproject import application

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

Enregistrez et fermez le fichier lorsque vous avez terminé.

Tester la capacité de Gunicorn à servir le projet

Avant de continuer, nous devrions vérifier que Gunicorn peut correctement.

Nous pouvons le faire en lui donnant simplement le nom de notre point d’entrée. Nous spécifierons également l’interface et le port auxquels vous souhaitez vous connecter afin qu’elle soit lancée sur une interface accessible au public:

cd ~/myproject
gunicorn --bind 0.0.0.0:8000 wsgi

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

Flask sample app

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é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 Gunicorn et de servir notre application Flask à chaque démarrage du serveur.

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

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

À l'intérieur, nous allons commencer par une 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 qu’après avoir atteint la cible réseau:

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

Ensuite, nous allons ouvrir 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 Gunicorn.

Nous allons ensuite mapper le répertoire de travail et définir la variable d'environnementPATH afin que le système init sache où se trouvent nos exécutables pour le 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 au fichier exécutable Gunicorn, qui est installé dans notre environnement virtuel.

Nous lui dirons de démarrer 3 processus de travail (ajustez-le si nécessaire). Nous lui dirons également de créer et de se lier à un fichier socket Unix dans notre répertoire de projet appelémyproject.sock. Nous allons définir une valeur umask de007 afin que le fichier socket soit créé, donnant accès au propriétaire et au groupe, tout en restreignant les autres accès. Enfin, nous devons passer le nom du fichier de point d’entrée WSGI:

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

[Service]
User=user
Group=nginx
WorkingDirectory=/home/user/myproject
Environment="PATH=/home/user/myproject/myprojectenv/bin"
ExecStart=/home/user/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi

Le dernier élément que nous devons ajouter au fichier est 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=Gunicorn instance to serve myproject
After=network.target

[Service]
User=user
Group=nginx
WorkingDirectory=/home/user/myproject
Environment="PATH=/home/user/myproject/myprojectenv/bin"
ExecStart=/home/user/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi

[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 myproject
sudo systemctl enable myproject

Configuration de Nginx en requêtes proxy

Notre serveur d’applications Gunicorn 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 à ce socket en apportant de petits ajouts à son fichier de configuration.

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 blocserver {} qui est déjà dans le fichier:

http {
    . . .

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

    server {
    }

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

La seule autre chose que nous devons ajouter est un bloc d’emplacement qui correspond à chaque demande. Au sein de ce bloc, nous allons définir des en-têtes HTTP standard pour permettre à Gunicorn de disposer d’informations sur la connexion du client distant. Nous transmettrons ensuite le trafic au socket spécifié dans notre fichier d'unité Systemd:

server {
    listen 80;
    server_name server_domain_or_IP;

    location / {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://unix:/home/user/myproject/myproject.sock;
    }
}

Enregistrez et fermez le fichier lorsque vous avez terminé.

L'utilisateur denginx doit avoir accès à notre répertoire d'application pour y accéder au fichier socket. Par défaut, CentOS verrouille le répertoire personnel de chaque utilisateur de manière très restrictive, nous allons donc ajouter l'utilisateurnginx à notre groupe d'utilisateurs afin que nous puissions ensuite ouvrir les autorisations minimales nécessaires pour accorder l'accès.

Vous pouvez ajouter l'utilisateurnginx à votre groupe d'utilisateurs avec la commande suivante. Remplacez lesuser par votre propre nom d'utilisateur dans la commande:

sudo usermod -a -G user nginx

Maintenant, nous pouvons donner à notre groupe d'utilisateurs des autorisations d'exécution sur notre répertoire personnel. Cela permettra au processus Nginx d’entrer et d’accéder au contenu dans:

chmod 710 /home/user

Une fois les autorisations définies, nous pouvons tester notre fichier de configuration Nginx pour rechercher des 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:

Flask sample app

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 Gunicorn pour fournir cette fonction. Nous avons ensuite créé un fichier d’unité Systemd pour lancer automatiquement le serveur d’applications 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 requêtes 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.

Related