Comment déployer des applications Web2py Python avec uWSGI et Nginx sur CentOS 7

introduction

Le framework web2py est un outil puissant et facile à utiliser pour le développement rapide d’applications Web Python complètes. Avec web2py, vous pouvez facilement développer et gérer vos applications grâce à une interface utilisateur Web administrative.

Dans ce guide, nous montrerons comment déployer une application web2py sur CentOS 7. Nous utiliserons le serveur d’applications uWSGI pour assurer l’interface avec l’application avec plusieurs processus de travail. Devant uWSGI, nous allons configurer Nginx dans une configuration de proxy inverse pour gérer les connexions client réelles. Il s’agit d’une stratégie de déploiement beaucoup plus robuste que l’utilisation du serveur Web2py ou de uWSGI seul.

Prérequis et objectifs

Pour compléter ce guide, vous devez disposer d’une nouvelle instance de serveur CentOS 7 avec un utilisateur non root doté des privilèges sudo + configurés. Vous pouvez apprendre à configurer cela en parcourant notre initial initial guide de configuration du serveur.

Nous allons télécharger le framework web2py et le tester pour nous assurer que l’environnement d’application par défaut fonctionne correctement. Ensuite, nous allons télécharger et installer le conteneur d’applications uWSGI pour servir d’interface entre les requêtes et le code web2py Python. Nous allons configurer Nginx devant celui-ci afin qu’il puisse gérer les connexions client et les requêtes proxy à uWSGI. Nous allons configurer chacun de nos composants pour qu’ils démarrent au démarrage afin de minimiser les interventions administratives.

Télécharger le framework web2py

