Flask
Wdrażanie aplikacji Flask za pomocą serwera WWW uWSGI z Nginx
Szukaj…
Używanie uWSGI do uruchomienia aplikacji kolby
Wbudowany serwer werkzeug
pewnością nie nadaje się do uruchamiania serwerów produkcyjnych. Najbardziej oczywistym powodem jest fakt, że serwer werkzeug
jest jednowątkowy, a zatem może obsłużyć tylko jedno żądanie na raz.
Z tego powodu chcemy używać serwera uWSGI do obsługi naszej aplikacji. W tym przykładzie zainstalujemy uWSGI i uruchomimy z nim prostą aplikację testową.
Instalowanie uWSGI :
pip install uwsgi
To takie proste. Jeśli nie masz pewności co do wersji Pythona, której używa pip, wyraź to:
python3 -m pip install uwsgi # for python3
python2 -m pip install uwsgi # for python2
Teraz stwórzmy prostą aplikację testową:
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
W kolbie konwencjonalną nazwą aplikacji jest app
ale uWSGI domyślnie szuka application
. Dlatego w ostatnim wierszu tworzymy alias dla naszej aplikacji.
Teraz nadszedł czas, aby uruchomić aplikację:
uwsgi --wsgi-file app.py --http :5000
Powinieneś zobaczyć komunikat „Hello uWSGI ...”, wskazując przeglądarkę na localhost:5000
Aby nie wpisywać pełnego polecenia za każdym razem, tworzymy plik uwsgi.ini
do przechowywania tej konfiguracji:
uwsgi.ini
[uwsgi]
http = :9090
wsgi-file = app.py
single-interpreter = true
enable-threads = true
master = true
Opcje wsgi-file
http
i wsgi-file
są takie same jak w poleceniu ręcznym. Ale są jeszcze trzy opcje:
single-interpreter
: Zaleca się włączyć to, ponieważ może to zakłócać następną opcjęenable-threads
: To musi być włączone, jeśli używasz dodatkowych wątków w swojej aplikacji. Nie używamy ich teraz, ale teraz nie musimy się tym martwić.master
: Tryb Master powinien być włączony z różnych powodów
Teraz możemy uruchomić aplikację za pomocą tego polecenia:
uwsgi --ini uwsgi.ini
Instalowanie nginx i konfigurowanie go dla uWSGI
Teraz chcemy zainstalować nginx, aby obsługiwał naszą aplikację.
sudo apt-get install nginx # on debian/ubuntu
Następnie tworzymy konfigurację dla naszej strony internetowej
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;
}
}
To każe nginx nasłuchiwać na porcie 80 (domyślnie dla http) i podawać coś w ścieżce katalogu głównego ( /
). Mówimy tam, aby nginx działał po prostu jako serwer proxy i przekazywał każde żądanie do gniazda o nazwie flask.sock
znajdującego się w /tmp/
.
Włączmy witrynę:
cd /etc/nginx/sites-enabled
sudo ln -s ../sites-available/flaskconfig .
Możesz usunąć domyślną konfigurację, jeśli jest włączona:
# inside /etc/sites-enabled
sudo rm default
Następnie uruchom ponownie nginx:
sudo service nginx restart
Skieruj przeglądarkę na localhost
a zobaczysz błąd: 502 Bad Gateway
.
Oznacza to, że nginx działa i działa, ale brakuje gniazda. Stwórzmy to.
Wróć do pliku uwsgi.ini
i otwórz go. Następnie dodaj te linie:
socket = /tmp/flask.sock
chmod-socket = 666
Pierwszy wiersz mówi uwsgi, aby utworzyło gniazdo w danej lokalizacji. Gniazdo będzie używane do odbierania żądań i wysyłania odpowiedzi. W ostatnim wierszu zezwalamy innym użytkownikom (w tym nginx) na odczyt i zapis z tego gniazda.
Uruchom uwsgi ponownie za pomocą uwsgi --ini uwsgi.ini
. Teraz ponownie skieruj przeglądarkę na localhost
a ponownie zobaczysz powitanie „Hello uWSGI”.
Zauważ, że nadal możesz zobaczyć odpowiedź na localhost:5000
ponieważ uWSGI obsługuje teraz aplikację przez http i gniazdo. Wyłączmy więc opcję http w pliku ini
http = :5000 # <-- remove this line and restart uwsgi
Teraz do aplikacji można uzyskać dostęp tylko z nginx (lub bezpośrednio czytając to gniazdo :)).
Włącz strumieniowanie z kolby
Flask ma tę funkcję, która pozwala przesyłać strumieniowo dane z widoku za pomocą generatorów.
app.py
plik app.py
- dodaj
from flask import Response
- dodaj
from datetime import datetime
- dodaj
from time import sleep
- utwórz nowy widok:
@app.route("/time/")
def time():
def streamer():
while True:
yield "<p>{}</p>".format(datetime.now())
sleep(1)
return Response(streamer())
Teraz otwórz przeglądarkę na localhost/time/
. Witryna będzie się ładować na zawsze, ponieważ nginx czeka na odpowiedź do końca. W takim przypadku odpowiedź nigdy nie będzie kompletna, ponieważ na zawsze wyśle bieżącą datę i godzinę.
Aby zapobiec oczekiwaniu nginx, musimy dodać nowy wiersz do konfiguracji.
Edytuj /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
}
}
Linia uwsgi_buffering off;
mówi nginx, aby nie czekał na odpowiedź do końca.
Zrestartuj nginx: sudo service nginx restart
i spójrz na localhost/time/
again.
Teraz zobaczysz, że co sekundę pojawia się nowa linia.
Skonfiguruj aplikację Flask, uWGSI, Nginx - szablon kotła Konfiguracje serwera (domyślnie, proxy i pamięć podręczna)
Jest to portowanie konfiguracji pochodzącej z samouczka DigitalOcean na temat obsługi aplikacji Flask za pomocą uWSGI i Nginx na Ubuntu 14.04
i kilka przydatnych zasobów git dla serwerów nginx.
Aplikacja na kolbę
W tym samouczku założono, że używasz Ubuntu.
- zlokalizuj folder
var/www/
. - Utwórz folder aplikacji internetowej
mkdir myexample
-
cd myexample
opcjonalnie Możesz skonfigurować środowisko wirtualne do wdrażania aplikacji internetowych na serwerze produkcyjnym.
sudo pip install virtualenv
zainstalować środowisko wirtualne.
virtualenv myexample
skonfigurować środowisko wirtualne dla Twojej aplikacji.
source myprojectenv/bin/activate
aby aktywować środowisko. Tutaj zainstalujesz wszystkie pakiety Pythona.
koniec opcjonalny, ale zalecany
Skonfiguruj skrzynkę i bramę uWSGI
Zainstaluj kolbę i bramę uSWGI:
pip install uwsgi flask
Przykład aplikacji flask w 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')
Utwórz plik do komunikacji między aplikacją internetową a serwerem: interfejs bramy [ https://en.wikipedia.org/wiki/Web_Server_Gateway_Interface]
nano wsgi.py
następnie zaimportuj moduł aplikacji internetowej i uruchom go z punktu wejścia bramy.
from myexample import application
if __name__ == "__main__":
application.run()
Aby przetestować uWSGI:
uwsgi --socket 0.0.0.0:8000 --protocol=http -w wsgi
Aby skonfigurować uWSGI:
Utwórz plik konfiguracyjny
.ini
nano myexample.ini
Podstawowa konfiguracja bramki 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
opcjonalne, jeśli używasz wirtualnej env Możesz deactivate
swoje wirtualne środowisko.
Konfiguracja Nginx Użyjemy nginx jako:
- domyślny serwer do przekazywania żądań do gniazda przy użyciu protokołu uwsgi
- serwer proxy przed domyślnym serwerem
- buforuj serwer w celu buforowania udanych żądań (na przykład możesz chcieć buforować żądania GET, jeśli twoja aplikacja internetowa)
Znajdź katalog sites-available
dla sites-available
i utwórz plik konfiguracyjny dla swojej aplikacji:
sudo nano /etc/nginx/sites-available/myexample
Dodaj następujący blok, w komentarzach, co robi:
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;
}
}
Na koniec połącz plik z katalogiem sites-enabled
. Aby uzyskać wyjaśnienie dostępnych i włączonych witryn, zobacz odpowiedź: [ http://serverfault.com/a/527644]
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
Skończyłeś z nginx. Możesz jednak sprawdzić ten bardzo cenny szablon kotła: [ https://github.com/h5bp/server-configs-nginx]
Bardzo przydatne do precyzyjnego strojenia.
Teraz przetestuj Nginx:
sudo nginx -t
Uruchom Nginx:
sudo service nginx restart
Zautomatyzuj Ubuntu, aby uruchomić uWSGI Ostatnią rzeczą jest, aby Ubuntu uruchomił bramę wsgi komunikującą się z twoją aplikacją, w przeciwnym razie powinieneś zrobić to ręcznie.
- Znajdź katalog skryptów inicjujących w Ubuntu i utwórz nowy skrypt:
sudo nano /etc/init/myexample.conf
Dodaj następujący blok, komentarze w linii, aby wyjaśnić, co robi
# 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
Teraz możesz aktywować skrypt: sudo uruchom mój przykład