One place for hosting & domains

      Gunicorn

      Comment servir des applications Flask avec Gunicorn et Nginx sur Ubuntu 20.04


      Introduction

      Dans ce guide, vous allez construire une application Python en utilisant le micro-framework Flask sur Ubuntu 20.04. L’essentiel de cet article portera sur la configuration du serveur d’application Gunicorn et sur la manière de lancer l’application et de configurer Nginx pour qu’il agisse comme un proxy inversé en amont.

      Conditions préalables

      Avant de démarrer ce guide, vous devriez avoir :

      • Un serveur avec Ubuntu 20.04 installé et un utilisateur non root avec des privilèges sudo. Suivez notre guide de configuration initiale du serveur pour vous aider.
      • Nginx installé, en suivant les étapes 1 et 2 de Comment installer Nginx sur Ubuntu 20.04.
      • Un nom de domaine configuré pour pointer vers votre serveur. Vous pouvez en acheter un sur Namecheap ou en obtenir un gratuitement sur Freenom.  Vous pouvez apprendre comment pointer des domaines vers DigitalOcean en suivant la documentation pertinente sur les domaines et le DNS. Veillez à créer les enregistrements DNS suivants :

        • Un enregistrement A avec your_domain pointant sur l’adresse IP publique de votre serveur.
        • Un enregistrement A avec www.your_domain​​​​​​ pointant à l’adresse IP publique de votre serveur.
      • Être familiarisé avec la spécification WSGI, que le serveur Gunicorn utilisera pour communiquer avec votre application Flask. Cette discussion couvre le WSGI plus en détail.

      Étape 1 — Installation des composants depuis les référentiels Ubuntu

      Notre première étape consistera à installer tous les éléments dont nous avons besoin depuis les référentiels Ubuntu. Cela inclut pip, le gestionnaire de paquets Python, qui gérera nos composants Python. Nous obtiendrons également les fichiers de développement Python nécessaires pour construire certains des composants de Gunicorn.

      Tout d’abord, nous allons mettre à jour l’index local des paquets et installer les paquets qui nous permettront de construire notre environnement Python. Ceux-ci comprendront python3-pip, ainsi que quelques autres paquets et outils de développement nécessaires pour un environnement de programmation robuste :

      • sudo apt update
      • sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools

      Une fois ces paquets en place, passons à la création d’un environnement virtuel pour notre projet.

      Étape 2 — Création d’un environnement virtuel Python

      Ensuite, nous allons configurer un environnement virtuel pour isoler notre application Flask des autres fichiers Python du système.

      Commencez par installer le paquet python3-venv, qui installera le module venv :

      • sudo apt install python3-venv

      Ensuite, créons un répertoire parent pour notre projet Flask. Déplacez-vous dans le répertoire après l’avoir créé :

      • mkdir ~/myproject
      • cd ~/myproject

      Créez un environnement virtuel pour stocker les exigences Python de votre projet Flask en tapant :

      • python3 -m venv myprojectenv

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

      Avant d’installer des applications dans l’environnement virtuel, vous devez l’activer. Faites-le en tapant :

      • source myprojectenv/bin/activate

      Votre invite changera pour indiquer que vous travaillez maintenant dans l’environnement virtuel. Cela ressemblera à ce qui suit (myprojectenv)user@host:~/myproject$.

      Étape 3 — Configuration d’une application Flask

      Maintenant que vous êtes dans votre environnement virtuel, vous pouvez installer Flask et Gunicorn et commencer à concevoir votre application.

      Tout d’abord, installons wheel avec l’instance locale de pip pour nous assurer que nos paquets s’installeront même s’il leur manque des archives de wheel :

      Note


      Quelle que soit la version de Python que vous utilisez, lorsque l’environnement virtuel est activé, vous devez utiliser la commande pip (et non pip3).

      Ensuite, installons Flask et Gunicorn :

      • pip install gunicorn flask

      Création d’un exemple d’application

      Maintenant que vous disposez de Flask, vous pouvez créer une application simple. Flask est un microframework. Il n’inclut pas de nombreux outils que des frameworks plus complets pourraient inclure, et existe principalement sous la forme d’un module que vous pouvez importer dans vos projets pour vous aider à initialiser une application web.

      Bien que votre application puisse être plus complexe, nous allons créer notre app Flask dans un seul fichier, appelé myproject.py :

      • nano ~/myproject/myproject.py

      Le code de l’application se trouvera dans ce fichier. Il importera Flask et instanciera un objet Flask. Vous pouvez l’utiliser pour définir les fonctions qui doivent être exécutées lorsqu’un itinéraire spécifique est demandé :

      ~/myproject/myproject.py

      from flask import Flask
      app = Flask(__name__)
      
      @app.route("/")
      def hello():
          return "<h1 style="color:blue">Hello There!</h1>"
      
      if __name__ == "__main__":
          app.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é.

      Si vous avez suivi le guide de configuration initiale du serveur, vous devriez disposer d’un pare-feu UFW activé. Pour tester l’application, vous devez autoriser l’accès au port 5000 :

      Vous pouvez maintenant tester votre application Flask en tapant :

      Vous obtiendrez un résultat comme suit, avec un avertissement utile vous rappelant de ne pas utiliser cette configuration de serveur en production :

      Output

      * Serving Flask app "myproject" (lazy loading) * Environment: production WARNING: Do not use the development server in a production environment. Use a production WSGI server instead. * Debug mode: off * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

      Visitez l’adresse IP de votre serveur, suivie de:5000 dans votre navigateur web :

      http://your_server_ip:5000
      

      Vous devriez voir quelque chose comme ceci :

      Exemple d'application Flask

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

      Création du point d’entrée WSGI

      Ensuite, créons un fichier qui servira de point d’entrée pour notre application. Cela indiquera à notre serveur Gunicorn comment interagir avec l’application.

      Appelons le fichier wsgi.py :

      Dans ce fichier, importons l’instance Flask de notre application et exécutons-la :

      ~/myproject/wsgi.py

      from myproject import app
      
      if __name__ == "__main__":
          app.run()
      

      Enregistrez et fermez le fichier lorsque vous avez terminé.

      Étape 4 — Configuration de Gunicorn

      Votre application est maintenant écrite avec un point d’entrée établi. Nous pouvons maintenant passer à la configuration de Gunicorn.

      Avant de continuer, nous devrions vérifier que Gunicorn peut servir correctement l’application.

      Nous pouvons le faire en lui passant simplement le nom de notre point d’entrée. Celui-ci est construit comme le nom du module (moins l’extension .py), plus le nom de l’appelable dans l’application. Dans notre cas, il s’agit de wsgi:app.

      Nous spécifierons également l’interface et le port à utiliser pour que l’application soit lancée sur une interface accessible au public :

      • cd ~/myproject
      • gunicorn --bind 0.0.0.0:5000 wsgi:app

      Vous devriez voir une sortie similaire à la suivante :

      Output

      [2020-05-20 14:13:00 +0000] [46419] [INFO] Starting gunicorn 20.0.4 [2020-05-20 14:13:00 +0000] [46419] [INFO] Listening at: http://0.0.0.0:5000 (46419) [2020-05-20 14:13:00 +0000] [46419] [INFO] Using worker: sync [2020-05-20 14:13:00 +0000] [46421] [INFO] Booting worker with pid: 46421

      Visitez à nouveau dans votre navigateur web l’adresse IP de votre serveur avec :5000 ajouté à la fin :

      http://your_server_ip:5000
      

      Vous devriez voir la sortie de votre application :

      Exemple d'application Flask

      Lorsque vous avez la confirmation qu’il fonctionne correctement, appuyez sur CTRL-C dans la fenêtre de votre terminal.

      Nous en avons maintenant fini avec notre environnement virtuel, nous pouvons donc le désactiver :

      Toutes les commandes Python utiliseront à nouveau l’environnement Python du système.

      Ensuite, créons le fichier d’unité de service systemd. La création d’un fichier d’unité systemd permettra au système d’init d’Ubuntu de lancer automatiquement Gunicorn et de servir l’application Flask à chaque démarrage du serveur.

      Créez un fichier d’unité se terminant par .service dans le répertoire /etc/system/system pour commencer

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

      Dans celui-ci, nous commencerons par la section [Unit], qui est utilisée pour spécifier les métadonnées et les dépendances. Ajoutons ici une description de notre service et disons au système d’initialisation de ne le lancer qu’une fois que l’objectif de mise en réseau a été atteint :

      /etc/systemd/system/myproject.service

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

      Ensuite, ouvrons la section [Service]. Celle-ci indiquera l’utilisateur et le groupe sous lequel nous voulons que le processus s’exécute. Donnons à notre compte utilisateur habituel la propriété du processus puisqu’il possède tous les fichiers pertinents. Donnons également la propriété du groupe au groupe www-data afin que Nginx puisse facilement communiquer avec les processus Gunicorn.  N’oubliez pas de remplacer le nom d’utilisateur ici par votre nom d’utilisateur :

      /etc/systemd/system/myproject.service

      [Unit]
      Description=Gunicorn instance to serve myproject
      After=network.target
      
      [Service]
      User=sammy
      Group=www-data
      

      Ensuite, définissons le répertoire de travail et la variable d’environnement PATH afin que le système d’initialisation sache que les exécutables du processus sont situés dans notre environnement virtuel. Précisons également la commande de démarrage du service. Cette commande fera ce qui suit :

      • Démarrez 3 processus de travail (mais vous devez ajuster cela si nécessaire)
      • Créez et reliez à un fichier socket Unix, myproject.sock, dans notre répertoire de projet. Nous fixerons une valeur d’umask de 007 pour que le fichier socket soit créé en donnant l’accès au propriétaire et au groupe, tout en limitant tout autre accès
      • Précisez le nom du fichier du point d’entrée du WSGI, ainsi que le nom de l’appel Python dans ce fichier (wsgi:app)

      Systemd exige que nous donnons le chemin complet à l’exécutable Gunicorn, qui est installé dans notre environnement virtuel.

      N’oubliez pas de remplacer le nom d’utilisateur et les chemins du projet par vos propres informations :

      /etc/systemd/system/myproject.service

      [Unit]
      Description=Gunicorn instance to serve myproject
      After=network.target
      
      [Service]
      User=sammy
      Group=www-data
      WorkingDirectory=/home/sammy/myproject
      Environment="PATH=/home/sammy/myproject/myprojectenv/bin"
      ExecStart=/home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
      

      Enfin, ajoutons une section [Install]. Cela indiquera à systemd à quoi lier ce service si nous autorisons son démarrage au boot. Nous voulons que ce service démarre lorsque le système multi-utilisateurs normal est opérationnel :

      /etc/systemd/system/myproject.service

      [Unit]
      Description=Gunicorn instance to serve myproject
      After=network.target
      
      [Service]
      User=sammy
      Group=www-data
      WorkingDirectory=/home/sammy/myproject
      Environment="PATH=/home/sammy/myproject/myprojectenv/bin"
      ExecStart=/home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
      
      [Install]
      WantedBy=multi-user.target
      

      Avec cela, notre fichier de service systemd est terminé. Enregistrez-le et fermez-le maintenant.

      Nous pouvons maintenant démarrer le service Gunicorn que nous avons créé et l’activer afin qu’il démarre au boot :

      • sudo systemctl start myproject
      • sudo systemctl enable myproject

      Vérifions l’état :

      • sudo systemctl status myproject

      Vous devriez voir une sortie comme celle-ci :

      Output

      ● myproject.service - Gunicorn instance to serve myproject Loaded: loaded (/etc/systemd/system/myproject.service; enabled; vendor preset: enabled) Active: active (running) since Wed 2020-05-20 14:15:18 UTC; 1s ago Main PID: 46430 (gunicorn) Tasks: 4 (limit: 2344) Memory: 51.3M CGroup: /system.slice/myproject.service ├─46430 /home/sammy/myproject/myprojectenv/bin/python3 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app ├─46449 /home/sammy/myproject/myprojectenv/bin/python3 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app ├─46450 /home/sammy/myproject/myprojectenv/bin/python3 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app └─46451 /home/sammy/myproject/myprojectenv/bin/python3 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app

      Si vous constatez des erreurs, veillez à les résoudre avant de poursuivre le tutoriel.

      Étape 5 — Configuration de Nginx pour les demandes de proxy

      Notre serveur d’application Gunicorn devrait maintenant être opérationnel, en attendant les requêtes sur le fichier socket dans le répertoire du projet. Configurons maintenant Nginx pour qu’il transmette les requêtes web à cette socket en effectuant quelques petits ajouts à son fichier de configuration.

      Commencez par créer un nouveau fichier de configuration du bloc serveur dans le répertoire sites-available de Nginx. Appelons cela myproject pour rester en phase avec le reste du guide :

      • sudo nano /etc/nginx/sites-available/myproject

      Ouvrez un bloc serveur et indiquez à Nginx d’écouter sur le port 80 par défaut. Demandons également à Nginx d’utiliser ce bloc pour les demandes de nom de domaine de notre serveur :

      /etc/nginx/sites-available/myproject

      server {
          listen 80;
          server_name your_domain www.your_domain;
      }
      

      Ensuite, ajoutons un bloc de localisation qui corresponde à chaque requête. Dans ce bloc, nous allons inclure le fichier proxy_params qui spécifie certains paramètres généraux de proxy devant être définis. Nous transmettrons ensuite les demandes à la socket que nous avons définie à l’aide de la directive proxy_pass :

      /etc/nginx/sites-available/myproject

      server {
          listen 80;
          server_name your_domain www.your_domain;
      
          location / {
              include proxy_params;
              proxy_pass http://unix:/home/sammy/myproject/myproject.sock;
          }
      }
      

      Enregistrez et fermez le fichier lorsque vous avez terminé.

      Pour activer la configuration du bloc serveur Nginx que vous venez de créer, reliez le fichier au répertoire sites-enabled :

      • sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled

      Avec le fichier dans ce répertoire, vous pouvez tester les erreurs de syntaxe :

      Si cela ne révèle aucun problème, relancez le processus Nginx pour lire la nouvelle configuration :

      • sudo systemctl restart nginx

      Enfin, ajustons à nouveau le pare-feu. Nous n’avons plus besoin d’un accès via le port 5000, nous pouvons donc supprimer cette règle. Nous pouvons alors autoriser l’accès complet au serveur Nginx :

      • sudo ufw delete allow 5000
      • sudo ufw allow 'Nginx Full'

      Vous devriez maintenant être en mesure de naviguer sur le nom de domaine de votre serveur dans votre navigateur web :

      http://your_domain
      

      Vous devriez voir la sortie de votre application :

      Exemple d'application Flask

      Si vous rencontrez des erreurs, essayez de vérifier les points suivants :

      • sudo less /var/log/nginx/error.log : vérifie les journaux d’erreurs de Nginx.
      • sudo less /var/log/nginx/access.log : vérifie les journaux d’accès Nginx.
      • sudo journalctl -u nginx : vérifie les journaux des processus Nginx.
      • sudo journalctl -u myproject : vérifie les journaux Gunicorn de votre application Flask.

      Étape 6 — Sécurisation de l’application

      Pour garantir que le trafic vers votre serveur reste sécurisé, obtenons un certificat SSL pour votre domaine. Il existe plusieurs façons de le faire, notamment en obtenant un certificat gratuit auprès de Let’s Encrypt, en générant un certificat auto-signé ou en en achetant un auprès d’un autre fournisseur et en configurant Nginx pour l’utiliser en suivant les étapes 2 à 6 de Comment créer un certificat SSL auto-signé pour Nginx dans Ubuntu 20.04. Nous allons choisir l’option 1 pour des raisons de commodité.

      Installez le paquet Nginx de Certbot avec apt :

      • sudo apt install python3-certbot-nginx

      Certbot propose différents moyens d’obtenir des certificats SSL par le biais de plugins. Le plugin Nginx se chargera de reconfigurer Nginx et de recharger la configuration chaque fois que nécessaire. Pour utiliser ce plugin, tapez ce qui suit :

      • sudo certbot --nginx -d your_domain -d www.your_domain

      Cela exécute certbot avec le plugin --nginx, en utilisant -d pour spécifier les noms pour lesquels nous aimerions que le certificat soit valide.

      Si vous utilisez certbot pour la première fois, vous serez invité à saisir une adresse électronique et à accepter les conditions régissant le service. Après avoir fait cela, certbot communiquera avec le serveur Let’s Encrypt, puis exécutera un défi pour vérifier que vous contrôlez le domaine pour lequel vous demandez un certificat.

      Si cela réussit, certbot demandera comment vous souhaitez configurer vos paramètres HTTPS :

      Output

      Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access. ------------------------------------------------------------------------------- 1: No redirect - Make no further changes to the webserver configuration. 2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for new sites, or if you're confident your site works on HTTPS. You can undo this change by editing your web server's configuration. ------------------------------------------------------------------------------- Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

      Sélectionnez votre choix ensuite appuyez sur ENTER. La configuration sera mise à jour, et Nginx se rechargera pour récupérer les nouveaux paramètres. certbot terminera par un message vous indiquant que le processus a réussi et où sont stockés vos certificats :

      Output

      IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/your_domain/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/your_domain/privkey.pem Your cert will expire on 2020-08-18. To obtain a new or tweaked version of this certificate in the future, simply run certbot again with the "certonly" option. To non-interactively renew *all* of your certificates, run "certbot renew" - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal. - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le

      Si vous avez suivi les instructions d’installation Nginx dans les conditions préalables, vous n’aurez plus besoin de l’autorisation de profil HTTP redondant :

      • sudo ufw delete allow 'Nginx HTTP'

      Pour vérifier la configuration, naviguez à nouveau sur votre domaine, en utilisant https:// :

      https://your_domain
      

      Vous devriez voir à nouveau la sortie de votre application, ainsi que l’indicateur de sécurité de votre navigateur, qui devrait indiquer que le site est sécurisé.

      Conclusion

      Dans ce guide, vous avez créé et sécurisé une application Flask simple dans un environnement virtuel Python. Vous avez créé un point d’entrée WSGI afin que tout serveur d’application compatible WSGI puisse s’interfacer avec lui, puis vous avez configuré le serveur d’application Gunicorn pour qu’il assure cette fonction. Ensuite, vous avez créé un fichier de service systemd pour lancer automatiquement le serveur de l’application au démarrage. Vous avez également créé un bloc serveur Nginx qui transmet le trafic du client web au serveur d’applications, relayant les requêtes externes, et qui sécurise le trafic vers votre serveur avec Let’s Encrypt.

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



      Source link

      Como servir aplicativos Flask com o Gunicorn e o Nginx no Ubuntu 20.04


      Introdução

      Neste guia, você construirá um aplicativo Python usando o microframework Flask no Ubuntu 20.04. A maior parte deste artigo será sobre como configurar o servidor do aplicativo Gunicorn, como iniciar o aplicativo e configurar o Nginx para atuar como um proxy reverso no front-end.

      Pré-requisitos

      Antes de iniciar este guia, você deve ter:

      • Um servidor com o Ubuntu 20.04 instalado e um usuário não root com privilégios sudo. Siga nosso guia de configuração inicial do servidor para orientação.
      • O Nginx instalado, seguindo os Passos 1 e 2 de Como instalar o Nginx no Ubuntu 20.04.
      • Um nome de domínio configurado para apontar para o seu servidor. Você pode comprar um no Namecheap ou obter um de graça no Freenom. Você pode aprender como apontar domínios para o DigitalOcean seguindo a relevante documentação para domínios e DNS. Certifique-se de criar os seguintes registros DNS:

        • Um registro A com your_domain apontando para o endereço IP público do seu servidor.
        • Um registro A com o www.your_domain apontando para o endereço de IP público do seu servidor.
      • Familiarize-se com a especificação do WSGI, que o servidor do Gunicorn usará para se comunicar com seu aplicativo Flask. Esta discussão aborda mais detalhadamente o WSGI.

      Passo 1 — Instalando os componentes dos repositórios do Ubuntu

      Nosso primeiro passo será instalar todas as partes que precisamos dos repositórios do Ubuntu. Isso inclui o pip, o gerenciador de pacotes Python que irá gerenciar nossos componentes Python. Também vamos obter os arquivos de desenvolvimento do Python necessários para construir alguns dos componentes do Gunicorn.

      Primeiramente, vamos atualizar o índice local de pacotes e instalar os pacotes que irão nos permitir construir nosso ambiente Python. Estes incluem o python3-pip, junto com alguns outros pacotes e ferramentas de desenvolvimento necessários para um ambiente de programação robusto:

      • sudo apt update
      • sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools

      Com esses pacotes instalados, vamos seguir em frente para criar um ambiente virtual para nosso projeto.

      Passo 2 — Criando um Ambiente Virtual em Python

      Em seguida, vamos configurar um ambiente virtual para isolar nosso aplicativo Flask dos outros arquivos Python no sistema.

      Inicie instalando o pacote python3-venv, que instalará o módulo venv:

      • sudo apt install python3-venv

      Em seguida, vamos fazer um diretório pai para nosso projeto Flask. Acesse o diretório após criá-lo:

      • mkdir ~/myproject
      • cd ~/myproject

      Crie um ambiente virtual para armazenar os requisitos Python do projeto Flask digitando:

      • python3 -m venv myprojectenv

      Isso instalará uma cópia local do Python e do pip em um diretório chamado myprojectenv dentro do diretório do seu projeto.

      Antes de instalar aplicativos no ambiente virtual, você precisa ativá-lo. Faça isso digitando:

      • source myprojectenv/bin/activate

      Seu prompt mudará para indicar que você agora está operando no ambiente virtual. Ele se parecerá com isso: (myprojectenv)user@host:~/myproject$.

      Passo 3 — Configurando um aplicativo Flask

      Agora que você está no seu ambiente virtual, instale o Flask e o Gunicorn e comece a projetar seu aplicativo.

      Primeiramente, vamos instalar o wheel com a instância local do pip para garantir que nossos pacotes sejam instalados mesmo se estiverem faltando arquivos wheel:

      Nota


      Independentemente da versão do Python que você estiver usando, quando o ambiente virtual for ativado, você deve usar o comando pip (não o pip3).

      Em seguida, vamos instalar o Flask e o Gunicorn:

      • pip install gunicorn flask

      Criando um app de exemplo

      Agora que você tem o Flask disponível, você pode criar um aplicativo simples. O Flask é um microframework. Ele não inclui muitas das ferramentas que os frameworks mais completos talvez tenham. Ele existe, principalmente, como um módulo que você pode importar para seus projetos para ajudá-lo na inicialização de um aplicativo Web.

      Embora o seu aplicativo possa ser mais complexo, vamos criar nosso app Flask em um único arquivo, chamado myproject.py:

      • nano ~/myproject/myproject.py

      O código do aplicativo ficará neste arquivo. Ele importará o Flask e instanciará um objeto Flask. Você pode usar isto para definir as funções que devem ser executadas quando uma rota específica for solicitada:

      ~/myproject/myproject.py

      from flask import Flask
      app = Flask(__name__)
      
      @app.route("/")
      def hello():
          return "<h1 style="color:blue">Hello There!</h1>"
      
      if __name__ == "__main__":
          app.run(host="0.0.0.0")
      

      Isso define basicamente qual conteúdo apresentar quando o domínio raiz for acessado. Salve e feche o arquivo quando você terminar.

      Se você seguiu o guia de configuração inicial do servidor, você deverá ter um firewall UFW ativado. Para testar o aplicativo, será necessário permitir o acesso à porta 5000:

      Agora é possível testar seu app Flask digitando:

      Você verá um resultado como o seguinte, incluindo um aviso útil lembrando para não usar essa configuração de servidor na produção:

      Output

      * Serving Flask app "myproject" (lazy loading) * Environment: production WARNING: Do not use the development server in a production environment. Use a production WSGI server instead. * Debug mode: off * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

      Visite o endereço IP do seu servidor seguido de :5000 no seu navegador Web:

      http://your_server_ip:5000
      

      Você deve ver algo como isto:

      Flask sample app

      Quando terminar, tecle CTRL-C na janela do seu terminal para parar o servidor de desenvolvimento Flask.

      Criando o ponto de entrada da WSGI

      Em seguida, vamos criar um arquivo que servirá como o ponto de entrada para nosso aplicativo. Isso dirá ao nosso servidor do Gunicorn como interagir com o aplicativo.

      Vamos chamar o arquivo de wsgi.py:

      Neste arquivo, vamos importar a instância Flask do nosso aplicativo e então executá-lo:

      ~/myproject/wsgi.py

      from myproject import app
      
      if __name__ == "__main__":
          app.run()
      

      Salve e feche o arquivo quando você terminar.

      Passo 4 — Configurando o Gunicorn

      Seu aplicativo agora está gravado com um ponto de entrada estabelecido. Podemos agora seguir em frente para configurar o Gunicorn.

      Antes de continuar, devemos verificar se o Gunicorn pode atender o aplicativo corretamente.

      Podemos fazer essa verificação simplesmente passando o nome do nosso ponto de entrada para o Gunicorn. Criamos esse ponto de entrada como o nome do módulo (menos a extensão .py) mais o nome do objeto callable dentro do aplicativo. No nosso caso, trata-se do wsgi:app.

      Também vamos especificar a interface e a porta a vincular, de modo que o aplicativo seja iniciado em uma interface disponível publicamente:

      • cd ~/myproject
      • gunicorn --bind 0.0.0.0:5000 wsgi:app

      Deverá ver um resultado como o seguinte:

      Output

      [2020-05-20 14:13:00 +0000] [46419] [INFO] Starting gunicorn 20.0.4 [2020-05-20 14:13:00 +0000] [46419] [INFO] Listening at: http://0.0.0.0:5000 (46419) [2020-05-20 14:13:00 +0000] [46419] [INFO] Using worker: sync [2020-05-20 14:13:00 +0000] [46421] [INFO] Booting worker with pid: 46421

      Visite o endereço IP do seu servidor com :5000 anexado ao final no seu navegador Web novamente:

      http://your_server_ip:5000
      

      Você deve ver o resultado do seu aplicativo:

      Flask sample app

      Quando você tiver confirmado que ele está funcionando corretamente, pressione CTRL-C na janela do seu terminal.

      Acabamos agora o nosso ambiente virtual, para que possamos desativá-lo:

      Agora, qualquer comando Python voltará a usar o ambiente do sistema Python.

      Em seguida, vamos criar o arquivo da unidade de serviço systemd. Criar um arquivo de unidade systemd permitirá que o sistema init do Ubuntu inicie automaticamente o Gunicorn e atenda o aplicativo Flask sempre que o servidor inicializar.

      Crie um arquivo de unidade que termine com .service dentro do diretório /etc/systemd/system para começar:

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

      Ali, vamos começar com a seção [Unit], que é usada para especificar os metadados e dependências. Vamos colocar uma descrição do nosso serviço aqui e dizer ao sistema init para iniciar isso somente após o objetivo da rede ter sido alcançado:

      /etc/systemd/system/myproject.service

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

      Em seguida, vamos abrir a seção [Service]. Isso especificará o usuário e o grupo sob o qual que queremos que o processo seja executado. Vamos dar à nossa conta de usuário regular a propriedade sobre o processo, uma vez que ela possui todos os arquivos relevantes. Vamos também dar a propriedade sobre o grupo para o grupo www-data, de modo que o Nginx possa se comunicar facilmente com os processos do Gunicorn. Lembre-se de substituir o nome de usuário abaixo pelo seu nome de usuário:

      /etc/systemd/system/myproject.service

      [Unit]
      Description=Gunicorn instance to serve myproject
      After=network.target
      
      [Service]
      User=sammy
      Group=www-data
      

      Em seguida, vamos mapear o diretório de trabalho e definir a variável de ambiente PATH para que o sistema init saiba que os executáveis do processo estão localizados dentro do nosso ambiente virtual. Vamos também especificar o comando para iniciar o serviço. Este comando fará o seguinte:

      • Iniciar três processos de trabalho (embora deva ajustar isso conforme necessário)
      • Criar e vincular a um arquivo de socket Unix, myproject.sock, dentro de nosso diretório de projeto. Vamos definir um valor de umask de 007 para que o arquivo socket seja criado dando acesso ao proprietário e ao grupo, ao mesmo tempo que restringe outros acessos
      • Especificar o nome do arquivo de ponto de entrada da WSGI, junto com o objeto callable do Python dentro daquele arquivo (wsgi:app)

      O systemd exige que seja dado o caminho completo para o executável do Gunicorn, que está instalado dentro do nosso ambiente virtual.

      Lembre-se de substituir o nome de usuário e os caminhos do projeto por seus próprios dados:

      /etc/systemd/system/myproject.service

      [Unit]
      Description=Gunicorn instance to serve myproject
      After=network.target
      
      [Service]
      User=sammy
      Group=www-data
      WorkingDirectory=/home/sammy/myproject
      Environment="PATH=/home/sammy/myproject/myprojectenv/bin"
      ExecStart=/home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
      

      Finalmente, vamos adicionar uma seção [Install]. Isso dirá ao systemd ao que vincular este serviço se nós o habilitarmos para iniciar na inicialização. Queremos que este serviço comece quando o sistema regular de vários usuários estiver funcionando:

      /etc/systemd/system/myproject.service

      [Unit]
      Description=Gunicorn instance to serve myproject
      After=network.target
      
      [Service]
      User=sammy
      Group=www-data
      WorkingDirectory=/home/sammy/myproject
      Environment="PATH=/home/sammy/myproject/myprojectenv/bin"
      ExecStart=/home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
      
      [Install]
      WantedBy=multi-user.target
      

      Com isso, nosso arquivo de serviço systemd está completo. Salve e feche-o agora.

      Podemos agora iniciar o serviço Gunicorn que criamos e habilitá-lo para que ele seja iniciado na inicialização:

      • sudo systemctl start myproject
      • sudo systemctl enable myproject

      Vamos verificar o status:

      • sudo systemctl status myproject

      Você deve ver um resultado como este:

      Output

      ● myproject.service - Gunicorn instance to serve myproject Loaded: loaded (/etc/systemd/system/myproject.service; enabled; vendor preset: enabled) Active: active (running) since Wed 2020-05-20 14:15:18 UTC; 1s ago Main PID: 46430 (gunicorn) Tasks: 4 (limit: 2344) Memory: 51.3M CGroup: /system.slice/myproject.service ├─46430 /home/sammy/myproject/myprojectenv/bin/python3 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app ├─46449 /home/sammy/myproject/myprojectenv/bin/python3 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app ├─46450 /home/sammy/myproject/myprojectenv/bin/python3 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app └─46451 /home/sammy/myproject/myprojectenv/bin/python3 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app

      Se encontrar erros, certifique-se de resolvê-los antes de continuar com o tutorial.

      Passo 5 — Configurando o Nginx para solicitações de proxy

      Nosso servidor do aplicativo Gunicorn deve estar funcionando agora, esperando pedidos no arquivo de socket no diretório do projeto. Vamos agora configurar o Nginx para passar pedidos Web para aquele socket, fazendo algumas pequenas adições ao seu arquivo de configuração.

      Comece criando um novo arquivo de configuração do bloco do servidor no diretório sites-available do Nginx. Vamos chamá-lo de myproject para mantê-lo alinhado com o resto do guia:

      • sudo nano /etc/nginx/sites-available/myproject

      Abra um bloco de servidor e diga ao Nginx para escutar na porta padrão 80. Vamos também dizer a ele para usar este bloco para pedidos para o nome de domínio do nosso servidor:

      /etc/nginx/sites-available/myproject

      server {
          listen 80;
          server_name your_domain www.your_domain;
      }
      

      Em seguida, vamos adicionar um bloco de localização que corresponda a cada pedido. Dentro deste bloco, vamos incluir o arquivo proxy_params que especifica alguns parâmetros gerais de proxy que precisam ser configurados. Vamos então passar os pedidos para o socket que definimos usando a diretriz proxy_pass:

      /etc/nginx/sites-available/myproject

      server {
          listen 80;
          server_name your_domain www.your_domain;
      
          location / {
              include proxy_params;
              proxy_pass http://unix:/home/sammy/myproject/myproject.sock;
          }
      }
      

      Salve e feche o arquivo quando terminar.

      Para habilitar a configuração do bloco do servidor Nginx que acabou de criar, vincule o arquivo ao diretório sites-enabled:

      • sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled

      Com o arquivo naquele diretório, você pode testar quanto a erros de sintaxe:

      Se retornar sem indicar quaisquer problemas, reinicie o processo Nginx para ler a nova configuração:

      • sudo systemctl restart nginx

      Finalmente, vamos ajustar o firewall novamente. Já não precisamos de acesso através da porta 5000, então podemos remover essa regra. Podemos então conceder acesso total ao servidor Nginx:

      • sudo ufw delete allow 5000
      • sudo ufw allow 'Nginx Full'

      Agora, você consegue navegar até o nome de domínio do seu servidor no seu navegador Web:

      http://your_domain
      

      Você deve ver o resultado do seu aplicativo:

      Flask sample app

      Caso encontre quaisquer erros, tente verificar o seguinte:

      • sudo less /var/log/nginx/error.log: verifica os registros de erros do Nginx.
      • sudo less /var/log/nginx/access.log: verifica os registros de acesso do Nginx.
      • sudo journalctl -u nginx: verifica os registros de processo do Nginx.
      • sudo journalctl -u myproject: verifica os registros do Gunicorn do seu app Flask.

      Passo 6 — Protegendo o aplicativo

      Para garantir que o tráfego para seu servidor permaneça protegido, vamos obter um certificado SSL para seu domínio. Há várias maneiras de fazer isso, incluindo a obtenção de um certificado gratuito do Let’s Encrypt, gerando um certificado autoassinado ou comprando algum de outro provedor e configurando o Nginx para usá-lo, seguindo os Passos 2 a 6 de Como criar um certificado SSL autoassinado para o Nginx no Ubuntu 20.04. Vamos escolher a opção um por questão de conveniência.

      Instale o pacote Nginx do Certbot com o apt:

      • sudo apt install python3-certbot-nginx

      O Certbot oferece várias maneiras de obter certificados SSL através de plug-ins. O plug-in Nginx cuidará da reconfiguração do Nginx e recarregará a configuração sempre que necessário. Para usar este plug-in, digite o seguinte:

      • sudo certbot --nginx -d your_domain -d www.your_domain

      Esse comando executa o certbot com o plug-in --nginx, usando -d para especificar os nomes para os quais desejamos um certificado válido.

      Se essa é a primeira vez que você executa o certbot, você será solicitado a informar um endereço de e-mail e concordar com os termos de serviço. Após fazer isso, o certbot se comunicará com o servidor da Let’s Encrypt, executando posteriormente um desafio para verificar se você controla o domínio para o qual está solicitando um certificado.

      Se tudo correr bem, o certbot perguntará como você quer definir suas configurações de HTTPS:

      Output

      Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access. ------------------------------------------------------------------------------- 1: No redirect - Make no further changes to the webserver configuration. 2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for new sites, or if you're confident your site works on HTTPS. You can undo this change by editing your web server's configuration. ------------------------------------------------------------------------------- Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

      Select your choice then hit ​​​ENTER​​​​​. A configuração será atualizada e o Nginx recarregará para aplicar as novas configurações. O certbot será encerrado com uma mensagem informando que o processo foi concluído e onde os certificados estão armazenados:

      Output

      IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/your_domain/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/your_domain/privkey.pem Your cert will expire on 2020-08-18. To obtain a new or tweaked version of this certificate in the future, simply run certbot again with the "certonly" option. To non-interactively renew *all* of your certificates, run "certbot renew" - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal. - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le

      Se seguiu as instruções de instalação do Nginx nos pré-requisitos, a permissão do perfil HTTP redundante não é mais necessária:

      • sudo ufw delete allow 'Nginx HTTP'

      Para verificar a configuração, navegue novamente para seu domínio, usando https://:

      https://your_domain
      

      Você deve ver novamente o resultado do seu aplicativo, junto com o indicador de segurança do seu navegador, o qual deve indicar que o site está protegido.

      Conclusão

      Neste guia, você criou e protegeu um aplicativo Flask simples em um ambiente virtual Python. Você criou um ponto de entrada da WSGI para que qualquer servidor de aplicativo compatível com a WSGI possa interagir com ela, e então configurou o servidor de app Gunicorn para fornecer essa função. Depois, criou um arquivo de serviço systemd para iniciar automaticamente o servidor do aplicativo na inicialização. Você também criou um bloco de servidor Nginx que passa o tráfego Web do cliente para o servidor do aplicativo – retransmitindo pedidos externos – e protegeu o tráfego para seu servidor com o Let’s Encrypt.

      O Flask é um framework muito simples – mas extremamente flexível, destinado a fornecer funcionalidade a seus aplicativos sem ser restritivo demais em termos de estrutura e design. Você pode usar a pilha geral descrita neste guia para atender os aplicativos flask que projetar.



      Source link

      Обслуживание приложений Flask с Gunicorn и Nginx в Ubuntu 20.04


      Введение

      В этом обучающем модуле вы создадите приложение Python с использованием микроструктуры Flask в Ubuntu 20.04. Основная часть этой статьи посвящена настройке сервера приложений Gunicorn, запуску приложения и настройке Nginx для работы в режиме обратного прокси-сервера фронтенда.

      Предварительные требования

      Перед началом прохождения этого обучающего модуля вам потребуется следующее:

      • Сервер с установленной операционной системой Ubuntu 20.04 и пользователь без привилегий root и с привилегиями sudo. Следуйте указаниям нашего руководства по начальной настройке сервера.
      • Веб-сервер Nginx, установленный в соответствии с шагами 1 и 2 модуля Установка Nginx в Ubuntu 20.04.
      • Доменное имя, настроенное так, чтобы указывать на ваш сервер. Вы можете приобрести его на Namecheap или получить бесплатно на Freenom. Вы можете узнать, как указывать домены на DigitalOcean, из соответствующей документации по доменам и DNS. Обязательно создайте следующие записи DNS:

        • Запись A, где your_domain указывает на публичный IP-адрес вашего сервера.
        • Запись A, где www.your_domain указывает на публичный IP-адрес вашего сервера.
      • Знакомство со спецификацией WSGI, которую сервер Gunicorn будет использовать для взаимодействия с вашими приложениями Flask. В этом обсуждении более подробно рассказывается о WSGI.

      Шаг 1 — Установка компонентов из хранилищ Ubuntu

      Первым шагом будет установка всех необходимых нам элементов из хранилищ Ubuntu. Она включает установку pip, диспетчера пакетов Python, который будет управлять нашими компонентами Python. Также мы получим файлы разработки Python, необходимые для создания некоторых компонентов Gunicorn.

      Вначале обновим локальный индекс пакетов и установим пакеты, которые позволят нам создать нашу среду Python. Мы установим пакет python3-pip, а также еще несколько пакетов и средств разработки, необходимых для создания надежной среды программирования:

      • sudo apt update
      • sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools

      С этими пакетами мы перейдем к созданию виртуальной среды для нашего проекта.

      Шаг 2 — Создание виртуальной среды Python

      Теперь мы настроим виртуальную среду, чтобы изолировать наше приложение Flask от других файлов Python в системе.

      Для начала установим пакет python3-vevv, который установит модуль venv:

      • sudo apt install python3-venv

      Затем создадим родительский каталог для нашего проекта Flask. Перейдите в каталог после его создания:

      • mkdir ~/myproject
      • cd ~/myproject

      Создайте виртуальную среду для хранения требований Python для вашего проекта Flask, введя следующую команду:

      • python3 -m venv myprojectenv

      Локальные копии Python и pip будут установлены в каталог myprojectenv в каталоге вашего проекта.

      Прежде чем устанавливать приложения в виртуальной среде, ее нужно активировать. Для этого нужно ввести следующую команду:

      • source myprojectenv/bin/activate

      Командная строка изменится, показывая, что теперь вы работаете в виртуальной среде. Она будет выглядеть примерно так: (myprojectenv)user@host:~/myproject$.

      Шаг 3 — Настройка приложения Flask

      Находясь в виртуальной среде, вы можете установить Flask и Gunicorn и начать работу над созданием вашего приложения.

      Вначале мы установим wheel с локальным экземпляром pip, чтобы убедиться, что наши пакеты будут устанавливаться даже при отсутствии архивов wheel:

      Примечание


      Если виртуальная среда активна, то вне зависимости от того, какую версию Python вы используете, вы должны использовать команду pip (а не pip3).

      Затем установим Flask и Gunicorn:

      • pip install gunicorn flask

      Создание образца приложения

      Теперь вы можете использовать Flask для создания простого приложения. Flask представляет собой микроструктуру. В ней отсутствуют многие инструменты, входящие в полноценные инфраструктуры программирования, и она существует в основном в виде модуля, который вы можете импортировать в проекты для инициализации веб-приложения.

      Хотя ваше приложение может быть более сложным, мы создадим наше приложение Flask в одном файле с именем myproject.py:

      • nano ~/myproject/myproject.py

      Код приложения будет находиться в этом файле. Он импортирует Flask и создаст экземпляр объекта Flask. Вы можете использовать его для определения функций, которые запускаться при запросе конкретного маршрута:

      ~/myproject/myproject.py

      from flask import Flask
      app = Flask(__name__)
      
      @app.route("/")
      def hello():
          return "<h1 style="color:blue">Hello There!</h1>"
      
      if __name__ == "__main__":
          app.run(host="0.0.0.0")
      

      Здесь определяется, какой контент должен выводиться при доступе к корневому домену. Сохраните файл и закройте его после завершения.

      Если вы следовали указаниям модуля по начальной настройке сервера, у вас должен быть включен брандмауэр UFW. Чтобы протестировать приложение, вам нужно разрешить доступ к порту 5000:

      Теперь вы можете протестировать приложение Flask с помощью следующей команды:

      Вы увидите следующий результат, в том числе полезное предупреждение, напоминающее не использовать эти настройки сервера в реальной работе:

      Output

      * Serving Flask app "myproject" (lazy loading) * Environment: production WARNING: Do not use the development server in a production environment. Use a production WSGI server instead. * Debug mode: off * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

      Откройте в браузере IP-адрес вашего сервера с суффиксом :5000:

      http://your_server_ip:5000
      

      Вы увидите примерно следующее:

      Образец приложения Flask

      Когда вы закончите, нажмите CTRL+C в окне терминала, чтобы остановить сервер разработки Flask.

      Создание точки входа WSGI

      Теперь создадим файл, который будет служить точкой входа в наше приложение. Это покажет серверу Gunicorn, как взаимодействовать с приложением.

      Мы назовем этот файл wsgi.py:

      Сейчас мы импортируем экземпляр Flask из нашего приложения в этот файл и запустим его:

      ~/myproject/wsgi.py

      from myproject import app
      
      if __name__ == "__main__":
          app.run()
      

      Сохраните файл и закройте его после завершения.

      Шаг 4 — Настройка Gunicorn

      Ваше приложение написано, и для него создана точка входа. Теперь мы можем перейти к настройке Gunicorn.

      Прежде чем продолжить, нужно убедиться, что Gunicorn может правильно обслуживать приложение.

      Для этого нужно просто передать имя нашей точки входа. Оно составляется из имени модуля (без расширения .py) и имени вызываемого элемента приложения. В нашем случае это wsgi:app.

      Также мы укажем интерфейс и порт для привязки, чтобы приложение запускалось через общедоступный интерфейс:

      • cd ~/myproject
      • gunicorn --bind 0.0.0.0:5000 wsgi:app

      Результат будет выглядеть следующим образом:

      Output

      [2020-05-20 14:13:00 +0000] [46419] [INFO] Starting gunicorn 20.0.4 [2020-05-20 14:13:00 +0000] [46419] [INFO] Listening at: http://0.0.0.0:5000 (46419) [2020-05-20 14:13:00 +0000] [46419] [INFO] Using worker: sync [2020-05-20 14:13:00 +0000] [46421] [INFO] Booting worker with pid: 46421

      Откройте в браузере IP-адрес вашего сервера с суффиксом :5000.

      http://your_server_ip:5000
      

      Вы увидите результат выполнения вашего приложения:

      Образец приложения Flask

      Убедившись в его нормальной работе, нажмите CTRL+C в окне терминала.

      Мы закончили работу с виртуальной средой, и теперь можем отключить ее:

      Теперь любые команды Python снова будут использовать системную среду Python.

      Далее мы созадим файл служебных элементов systemd. Создание файла элементов systemd позволит системе инициализации Ubuntu автоматически запускать Gunicorn и обслуживать приложение Flask при загрузке сервера.

      Для начала создайте файл элементов с расширением .service в каталоге /etc/systemd/system:

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

      Мы начнем с раздела [Unit] этого файла, где указываются метаданные и зависимости. Здесь мы разместим описание службы и предпишем системе инициализации запускать ее только после достижения сетевой цели:

      /etc/systemd/system/myproject.service

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

      Теперь откроем раздел [Service]. Здесь указывается пользователь и группа, от имени которых мы хотим запустить данный процесс. Сделаем владельцем процесса учетную запись обычного пользователя, поскольку этот пользователь является владельцем всех соответствующих файлов. Также назначим владельцем группу www-data, чтобы упростить коммуникацию Nginx с процессом Gunicorn. Не забудьте заменить приведенное имя пользователя своим именем пользователя:

      /etc/systemd/system/myproject.service

      [Unit]
      Description=Gunicorn instance to serve myproject
      After=network.target
      
      [Service]
      User=sammy
      Group=www-data
      

      Теперь составим карту рабочего каталога и зададим переменную среды PATH, чтобы система инициализации знала, что исполняемые файлы этого процесса находятся в нашей виртуальной среде. Также укажем команду для запуска службы. Эта команда будет выполнять следующее:

      • Запуск 3 рабочих процессов (хотя вы можете изменить это при необходимости)
      • Создание и привязвка к файлу сокетов Unix myproject.sock в каталоге нашего проекта. Мы зададим значение umask 007, чтобы при создании файла сокета предоставлялся доступ для владельца и для группы, а любой другой доступ ограничивался
      • Укажите имя файла точки входа WSGI, а также вызываемый элемент Python в этом файле (wsgi:app)

      Systemd требует, чтобы мы указывали полный путь исполняемого файла Gunicorn, установленного в нашей виртуальной среде.

      Не забудьте заменить имя пользователя и пути проекта собственными данными:

      /etc/systemd/system/myproject.service

      [Unit]
      Description=Gunicorn instance to serve myproject
      After=network.target
      
      [Service]
      User=sammy
      Group=www-data
      WorkingDirectory=/home/sammy/myproject
      Environment="PATH=/home/sammy/myproject/myprojectenv/bin"
      ExecStart=/home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
      

      Наконец, добавим раздел [Install]. Это покажет systemd, куда привязывать эту службу, если мы активируем ее запуск при загрузке. Нам нужно, чтобы эта служба запускалась во время работы обычной многопользовательской системы:

      /etc/systemd/system/myproject.service

      [Unit]
      Description=Gunicorn instance to serve myproject
      After=network.target
      
      [Service]
      User=sammy
      Group=www-data
      WorkingDirectory=/home/sammy/myproject
      Environment="PATH=/home/sammy/myproject/myprojectenv/bin"
      ExecStart=/home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
      
      [Install]
      WantedBy=multi-user.target
      

      Теперь служебный файл systemd готов. Сохраните и закройте его.

      Теперь мы запустим созданную службу Gunicorn и активируем ее запуск при загрузке системы:

      • sudo systemctl start myproject
      • sudo systemctl enable myproject

      Теперь проверим состояние:

      • sudo systemctl status myproject

      Результат должен выглядеть следующим образом:

      Output

      ● myproject.service - Gunicorn instance to serve myproject Loaded: loaded (/etc/systemd/system/myproject.service; enabled; vendor preset: enabled) Active: active (running) since Wed 2020-05-20 14:15:18 UTC; 1s ago Main PID: 46430 (gunicorn) Tasks: 4 (limit: 2344) Memory: 51.3M CGroup: /system.slice/myproject.service ├─46430 /home/sammy/myproject/myprojectenv/bin/python3 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app ├─46449 /home/sammy/myproject/myprojectenv/bin/python3 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app ├─46450 /home/sammy/myproject/myprojectenv/bin/python3 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app └─46451 /home/sammy/myproject/myprojectenv/bin/python3 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app

      Если вы увидите какие-либо ошибки, устраните их, прежде чем продолжить выполнение этого обучающего модуля.

      Шаг 5 — Настройка Nginx для работы с запросами прокси-сервера

      Сервер приложений Gunicorn должен быть запущен и ожидать запросы файла сокета в каталоге проекта. Теперь мы настроим Nginx для передачи веб-запросов на этот сокет. Для этого мы сделаем небольшие добавления в его файл конфигурации.

      Вначале мы создадим новый файл конфигурации серверных блоков в каталоге Nginx sites-available. Назовем его myproject для соответствия остальным именам в этом модуле:

      • sudo nano /etc/nginx/sites-available/myproject

      Откройте серверный блок и укажите Nginx прослушивать порт по умолчанию 80. Также укажите использовать этот блок для запросов доменного имени нашего сервера:

      /etc/nginx/sites-available/myproject

      server {
          listen 80;
          server_name your_domain www.your_domain;
      }
      

      Затем добавим блок расположения, соответствующий каждому запросу. В этот блок мы добавим файл proxy_params, определяющий некоторые общие параметры прокси, которые необходимо настроить. После этого запросы будут переданы на сокет, который мы определили с помощью директивы proxy_pass:

      /etc/nginx/sites-available/myproject

      server {
          listen 80;
          server_name your_domain www.your_domain;
      
          location / {
              include proxy_params;
              proxy_pass http://unix:/home/sammy/myproject/myproject.sock;
          }
      }
      

      Сохраните файл и закройте его после завершения.

      Чтобы активировать созданную конфигурацию серверных блоков Nginx, необходимо привязать файл к каталогу sites-enabled:

      • sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled

      Когда файл будет находиться в этом каталоге, можно провести проверку на ошибки синтаксиса:

      Если ошибок обнаружено не будет, перезапустите процесс Nginx для чтения новой конфигурации:

      • sudo systemctl restart nginx

      В заключение снова изменим настройки брандмауэра. Нам больше не потребуется доступ через порт 5000, и мы можем удалить это правило. Затем мы сможем разрешить полный доступ к серверу Nginx:

      • sudo ufw delete allow 5000
      • sudo ufw allow 'Nginx Full'

      Теперь у вас должна быть возможность открыть доменное имя вашего сервера в браузере:

      http://your_domain
      

      Вы увидите результат выполнения вашего приложения:

      Образец приложения Flask

      Если будут обнаружены любые ошибки, проверьте следующее:

      • sudo less /var/log/nginx/error.log: проверяет журналы ошибок Nginx.
      • sudo less /var/log/nginx/access.log: проверяет журналы доступа Nginx.
      • sudo journalctl -u nginx: проверяет журналы процессов Nginx.
      • sudo journalctl -u myproject: проверяет журналы Gunicorn вашего приложения Flask.

      Шаг 6 — Защита приложения

      Чтобы обеспечить защиту трафика вашего сервера, необходимо получить сертификат SSL для вашего домена. Этого можно добиться несколькими способами, в том числе получить бесплатный сертификат от Let’s Encrypt, сгенерировать сертификат с собственной подписью или приобрести сертификат у другого поставщика и настроить Nginx для его использования, для чего потребуется выполнить шаги с 2 по 6 обучающего модуля Создание сертификата SSL с собственной подписью для Nginx в Ubuntu 20.04. Для удобства мы выберем первый вариант.

      Установите пакет Certbot Nginx с apt:

      • sudo apt install python3-certbot-nginx

      Certbot предоставляет широкий выбор способов получения сертификатов SSL с помощью плагинов: Плагин Nginx изменит конфигурацию Nginx и перезагрузит ее, когда это потребуется. Для использования этого плагина введите следующую команду:

      • sudo certbot --nginx -d your_domain -d www.your_domain

      Эта команда запускает certbot с плагином --nginx, используя опцию -d для указания имен, для которых должен действовать сертификат.

      Если это первый запуск certbot, вам будет предложено указать адрес эл. почты и принять условия обслуживания. После этого certbot свяжется с сервером Let’s Encrypt и отправит запрос с целью подтвердить, что вы контролируете домен, для которого запрашиваете сертификат.

      Если это будет подтверждено, certbot запросит у вас предпочитаемый вариант настройки HTTPS:

      Output

      Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access. ------------------------------------------------------------------------------- 1: No redirect - Make no further changes to the webserver configuration. 2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for new sites, or if you're confident your site works on HTTPS. You can undo this change by editing your web server's configuration. ------------------------------------------------------------------------------- Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

      Выберите желаемый вариант, после чего нажмите ENTER. Конфигурация будет обновлена, а Nginx перезагрузится для получения новых настроек. Затем certbot завершит работу и выведет сообщение, подтверждающее завершение процесса и указывающее место хранения ваших сертификатов:

      Output

      IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/your_domain/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/your_domain/privkey.pem Your cert will expire on 2020-08-18. To obtain a new or tweaked version of this certificate in the future, simply run certbot again with the "certonly" option. To non-interactively renew *all* of your certificates, run "certbot renew" - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal. - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le

      Если вы следовали инструкциям по установке Nginx из предварительных требований, вам больше не потребуется разрешать профиль HTTP лишний раз:

      • sudo ufw delete allow 'Nginx HTTP'

      Чтобы подтвердить конфигурацию, снова перейдите в свой домен, используя префикс адреса https://:

      https://your_domain
      

      Вы снова должны увидеть результат выполнения приложения, а также значок замка в браузере, подтверждающий, что сайт защищен.

      Заключение

      В этом обучающем модуле вы научились создавать и защищать простое приложение Flask в виртуальной среде Python. Вы создали точку входа WSGI, с которой может взаимодействовать любой сервер приложений с поддержкой WSGI, а затем настроили сервер приложения Gunicorn для обеспечения этой функции. После этого вы создали служебный файл systemd, который автоматически запускает сервер приложений при загрузке. Также вы создали серверный блок Nginx, который передает трафик веб-клиента на сервер приложений, перенаправляет внешние запросы и защищает трафик вашего сервера с помощью сертификата Let’s Encrypt.

      Flask — простая, но очень гибкая инфраструктура приложения, обеспечивающая работу приложений без значительных структурных ограничений. Вы можете использовать описанный в этом обучающем модуле комплекс для обслуживания разрабатываемых вами приложений flask.



      Source link