Recherche…


Utiliser uWSGI pour exécuter une application de flacon

Le serveur werkzeug intégré ne convient certainement pas pour exécuter des serveurs de production. La raison la plus évidente est le fait que le serveur werkzeug est à thread unique et ne peut donc traiter qu’une seule demande à la fois.

Pour cette raison, nous souhaitons utiliser le serveur uWSGI pour servir notre application à la place. Dans cet exemple, nous allons installer uWSGI et exécuter une application de test simple.

Installer uWSGI :

pip install uwsgi

C'est aussi simple que ça. Si vous n'êtes pas sûr de la version de python utilisée par votre pip, il est explicite:

python3 -m pip install uwsgi  # for python3
python2 -m pip install uwsgi  # for python2

Maintenant, créons une application de test simple:

app.py

from flask import Flask
from sys import version

app = Flask(__name__)

@app.route("/")
def index():
    return "Hello uWSGI from python version: <br>" + version

application = app

Dans flask, le nom conventionnel de l'application est app mais uWSGI recherche l' application par défaut. C'est pourquoi nous créons un alias pour notre application dans la dernière ligne.

Il est maintenant temps d'exécuter l'application:

uwsgi --wsgi-file app.py --http :5000

Vous devriez voir le message "Hello uWSGI ..." en pointant votre navigateur sur localhost:5000

Afin de ne pas taper la commande complète à chaque fois, nous allons créer un fichier uwsgi.ini pour stocker cette configuration:

uwsgi.ini

[uwsgi]
http = :9090
wsgi-file = app.py
single-interpreter = true
enable-threads = true
master = true

Les options http et wsgi-file sont les mêmes que dans la commande manuelle. Mais il y a trois autres options:

  • single-interpreter : Il est recommandé de l'activer car cela pourrait interférer avec l'option suivante

  • enable-threads : Cela doit être activé si vous utilisez des threads supplémentaires dans votre application. Nous ne les utilisons pas maintenant, mais maintenant nous n'avons plus à nous en préoccuper.

  • master : le mode master doit être activé pour diverses raisons

Maintenant, nous pouvons exécuter l'application avec cette commande:

uwsgi --ini uwsgi.ini

Installer nginx et le configurer pour uWSGI

Maintenant, nous voulons installer nginx pour servir notre application.

sudo apt-get install nginx  # on debian/ubuntu

Ensuite, nous créons une configuration pour notre site Web

cd /etc/nginx/site-available  # go to the configuration for available sites
# create a file flaskconfig with your favourite editor

flaskconfig

server {
    listen 80;
    server_name localhost;

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

Cela dit à nginx d'écouter sur le port 80 (par défaut pour http) et de servir quelque chose au niveau du chemin racine ( / ). Là, nous demandons à nginx d’agir simplement en tant que proxy et de transmettre chaque requête à un socket appelé flask.sock situé dans /tmp/ .

Activons le site:

cd /etc/nginx/sites-enabled
sudo ln -s ../sites-available/flaskconfig .

Vous souhaiterez peut-être supprimer la configuration par défaut si elle est activée:

# inside /etc/sites-enabled
sudo rm default

Puis redémarrez nginx:

sudo service nginx restart

Pointez votre navigateur sur localhost et vous verrez une erreur: 502 Bad Gateway .

Cela signifie que nginx est opérationnel et que le socket est absent. Alors créons cela.

Retournez dans votre fichier uwsgi.ini et ouvrez-le. Puis ajoutez ces lignes:

socket = /tmp/flask.sock
chmod-socket = 666

La première ligne indique à uwsgi de créer un socket à l'emplacement indiqué. Le socket sera utilisé pour recevoir des demandes et renvoyer les réponses. Dans la dernière ligne, nous permettons aux autres utilisateurs (y compris nginx) de pouvoir lire et écrire depuis cette socket.

Relancez uwsgi avec uwsgi --ini uwsgi.ini . Maintenant, pointez à nouveau votre navigateur vers localhost et vous verrez le message d'accueil "Hello uWSGI".

Notez que vous pouvez toujours voir la réponse sur localhost:5000 car uWSGI sert maintenant l'application via http et le socket. Désactivons donc l'option http dans le fichier ini

http = :5000  # <-- remove this line and restart uwsgi

Maintenant, l'application n'est accessible qu'à partir de nginx (ou en lisant directement cette socket :)).

Activer le streaming depuis flask

Flask a cette fonctionnalité qui vous permet de diffuser des données depuis une vue en utilisant des générateurs.

Changeons le fichier app.py

  • ajouter à from flask import Response
  • ajout from datetime import datetime
  • ajouter from time import sleep
  • créer une nouvelle vue:
@app.route("/time/")
def time():
    def streamer():
        while True:
            yield "<p>{}</p>".format(datetime.now())
            sleep(1)

    return Response(streamer())

Ouvrez maintenant votre navigateur sur localhost/time/ . Le site se chargera pour toujours car nginx attend que la réponse soit complète. Dans ce cas, la réponse ne sera jamais complète car elle enverra la date et l'heure actuelles pour toujours.

Pour éviter que nginx attende, nous devons ajouter une nouvelle ligne à la configuration.

Editez /etc/nginx/sites-available/flaskconfig

server {
    listen 80;
    server_name localhost;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:///tmp/flask.sock;
        uwsgi_buffering off;  # <-- this line is new
    }
}

