python, flask, https et wsgi howto
- flask
- wsgi
- https
https / certbot
Je vous donne des pistes, à vous de finir.
L’idée, c’est que je veux paramétrer pour la n-ième fois un nouveau nom de domaine via certbot
, et je ne veux pas qu’il touche à la conf de nginx
.
L’idée c’est que :
(1) Je le fais simplement via certbot-auto
puis après,
(2) toutes les autres fois j’utilise « -d
» pour qu’il ne touche pas à la conf, et je le fais à la main, en m’inspirant de la conf que cert-bot
a fait dans le (1)
Donc, pour faire le (1), je demande à certbot
de me créer uniquement le certificat :
./certbot-auto certonly -d monsite.fr
Pour le https
, regardez ici.
Python
Code exemple, qui lit un fichier JSON, lance le serveur et sert le fichier lu en tant que JSON :
import json
from flask import Flask, jsonify
app = Flask(__name__)
with open("mon fichier JSON", 'r') as f:
json_levels_full_description = json.load(f)
@app.route('/')
def index():
return jsonify(json_levels_full_description)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8004)
else:
application = app
Attention : surtout ne faites pas le classique if __name__ == '__main__'
car uwsgi inclut ce fichier, donc ce fichier n’est jamais un __main__
, par contre la configuration au lancement a besoin d’une variable globale nommée application
.
Nginx
Je copie colle la configuration d’un site qui tourne déjà enhttps
, en voici un extrait diminué à mort pour ne pas polluer avec des règles personnelles, regardez bien le texte en gras, c’est le plus important pour faire tourner Nginx en collaboration avec wsgi :
server {
server_name "~(www\.)?monsite\.(com|fr|org|biz|be)$";
index index.html index.htm;
access_log /blah/proxy-access.monsite.log proxylog;
error_log /blah/proxy-error.monsite.log error;
listen 443 ssl;
ssl_certificate /blah/fullchain.pem;
ssl_certificate_key /blah/privkey.pem;
include /blah/options-ssl-nginx.conf;
ssl_dhparam /blah/ssl-dhparams.pem;
location / {
include denied_clients;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Server $host;
# (!) here it's uwsgi:
include uwsgi_params;
uwsgi_pass 127.0.0.1:8002;
}
}
# redirect http -> https:
server {
listen *:80;
server_name "~^monsite\..*$";
return 302 https://$host$request_uri;
}
Flask
Pour installer flask, et uwsgi, faites un environnement virtuel puis installez les deux :
$ python3 -m venv venvpython.3.6.6
$ source venvpython.3.6.6/bin/activate
$ pip install --upgrade pip
$ pip install flask
uwsgi
Il faut être dans le venv activé (voir paragraphe précédent), puis l’installer via pip
:
$ pip install uwsgi
Enfin, le script de lancement !
uwsgi --chdir=/web/htdocs/blah \
--module=flask_server:application \
--master --pidfile=/tmp/uwsgi.blah.pid \
--socket=127.0.0.1:8004 \
--processes=5 \
--uid=1000 --gid=2000 \
--harakiri=20 \
--max-requests=5000 \
--vacuum \
--home=/web/htdocs/blah/venvpython.3.6.6
flask_server
correspond au fichier python flask_server.py
décrit dans la section python au début et application
est le nom de la variable globale (lisez le code de la section python)
Lorsque vous le lancerez, tout se passera bien, mais l’exécutable ne sera pas en tâche de fond. Cela a un avantage : un CTRL-C et vous l’arrêtez ! L’inconvénient, c’est que vous n’avez pas la main.
Si vous voulez le lancer en tâche de fond et qu’il écrive les logs dans un fichier, ajoutez l’option
--daemonize=/var/log/uwsgi/blah.uwsgi.log
Notes d’amélioration :
– Le port
8004
peut être passé en tant que variable d’environnement à l’application flask via le paramètre `env
` de la commande uwsgi, ce qui rend le code plus portable ;– Les paramètres uwsgi peuvent être consignés dans un fichier
my_app.ini
et uwsgi
serait alors lancé en faisant uwsgi my_app.ini