Préparation d'un serveur pour la publication d'une application Web en Python

Bonjour, Habrovsk!

Il y avait du temps libre, et il y avait un désir de faire une petite application web. Il y a une idée (pour recevoir des données d'un capteur météo, stocker dans la base de données et faire quelque chose d'intéressant), un serveur gratuit sur centos aussi. Tutoriels sur le réglage semblent être les mêmes aussi ... Mais au moment de l' écriture, pas un seul travail pleinement un a été trouvé. Si vous souhaitez également déployer l'application sur un serveur CentOS 7.4 à l'aide de python3. * Bundle, uwsgi et nginx, bienvenue dans cat.

Donc, ce qui devrait déjà être et ce qui ne sera pas couvert dans cet article:

  1. Un serveur physique ou virtuel exécutant CentOS 7.4 (les performances ne sont pas garanties pour les autres systèmes d'exploitation et versions).
  2. Accès au serveur avec des privilèges de superutilisateur * si le serveur est virtuel, alors il est supposé qu'il y a la possibilité et la possibilité de s'y connecter via SSH).

Après vous être connecté en tant qu'utilisateur root, la première étape consiste à créer un nouvel utilisateur avec des droits d'administrateur (ce n'est pas nécessaire, mais au moins un bon ton):

adduser developer
passwd developer

Ici, vous devrez saisir et confirmer le mot de passe utilisateur

usermod -aG wheel developer

Ajouter un utilisateur au groupe d'administrateurs locaux

su - developer

Passez à l'utilisateur fraîchement créé.

Préparez maintenant l'environnement:

sudo yum install -y epel-release
sudo yum install -y python3 python3-pip python3-devel nginx gcc
sudo yum update -y python36 python2
sudo yum groupinstall -y "Development Tools" "Development Libraries"
sudo yum install -y python3-devel python36-virtualenv

Je voudrais attirer l'attention sur l'avant-dernière ligne - «Outils de développement» et «Bibliothèques de développement» sont nécessaires pour le lancement correct de l'environnement virtuel. Nous utilisons le drapeau pour que l'équipe se remplisse sans demander de confirmation.

Vous pouvez maintenant commencer à créer le répertoire de travail:

sudo mkdir /opt/myproject && cd /opt/myproject
sudo chown -R developer /opt/
python3 -m venv myprojectenv
source myprojectenv/bin/activate

pip3 install --upgrade pip
pip3 install uwsgi flask

Nous

vi /opt/myproject/wsgi.pyallons maintenant préparer le point d'entrée de l'application Web: (ci-après j'utiliserai l'éditeur vi, mais c'est une question de goût)

def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return ["<h1 style='color:blue'>Testing Success!</h1>"]

Ce code après le lancement nous permettra de nous assurer que toutes les étapes prises précédemment ont réussi. Pour tester, exécutez le service:

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

Avec une connexion physique ljcnegt ou rdp, le résultat peut être vérifié dans un navigateur à 0.0.0.0:8080. Avec une connexion SSH, ouvrez une nouvelle session et testez avec curl:

curl -v 0.0.0.0:8080

L'indicateur -v vous permet de voir la sortie complète.

Une fois les tests terminés, vous devez mettre fin au service en appuyant sur CTRL + C (sinon vous devez rechercher le processus et le tuer avec kill. C'est également une sortie, mais certainement moins pratique).

Vous pouvez maintenant créer l'application Web principale:

vi /opt/myproject/myproject.py

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')

Le processus de test est assez similaire au précédent - nous lançons l'application à l'aide de la commande python3 /opt/myproject/myproject.pyet vérifions. Le résultat devrait être le même.

Modifiez maintenant le point d'entrée pour que lors de son appel, notre application démarre:

vi /opt/myproject/wsgi.py

from myproject import application

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

Maintenant le plus difficile et le plus intéressant. Il est temps de créer un service à partir de cette application qui fonctionnera automatiquement et en arrière-plan.

Tout d'abord, préparez le fichier ini pour uwsgi:

vi /opt/myproject/myproject.ini

[uwsgi]
wsgi-file = myproject/wsgi.py

master = true
processes = 2

uid = developer
socket = /tmp/uwsgi/myproject.sock
chown-socket = nginx:nginx
chmod-socket = 666
vacuum = true

die-on-term = true

Ici, je veux prêter attention aux lignes suivantes:

  1. socket = /tmp/uwsgi/myproject.sock - pour accélérer le service, vous devez utiliser unix-socket, et pour que nginx s'y connecte, créez-le dans le dossier temporaire / tmp / uwsgi
  2. chown-socket = nginx: nginx transférera les droits d'utilisation du socket à l'utilisateur nginx
  3. chmod-socket = 666 - sert le même but que le précédent. Différents manuels et astuces ont des valeurs de paramètres différentes - 664, 665, 777 - mais il a été expérimentalement établi que 666 est un fonctionnement minimal.

Vous pouvez maintenant passer directement à la création du service:

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

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

[Service]
ExecStartPre=-/usr/bin/bash -c 'mkdir -p /tmp/uwsgi chown nginx:nginx /tmp/uwsgi'
ExecStart=/usr/bin/bash -c 'cd /opt/myproject; source myprojectenv/bin/activate; uwsgi --ini myproject.ini'
ExecStartPost=/usr/bin/bash -c 'setenforce 0'
PrivateTmp=false
[Install]
WantedBy=multi-user.target

Toutes les lignes intéressantes sont dans le bloc Service:

  1. ExecStartPre est une commande que le gestionnaire système exécutera avant de démarrer le service.

    - / usr / bin / bash -c annonce le début de la prochaine séquence de commandes, et 'mkdir -p / tmp / uwsgi chown nginx: nginx / tmp / uwsgi' crée un dossier temporaire pour le socket et transfère les droits à l'utilisateur nginx.
  2. ExecStart est la commande qui démarre le service directement et nous y allons séquentiellement vers le répertoire de travail, activons l'environnement virtuel et démarrons le serveur uwsgi à partir du fichier ini.
  3. ExecStartPost - une commande qui s'exécute après le démarrage du service. Dans notre cas, il est nécessaire pour le transfert correct des requêtes du serveur nginx vers le serveur uwsgi.
  4. PrivateTmp = false est un paramètre qui rend le dossier temporaire créé visible aux autres processus.

Exécutez maintenant le service:

systemctl start myproject
systemctl status myproject
systemctl enable myproject

La dernière commande le fera démarrer automatiquement après un redémarrage du serveur.

Et la dernière secousse - nous allons configurer le serveur nginx et rendre notre application Web disponible pour le réseau externe. Le journal de son travail peut toujours être consulté à l'aide de la commande

journalctl -u  myproject

sudo vi /usr/lib/systemd/system/nginx.service

Recherchez le bloc [Service] et ajoutez PrivateTmp = false à la fin.

Après cela, redémarrez les démons avec la commande. systemctl daemon-reload

Maintenant, nous passons directement à la configuration du serveur:

vi /etc/nginx/nginx.conf

http {
    . . .

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

    server {
        listen 80 default_server;

        . . .

Recherchez le bloc http et ajoutez un nouveau serveur:

server {
    listen 80;
    server_name server_domain_or_IP;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:/tmp/uwsgi/myproject.sock;
    }
}

Reste maintenant à allumer le serveur et à éditer les règles sur le pare-feu:

systemctl start nginx
systemctl enable nginx

firewall-cmd --zone=public --permanent --add-service=http
firewall-cmd --zone=public --permanent --add-service=https

firewall-cmd --reload

Désormais, lors de l'accès au serveur par son nom de domaine ou son adresse IP, nous recevrons une réponse de notre application Flask.

J'espère que ce matériel vous sera utile.

All Articles