La ligne uwsgi_buffering off; indique à nginx de ne pas attendre qu'une réponse soit complète.

Redémarrez nginx: sudo service nginx restart et regardez localhost/time/ again.

Maintenant, vous verrez que chaque seconde une nouvelle ligne apparaît.

Configurer le modèle de chaudière Flask Application, uWGSI, Nginx - Configurations de serveur (par défaut, proxy et cache)

Ceci est un portage de configuration provenant du tutoriel de DigitalOcean sur la façon de servir des applications Flask avec uWSGI et Nginx sur Ubuntu 14.04.

et quelques ressources utiles pour les serveurs nginx.

Application en flacon

Ce tutoriel suppose que vous utilisez Ubuntu.

  1. Localisez var/www/ folder.
  2. Créez votre dossier d'application Web mkdir myexample
  3. cd myexample

facultatif Vous souhaiterez peut-être configurer un environnement virtuel pour le déploiement d'applications Web sur le serveur de production.

sudo pip install virtualenv

installer l'environnement virtuel.

virtualenv myexample

configurer l'environnement virtuel pour votre application.

source myprojectenv/bin/activate 

pour activer votre environnement. Ici vous allez installer tous les paquets Python.

fin facultatif mais recommandé

Mettre en place le flacon et la passerelle uWSGI

Installez flask et la passerelle uSWGI:

pip install uwsgi flask

Exemple d'application flask dans myexample.py:

from flask import Flask
application = Flask(__name__)

@application.route("/")
def hello():
    return "<h1>Hello World</h1>"

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

