Flask
Déploiement d'une application Flask à l'aide du serveur Web uWSGI avec Nginx
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 suivanteenable-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.
- Localisez
var/www/
folder. - Créez votre dossier d'application Web
mkdir myexample
-
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:
Créez un fichier de configuration
.ini
nano myexample.ini
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:
- serveur par défaut pour transmettre la requête au socket, en utilisant le protocole uwsgi
- serveur proxy devant le serveur par défaut
- 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.
- Localisez le répertoire des scripts d'initialisation dans Ubuntu et créez un nouveau script:
sudo nano /etc/init/myexample.conf
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