Flask
Развертывание приложения Flask с использованием веб-сервера uWSGI с Nginx
Поиск…
Использование uWSGI для запуска фляжного приложения
Встроенный сервер werkzeug
конечно, не подходит для запуска производственных серверов. Наиболее очевидной причиной является тот факт, что сервер werkzeug
является однопоточным и, следовательно, может обрабатывать только один запрос за раз.
Из-за этого мы хотим использовать сервер uWSGI для обслуживания нашего приложения. В этом примере мы установим uWSGI и запустим с ним простое тестовое приложение.
Установка uWSGI :
pip install uwsgi
Это так просто. Если вы не уверены в версии python, которую использует ваш протокол, сделайте его явным:
python3 -m pip install uwsgi # for python3
python2 -m pip install uwsgi # for python2
Теперь давайте создадим простое тестовое приложение:
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
В фляге стандартное имя приложения - app
но uWSGI ищет application
по умолчанию. Вот почему мы создаем псевдоним для нашего приложения в последней строке.
Теперь пришло время запустить приложение:
uwsgi --wsgi-file app.py --http :5000
Вы должны увидеть сообщение «Hello uWSGI ...», указав свой браузер на localhost:5000
Чтобы не вводить полную команду каждый раз, мы создадим файл uwsgi.ini
для сохранения этой конфигурации:
uwsgi.ini
[uwsgi]
http = :9090
wsgi-file = app.py
single-interpreter = true
enable-threads = true
master = true
Параметры http
и wsgi-file
такие же, как в ручной команде. Но есть еще три варианта:
single-interpreter
: рекомендуется включить это, потому что это может помешать следующей опцииenable-threads
: Это нужно включить, если вы используете дополнительные потоки в своем приложении. Мы не используем их прямо сейчас, но теперь нам не о чем беспокоиться.master
: Мастер-режим должен быть включен по разным причинам
Теперь мы можем запустить приложение с помощью этой команды:
uwsgi --ini uwsgi.ini
Установка nginx и настройка его на uWSGI
Теперь мы хотим установить nginx для обслуживания нашего приложения.
sudo apt-get install nginx # on debian/ubuntu
Затем мы создаем конфигурацию для нашего сайта
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;
}
}
Это говорит nginx прослушивать порт 80 (по умолчанию для http) и обслуживать что-то на корневом пути ( /
). Там мы говорим nginx просто действовать как прокси-сервер и передавать каждый запрос в сокет под названием flask.sock
расположенный в /tmp/
.
Давайте включим сайт:
cd /etc/nginx/sites-enabled
sudo ln -s ../sites-available/flaskconfig .
Возможно, вы захотите удалить конфигурацию по умолчанию, если она включена:
# inside /etc/sites-enabled
sudo rm default
Затем перезапустите nginx:
sudo service nginx restart
Направьте свой браузер на localhost
и вы увидите сообщение об ошибке: 502 Bad Gateway
.
Это означает, что nginx работает и работает, но сокет отсутствует. Поэтому давайте создадим это.
Вернитесь к своему файлу uwsgi.ini
и откройте его. Затем добавьте следующие строки:
socket = /tmp/flask.sock
chmod-socket = 666
Первая строка сообщает uwsgi о создании сокета в данном месте. Сокет будет использоваться для приема запросов и отправки ответов. В последней строке мы разрешаем другим пользователям (включая nginx) читать и записывать из этого сокета.
Запустите uwsgi снова с помощью uwsgi --ini uwsgi.ini
. Теперь снова укажите ваш браузер на localhost
и вы снова увидите приветствие приветствия uWSGI.
Обратите внимание, что вы все еще можете увидеть ответ на localhost:5000
потому что uWSGI теперь обслуживает приложение через http и сокет. Поэтому давайте отключить параметр http в ini-файле
http = :5000 # <-- remove this line and restart uwsgi
Теперь приложение может быть доступно только из nginx (или прямое чтение этого сокета :)).
Включить поток из фляжки
Flask имеет эту функцию, которая позволяет вам передавать данные из представления с помощью генераторов.
Давайте изменим файл app.py
- добавить
from flask import Response
- добавить
from datetime import datetime
- добавить
from time import sleep
- создать новое представление:
@app.route("/time/")
def time():
def streamer():
while True:
yield "<p>{}</p>".format(datetime.now())
sleep(1)
return Response(streamer())
Теперь откройте свой браузер на localhost/time/
. Сайт будет загружаться навсегда, потому что nginx ждет, пока ответ не будет завершен. В этом случае ответ никогда не будет завершен, потому что он будет отправлять текущую дату и время навсегда.
Чтобы предотвратить ожидание nginx, нам нужно добавить новую строку в конфигурацию.
Изменить /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
}
}
Линия uwsgi_buffering off;
говорит nginx не ждать завершения ответа.
Перезагрузите nginx: перезапустите sgino sudo service nginx restart
и посмотрите на localhost/time/
again.
Теперь вы увидите, что каждую секунду появляется новая строка.
Настроить флеш-приложение, uWGSI, Nginx - Конфигурация котла с конфигурацией сервера (по умолчанию, прокси и кеш)
Это портирование из источников, полученных из учебника DigitalOcean о том, как подавать фляжные приложения с помощью uWSGI и Nginx на Ubuntu 14.04
и некоторые полезные ресурсы git для серверов nginx.
Применение колбы
В этом учебнике предполагается использование Ubuntu.
- найдите папку
var/www/
. - Создайте свою папку веб-приложений
mkdir myexample
-
cd myexample
необязательно. Вы можете настроить виртуальную среду для развертывания веб-приложений на рабочем сервере.
sudo pip install virtualenv
для установки виртуальной среды.
virtualenv myexample
для настройки виртуальной среды для вашего приложения.
source myprojectenv/bin/activate
для активации вашей среды. Здесь вы будете устанавливать все пакеты python.
окончательный вариант, но рекомендуется
Настройте колбу и шлюз uWSGI
Установить колбу и шлюз uSWGI:
pip install uwsgi flask
Пример флеш-приложения в 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')
Создайте файл для связи между вашим веб-приложением и веб-сервером: интерфейс шлюза [ https://en.wikipedia.org/wiki/Web_Server_Gateway_Interface]
nano wsgi.py
затем импортируйте свой модуль webapp и запустите его из точки входа в шлюз.
from myexample import application
if __name__ == "__main__":
application.run()
Чтобы проверить uWSGI:
uwsgi --socket 0.0.0.0:8000 --protocol=http -w wsgi
Чтобы настроить uWSGI:
Создайте файл конфигурации
.ini
nano myexample.ini
Базовая конфигурация для шлюза 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
необязательно, если вы используете виртуальный env. Вы можете deactivate
свою виртуальную среду.
Конфигурация Nginx Мы будем использовать nginx как:
- сервер по умолчанию для передачи запроса в сокет, используя протокол uwsgi
- прокси-сервер перед сервером по умолчанию
- кэш-сервер для кэширования успешных запросов (например, вы можете захотеть кэшировать GET-запросы, если ваше веб-приложение)
Найдите каталог, sites-available
ваших sites-available
и создайте файл конфигурации для вашего приложения:
sudo nano /etc/nginx/sites-available/myexample
Добавьте следующий блок, в комментариях, что он делает:
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;
}
}
Наконец, свяжите файл с каталогом с поддержкой sites-enabled
. Для объяснения доступных и разрешенных сайтов см. Ответ: [ http://serverfault.com/a/527644]
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
Теперь вы закончили с nginx. Однако вы можете проверить этот очень ценный шаблон котла: [ https://github.com/h5bp/server-configs-nginx]
Очень полезно для точной настройки.
Теперь протестируйте Nginx:
sudo nginx -t
Запуск Nginx:
sudo service nginx restart
Автоматизация Ubuntu для запуска uWSGI Последнее, что нужно сделать, чтобы Ubuntu запустил wsgi-шлюз, взаимодействующий с вашим приложением, иначе вы должны сделать это вручную.
- Найдите каталог для сценариев инициализации в Ubuntu и создайте новый скрипт:
sudo nano /etc/init/myexample.conf
Добавьте следующий блок, комментарии в строке, чтобы объяснить, что он делает
# 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
Теперь вы можете активировать свой скрипт: sudo start myexample