Créer un fichier pour communiquer entre votre application Web et le serveur Web: interface de passerelle [ https://en.wikipedia.org/wiki/Web_Server_Gateway_Interface]

nano wsgi.py

importez ensuite votre module webapp et lancez-le à partir du point d’entrée de la passerelle.

from myexample import application

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

Pour tester uWSGI:

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

Pour configurer uWSGI:

  1. Créez un fichier de configuration .ini

    nano myexample.ini

  2. Configuration de base pour la passerelle uWSGI

# include header for using uwsgi
[uwsgi]
# point it to your python module wsgi.py
module = wsgi
# tell uWSGI to start a master node to serve requests
master = true
# spawn number of processes handling requests
processes = 5
# use a Unix socket to communicate with Nginx. Nginx will pass connections to uWSGI through a socket, instead of using ports. This is preferable because Nginx and uWSGI stays on the same machine.
socket = myexample.sock
# ensure file permission on socket to be readable and writable
chmod-socket = 660
# clean the socket when processes stop
vacuum = true
# use die-on-term to communicate with Ubuntu versions using Upstart initialisations: see:
# http://uwsgi-docs.readthedocs.io/en/latest/Upstart.html?highlight=die%20on%20term
die-on-term = true

facultatif si vous utilisez virtual env Vous pouvez deactivate votre environnement virtuel.

Configuration de Nginx Nous allons utiliser nginx comme:

  1. serveur par défaut pour transmettre la requête au socket, en utilisant le protocole uwsgi
  2. serveur proxy devant le serveur par défaut
  3. serveur de cache pour mettre en cache les requêtes réussies (par exemple, vous pouvez vouloir mettre en cache les requêtes GET si votre application Web)

Recherchez le répertoire sites-available vos sites-available et créez un fichier de configuration pour votre application:

sudo nano /etc/nginx/sites-available/myexample

Ajouter le bloc suivant, dans les commentaires ce qu'il fait:

server {
   

    # setting up default server listening to port 80
    listen 8000 default_server;
    server_name myexample.com; #you can also use your IP 
    
    # specify charset encoding, optional
    charset utf-8;

    # specify root of your folder directory
    root /var/www/myexample;

    # specify locations for your web apps.
    # here using /api endpoint as example
    location /api {
        # include parameters of wsgi.py and pass them to socket
        include uwsgi_params;
        uwsgi_pass unix:/var/www/myexample/myexample.sock;
    }

}

# Here you will specify caching zones that will be used by your virtual server
# Cache will be stored in /tmp/nginx folder
# ensure nginx have permissions to write and read there!
# See also:
# http://nginx.org/en/docs/http/ngx_http_proxy_module.html

proxy_cache_path /tmp/nginx levels=1:2 keys_zone=my_zone:10m inactive=60m;
proxy_cache_key "$scheme$request_method$host$request_uri";

# set up the virtual host!
server {
    listen   80  default_server;
    
    # Now www.example.com will listen to port 80 and pass request to http://example.com
    server_name www.example.com;

    # Why not caching responses

    location /api {
        # set up headers for caching
        add_header X-Proxy-Cache $upstream_cache_status;

        # use zone specified above
        proxy_cache my_zone;
        proxy_cache_use_stale updating;
        proxy_cache_lock on;
        
        # cache all responses ?
        # proxy_cache_valid 30d;

        # better cache only 200 responses :)
        proxy_cache_valid 200 30d;

        # ignore headers to make cache expire
        proxy_ignore_headers X-Accel-Expires Expires Cache-Control;

        # pass requests to default server on port 8000
        proxy_pass http://example.com:8000/api;
    }
}

Enfin, liez le fichier au répertoire sites-enabled avec les sites-enabled . Pour une explication des sites disponibles et activés, voir la réponse: [ http://serverfault.com/a/527644]

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

Vous avez terminé avec nginx. Cependant, vous pourriez vouloir vérifier ce modèle de chaudière très précieux: [ https://github.com/h5bp/server-configs-nginx]

Très utile pour les réglages fins.

Maintenant, testez Nginx:

sudo nginx -t

Lancez Nginx:

sudo service nginx restart

Automatiser Ubuntu pour démarrer uWSGI La dernière chose à faire est de faire qu'Ubuntu lance la passerelle wsgi en communiquant avec votre application, sinon vous devriez le faire manuellement.

  1. Localisez le répertoire des scripts d'initialisation dans Ubuntu et créez un nouveau script:

sudo nano /etc/init/myexample.conf

  1. Ajouter le bloc suivant, commentaires en ligne pour expliquer ce qu'il fait

    # description for the purpose of this script
    description "uWSGI server instance configured to serve myproject"
    
    # Tell to start on system runtime 2, 3, 4, 5. Stop at any other level (0,1,6). 
    # Linux run levels: [http://www.debianadmin.com/debian-and-ubuntu-linux-run-levels.html]
    start on runlevel [2345]
    stop on runlevel [!2345]
    
    # Set up permissions! "User" will be the username of your user account on ubuntu.
    setuid user
    # Allow www-data group to read and write from the socket file. 
    # www-data is normally the group Nginx and your web applications belong to.
    # you may have all web application projects under /var/www/ that belongs to www-data group
    setgid www-data
    
    # tell Ubunutu which environment to use.
    # This is the path of your virtual environment: python will be in this path if you installed virtualenv. Otherwise, use path of your python installation
    env PATH=/var/www/myexample/myexample/bin
    # then tell to Ubuntu to change and locate your web application directory
    chdir /var/www/myexample
    # finally execute initialisation script, that load your web app myexample.py
    exec uwsgi --ini myexample.ini
    
    

Maintenant, vous pouvez activer votre script: sudo start myexample



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow