Самостоятельные контейнеры WSGI
Существуют популярные серверы на Python, содержащие приложения WSGI и предоставляющие HTTP-сервис. Эти серверы работают автономно; к ним можно обратиться через прокси с вашего веб-сервера. Обратите внимание на раздел о Настройках прокси, если у вас возникнут проблемы.
Gunicorn
Gunicorn «Зелёный единорог» — WSGI HTTP-сервер для UNIX. Это модель пре-форка рабочих процессов, портированная из Ruby-проекта Unicorn. Он поддерживает как eventlet, так и greenlet. Запуск приложения Flask на этом сервере довольно прост:
$ gunicorn myproject:app
Gunicorn предоставляет множество командных опций — см. gunicorn -h. Например, для запуска приложения Flask с 4 рабочими процессами (-w
4) привязанными к localhost порту 4000 (-b 127.0.0.1:4000):
$ gunicorn -w 4 -b 127.0.0.1:4000 myproject:app
Команда gunicorn ожидает имен модуля или пакета вашего приложения и экземпляра приложения внутри модуля. Если вы используете шаблон фабрики приложения, вы можете передать вызов этому:
$ gunicorn "myproject:create_app()"
uWSGI
uWSGI — это быстрый сервер приложений, написанный на C. Он очень настраиваемый, что делает его настройку более сложной, чем gunicorn.
Запуск маршрутизатора uWSGI HTTP:
$ uwsgi --http 127.0.0.1:5000 --module myproject:app
Для более оптимизированной настройки см. настройка uWSGI и NGINX.
Gevent
Gevent — основанная на сопрограммах Python-библиотека сетевого программирования, которая использует greenlet для предоставления высокоуровневого синхронного API поверх цикла событий libev:
from gevent.pywsgi import WSGIServer
from yourapplication import app
http_server = WSGIServer(('', 5000), app)
http_server.serve_forever()
Twisted Web
Twisted Web — веб-сервер, поставляемый с Twisted, зрелой, неблокирующей библиотекой сетевого программирования с событийно-ориентированным подходом. Twisted Web поставляется со стандартным контейнером WSGI, которым можно управлять из командной строки с помощью утилиты twistd:
$ twistd web --wsgi myproject.app
Этот пример запустит приложение Flask с именем app из модуля с именем myproject.
Twisted Web поддерживает множество флагов и опций, и утилита twistd тоже; см. twistd -h и twistd web -h для получения дополнительной информации. Например, для запуска сервера Twisted Web в фоновом режиме на порту 8080 с приложением из myproject:
$ twistd -n web --port tcp:8080 --wsgi myproject.app
Настройки прокси
Если вы развертываете своё приложение, используя один из этих серверов за HTTP-прокси, вам потребуется переписать некоторые заголовки для корректной работы приложения. Обычно двумя проблемными значениями в среде WSGI являются REMOTE_ADDR и HTTP_HOST. Вы можете настроить httpd для передачи этих заголовков или исправить их в промежуточном программном обеспечении. Werkzeug поставляет инструмент, который решит некоторые распространённые ситуации, но, возможно, вам потребуется написать собственный WSGI-промежуточный слой для конкретных установок.
Вот простая конфигурация nginx, которая выполняет проксирование к приложению, работающему на localhost на порту 8000, устанавливая соответствующие заголовки:
server {
listen 80;
server_name _;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
location / {
proxy_pass http://127.0.0.1:8000/;
proxy_redirect off;
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-Forwarded-Proto $scheme;
}
}
Если ваш httpd не предоставляет эти заголовки, наиболее распространённая настройка предполагает установку хоста из X-Forwarded-Host и удалённого адреса из X-Forwarded-For:
from werkzeug.middleware.proxy_fix import ProxyFix app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1)
Использование заголовков с доверием
Пожалуйста, имейте в виду, что использование такого промежуточного программного обеспечения в настройке, не использующей прокси, является вопросом безопасности, поскольку оно будет слепо доверять входящим заголовкам, которые могут быть подделаны злонамеренными клиентами.
Если вы хотите переписать заголовки из другого заголовка, вам может понадобиться использовать инструмент, подобный этому:
class CustomProxyFix(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
host = environ.get('HTTP_X_FHOST', '')
if host:
environ['HTTP_HOST'] = host
return self.app(environ, start_response)
app.wsgi_app = CustomProxyFix(app.wsgi_app)
© 2007–2020 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/1.1.x/deploying/wsgi-standalone/