Notre première étape sera de télécharger le framework web2py actuel. Ceci est maintenu dans un référentiel + git + sur GitHub, le meilleur moyen de le télécharger est donc `` + git + `lui-même.

Nous pouvons télécharger et installer + git + à partir des référentiels CentOS par défaut en tapant:

sudo yum install git

Une fois que + git + est installé, nous pouvons cloner le référentiel dans le répertoire de base de nos utilisateurs. Nous pouvons nommer l’application comme bon nous semble. Dans notre exemple, nous utilisons le nom ++ pour plus de simplicité. Nous devons ajouter l’indicateur + - récursif + car la couche d’abstraction de la base de données est gérée comme son propre sous-module + git +:

git clone --recursive https://github.com/web2py/web2py.git ~/

Le framework web2py sera téléchargé dans un répertoire nommé + myapp + dans votre répertoire personnel.

Nous pouvons tester l’application par défaut en allant dans le répertoire:

cd ~/

L’interface administrative doit être sécurisée par SSL afin que nous puissions créer un simple certificat auto-signé pour le tester. Créez la clé du serveur et le certificat en tapant:

openssl req -x509 -new -newkey rsa:4096 -days 3652 -nodes -keyout .key -out .crt

Vous devrez renseigner certaines informations pour le certificat que vous générez. Le seul élément qui importe réellement dans cette situation est le champ + Common Name +, qui doit référencer le nom de domaine ou l’adresse IP de votre serveur:

. . .

Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:New York
Locality Name (eg, city) []:New York City
Organization Name (eg, company) [Internet Widgits Pty Ltd]:DigitalOcean
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:[email protected]

Lorsque vous avez terminé, une clé SSL et un certificat doivent figurer dans votre répertoire d’application. Celles-ci seront appelées + .key + et + .crt + respectivement.

Une fois cette opération terminée, nous pouvons démarrer l’interface Web web2py pour la tester. Pour ce faire, nous pouvons taper:

python web2py.py -k .key -c .crt -i 0.0.0.0 -p 8000

Vous serez invité à sélectionner un mot de passe pour l’interface administrative.

Maintenant, vous pouvez visiter votre application dans votre navigateur Web en accédant à:

https://:8000

Assurez-vous d’utiliser + https + au lieu de + http + à l’adresse ci-dessus. Vous serez averti que votre navigateur ne reconnaît pas le certificat SSL:

image: https: //assets.digitalocean.com/articles/web2py_uwsgi_nginx_centos7/ssl_warning.png [avertissement SSL de web2py]

Ceci est attendu puisque nous avons signé notre propre certificat. Cliquez sur le lien "Avancé" ou sur tout autre lien fourni par votre navigateur, puis accédez au site comme prévu. Vous verrez l’interface web2py:

image: https: //assets.digitalocean.com/articles/web2py_uwsgi_nginx_centos7/welcome_app.png [application de bienvenue web2py]

En cliquant sur le bouton «Interface administrative» à l’extrême droite, vous devriez pouvoir saisir le mot de passe que vous avez sélectionné lors de l’exécution du serveur et accéder au site d’administration:

image: https: //assets.digitalocean.com/articles/web2py_uwsgi_nginx_centos7/admin_interface.png [interface d’administration de web2py]

Cela vous donne accès au code réel qui exécute vos applications, vous permettant d’éditer et de peaufiner les fichiers à partir de l’interface elle-même.

Lorsque vous avez terminé, tapez CTRL-C dans la fenêtre de votre terminal. Nous avons testé notre application et démontré qu’elle était accessible sur le Web lorsque le serveur de développement web2py était en cours d’exécution.

Installer et configurer uWSGI

Maintenant que l’application web2py est opérationnelle, nous pouvons configurer uWSGI. uWSGI est un serveur d’applications pouvant communiquer avec des applications via une interface standard appelée WSGI. Pour en savoir plus à ce sujet, lisez 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 [cette section] de notre guide sur la configuration de uWSGI et Nginx sur Ubuntu 14.04.

Installer uWSGI

Contrairement au guide cité ci-dessus, dans ce tutoriel, nous allons installer uWSGI globalement. Avant de pouvoir installer uWSGI, nous devrons installer + pip +, le gestionnaire de paquets Python et les fichiers de développement Python sur lesquels repose uWSGI. Nous aurons également besoin d’un compilateur pour construire le binaire réel. Pour obtenir + pip +, nous devrons utiliser le référentiel EPEL, qui contient des paquets supplémentaires.

Nous pouvons activer le référentiel EPEL en tapant:

sudo yum install epel-release

Ensuite, nous pouvons installer les paquets dont nous avons besoin en tapant

sudo yum install python-devel python-pip gcc

Nous pouvons maintenant installer uWSGI globalement avec + pip + en tapant:

sudo pip install uwsgi

Le serveur de conteneur d’applications uWSGI s’interface avec les applications Python à l’aide de la spécification d’interface WSGI. Le framework web2py inclut un fichier conçu pour fournir cette interface dans son répertoire + handlers +. Pour utiliser le fichier, nous devons le déplacer hors du répertoire et dans le répertoire principal du projet:

mv ~//handlers/wsgihandler.py ~/

Avec le gestionnaire WSGI dans le répertoire principal du projet, nous pouvons vérifier que uWSGI est capable de servir l’application en tapant:

uwsgi --http :8000 --chdir ~/ -w wsgihandler:application

Cela devrait redémarrer l’application sur le port 8000. Cette fois, comme nous n’utilisons pas le certificat SSL et la clé, celle-ci sera servie via HTTP simple au lieu de HTTPS. Vous pouvez le tester à nouveau dans votre navigateur en utilisant le protocole + http +. Vous ne pourrez pas tester l’interface d’administration car web2py le désactive lorsque le chiffrement n’est pas disponible.

Lorsque vous avez terminé, tapez CTRL-C dans la fenêtre de votre terminal pour arrêter le serveur.

Création d’un fichier de configuration uWSGI

Maintenant que nous savons que uWSGI peut servir l’application, nous pouvons créer un fichier de configuration uWSGI avec les informations de notre application.

Créez un répertoire dans + / etc / uwsgi / sites + pour stocker nos configurations, puis accédez à ce répertoire:

sudo mkdir -p /etc/uwsgi/sites
cd /etc/uwsgi/sites

Nous appellerons notre fichier de configuration + myapp.ini +:

sudo nano .ini

Dans le fichier de configuration, nous devons commencer par un en-tête + [uwsgi] + sous lequel seront placées toutes nos directives de configuration. Après l’en-tête, nous indiquerons le chemin du répertoire de notre application et lui indiquerons le module à exécuter. Ce seront les mêmes informations que nous avons utilisées précédemment sur la ligne de commande. Vous n’avez pas besoin de modifier la ligne de module:

[uwsgi]
chdir = /home//
module = wsgihandler:application

Ensuite, nous devons spécifier que nous voulons que uWSGI fonctionne en mode maître. Nous voulons générer cinq processus de travail:

[uwsgi]
chdir = /home//
module = wsgihandler:application

master = true
processes = 5

Ensuite, nous devons spécifier comment nous voulons que uWSGI obtienne des connexions. Lors de notre test du serveur uWSGI, nous avons accepté les connexions HTTP normales. Cependant, puisque nous allons configurer Nginx en tant que proxy inverse devant uWSGI, nous avons d’autres options.

Au lieu d’utiliser un port réseau, tous les composants fonctionnant sur un seul serveur, nous pouvons utiliser un socket Unix. Ceci est plus sécurisé et offre de meilleures performances. Ce socket n’utilisera pas HTTP, mais implémentera le protocole + uwsgi + de uWSGI, qui est un protocole binaire rapide conçu pour communiquer avec d’autres serveurs. Nginx peut utiliser un proxy natif en utilisant le protocole + uwsgi +, il s’agit donc de notre meilleur choix.

Nous devons définir l’utilisateur qui exécutera les processus sur notre propre utilisateur, car nous possédons les fichiers. Nous allons également modifier les autorisations et la propriété du socket, car nous donnerons un accès en écriture au serveur Web. Le socket lui-même sera placé dans le répertoire + / run / uwsgi + (nous allons créer ce répertoire un peu) où uWSGI et Nginx peuvent l’atteindre. Nous allons définir l’aspiration pour que le fichier de socket soit automatiquement nettoyé lorsque le service est arrêté:

[uwsgi]
chdir = /home//
module = wsgihandler:application

master = true
processes = 5

uid =
socket = /run/uwsgi/.sock
chown-socket = :nginx
chmod-socket = 660
vacuum = true

Notre fichier de configuration uWSGI est maintenant complet. Enregistrez et fermez le fichier.

Créer un fichier d’unité Systemd pour uWSGI

Nous avons créé un fichier de configuration pour uWSGI, mais nous n’avons toujours pas configuré notre serveur d’applications pour qu’il démarre automatiquement au démarrage. Pour implémenter cette fonctionnalité, nous pouvons créer un fichier unité Systemd.

Nous allons créer le fichier d’unité dans le répertoire + / etc / systemd / system + où les fichiers d’unité créés par l’utilisateur sont conservés. Nous appellerons votre fichier + uwsgi.service:

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

Commencez par la section + [Unit] +, utilisée pour spécifier les métadonnées. Nous allons simplement mettre une description de notre service ici:

[Unit]
Description=uWSGI Emperor service

Ensuite, nous ouvrirons la section [Service]. Nous allons utiliser la directive ExecStartPre pour configurer les éléments nécessaires à l’exécution de notre serveur. Cela garantira que le répertoire / run / uwsgi est créé et que notre utilisateur normal le possède avec le groupe Nginx en tant que propriétaire du groupe. Mkdir avec l’indicateur -p et la commande chown retournent avec succès même s’ils existent déjà. C’est ce que nous voulons.

Pour la commande de démarrage réelle, spécifiée par la directive ExecStart, nous allons pointer sur l’exécutable uwsgi. Nous lui indiquerons de fonctionner en «mode Emperor», ce qui lui permettra de gérer plusieurs applications à l’aide des fichiers trouvés dans / etc / uwsgi / sites. Nous ajouterons également les éléments nécessaires à Systemd pour gérer correctement le processus. Celles-ci sont extraites de la documentation uWSGI here:

[Unit]
Description=uWSGI Emperor service

[Service]
ExecStartPre=/usr/bin/bash -c 'mkdir -p /run/uwsgi; chown :nginx /run/uwsgi'
ExecStart=/usr/bin/uwsgi --emperor /etc/uwsgi/sites
Restart=always
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all

Il ne reste plus qu’à ajouter la section [Install]. Cela nous permet de spécifier quand le service doit être démarré automatiquement. Nous allons lier notre service à l’état du système multi-utilisateur. Chaque fois que le système est configuré pour plusieurs utilisateurs (la condition de fonctionnement normale), notre service sera activé:

[Unit]
Description=uWSGI Emperor service

[Service]
ExecStartPre=/usr/bin/bash -c 'mkdir -p /run/uwsgi; chown :nginx /run/uwsgi'
ExecStart=/usr/bin/uwsgi --emperor /etc/uwsgi/sites
Restart=always
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all

[Install]
WantedBy=multi-user.target

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

Nous ne pourrons pas démarrer le service avec succès à ce stade car il repose sur la disponibilité de l’utilisateur nginx. Nous devrons attendre le démarrage du service uWSGI après l’installation de Nginx.

Installer et configurer Nginx en tant que proxy inverse

Avec uWSGI configuré et prêt à fonctionner, nous pouvons maintenant installer et configurer Nginx en tant que proxy inverse. Cela peut être téléchargé avec + yum + en tapant:

sudo yum install nginx

Une fois que Nginx est installé, nous pouvons continuer et modifier la configuration du bloc serveur. Nous allons éditer le fichier de configuration principal de Nginx:

sudo nano /etc/nginx/nginx.conf

L’application web2py détecte si vous vous connectez avec un cryptage HTTP simple ou avec un cryptage SSL. Pour cette raison, notre fichier contiendra en fait un bloc de serveur pour chacun. Nous allons commencer par le bloc de serveur configuré pour fonctionner sur le port 80.

Changez le + nom_serveur + pour référencer le nom de domaine ou l’adresse IP où votre site devrait être accessible. Ensuite, nous allons créer un bloc + emplacement {} + qui correspondra aux demandes de contenu statique. Fondamentalement, nous voulons utiliser des expressions régulières pour faire correspondre les demandes se terminant par + / static / + avec un composant de chemin précédent. Nous voulons mapper ces requêtes au répertoire + applications + de notre projet web2py. Assurez-vous de référencer le répertoire de base de votre utilisateur et le nom de l’application:

server {
   listen                  80 default_server;
   server_name             ;
   root                    /usr/share/nginx/html;

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





   . . .

Ensuite, nous devons ajuster le bloc + location / {} + pour transmettre les requêtes à notre socket uWSGI. Nous devons simplement inclure le fichier de paramètres uWSGI fourni avec Nginx et transmettre les requêtes au socket que nous avons configuré (dans notre fichier uWSGI + .ini +):

server {
   listen                  80 default_server;
   server_name             ;
   root                    /usr/share/nginx/html;

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

   location ~* /(\w+)/static/ {
       root /home/user/myapp/applications/;
   }

   location / {


   }
}

   . . .

Ce sera tout ce dont nous avons besoin pour notre premier bloc de serveurs.

Au bas du fichier, mais à l’intérieur du crochet de fermeture + http {} +, créez un autre bloc + serveur {} +. Nous allons l’utiliser pour configurer les connexions SSL.

Commencez par les bases. Ce bloc serveur écoute les connexions sur le port 443, le port SSL par défaut. Nous allons définir le nom de domaine ou l’adresse IP du serveur, comme nous l’avons fait pour le bloc de serveurs du port 80. Pour démarrer la configuration SSL réelle, nous spécifions que SSL doit être activé pour ce bloc et nous indiquerons le chemin d’accès au certificat SSL et la clé à utiliser pour chiffrer la connexion. Nous allons y déplacer les fichiers dans un instant:

http {
   . . .
   server {
       listen 80;
       . . .
   }








}

Nous allons continuer avec un peu de passe-partout SSL destiné à établir les protocoles et les chiffrements acceptés. Ensuite, nous pouvons configurer le même bloc + location / {} + que nous avons configuré dans le bloc de serveur du port 80:

http {
   . . .
   server {
       listen 80;
       . . .
   }
   server {
       listen 443;
       server_name ;

       ssl on;
       ssl_certificate /etc/nginx/ssl/myapp.crt;
       ssl_certificate_key /etc/nginx/ssl/myapp.key;









   }
}

Vous devez maintenant avoir deux blocs de serveur configurés dans ce fichier. Enregistrez et fermez-le lorsque vous avez terminé.

Étapes finales

Ensuite, nous devons déplacer les certificats SSL dans le répertoire que nous avons spécifié. Créez d’abord le répertoire:

sudo mkdir -p /etc/nginx/ssl

Maintenant, déplacez le certificat et la clé que vous avez créés dans ce répertoire. Si vous avez un certificat SSL signé par une autorité de certification commerciale, vous pouvez remplacer le certificat et la clé correspondante ici afin d’éviter des avertissements de certificat SSL non fiables pour vos visiteurs:

sudo mv ~//.crt /etc/nginx/ssl
sudo mv ~//.key /etc/nginx/ssl

Modifiez les autorisations afin que les utilisateurs non root ne puissent pas accéder à ce répertoire:

sudo chmod 700 /etc/nginx/ssl

L’utilisateur + nginx + doit avoir accès à notre répertoire d’applications pour pouvoir directement servir les fichiers statiques en fonction des besoins. 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 pour pouvoir ensuite ouvrir les autorisations minimales nécessaires à son fonctionnement.

Ajoutez l’utilisateur + nginx + à votre groupe en tapant ceci. Remplacez votre nom d’utilisateur par + user + dans la commande ci-dessous:

sudo usermod -a -G  nginx

Maintenant, nous allons donner à notre groupe d’utilisateurs des autorisations d’exécution sur notre répertoire, ce qui permettra au processus Nginx d’entrer et d’accéder au contenu dans:

chmod 710 /home/

Maintenant, vérifiez votre fichier de configuration Nginx pour les erreurs de syntaxe:

sudo nginx -t

Si aucune erreur de syntaxe n’est signalée, nous pouvons poursuivre et lancer Nginx:

sudo service nginx start

Nous pouvons également démarrer notre service uWSGI:

sudo service uwsgi start

La dernière chose à faire est de copier le fichier de paramètres de notre application afin qu’il soit lu correctement lors de la connexion au port 443. Ceci contient le mot de passe que nous avons configuré pour l’interface administrative. Nous devons simplement le copier sous un nouveau nom qui indique le port 443 au lieu du port 8000:

cp ~//parameters_8000.py ~//parameters_443.py

Avec cela, vous devriez pouvoir accéder à votre serveur en utilisant son nom de domaine ou son adresse IP. Utilisez + https + si vous souhaitez vous connecter à l’interface administrative.

Si tout se passe bien, vous pouvez activer Nginx et uWSGI pour qu’ils démarrent au démarrage en tapant:

sudo systemctl enable nginx
sudo systemctl enable uwsgi

Conclusion

Dans ce guide, nous avons configuré un exemple de projet web2py pour s’exercer au déploiement. Nous avons configuré uWSGI pour agir en tant qu’interface entre les demandes de nos applications et celles de nos clients. Nous avons ensuite configuré Nginx devant uWSGI pour permettre les connexions SSL et traiter efficacement les demandes des clients.

Le projet web2py simplifie le développement de sites et d’applications Web en fournissant une interface Web fonctionnelle dès le début. 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.