Самостоятельные контейнеры WSGI
Существуют популярные серверы, написанные на Python, которые содержат приложения WSGI и обслуживают HTTP. Эти серверы работают автономно; к ним можно обращаться через прокси с вашего веб-сервера. Обратите внимание на раздел Настройки прокси, если у вас возникнут проблемы.
Gunicorn
Gunicorn «Зеленый единорог» — это WSGI HTTP-сервер для UNIX. Это модель предварительного разветвления, перенесённая из проекта Unicorn для Ruby. Он поддерживает как 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.
Gevent
Gevent — это основанная на сопрограммах Python-библиотека для сетевого программирования, использующая greenlet для предоставления высокоуровневого синхронного API поверх цикла событий libev:
from gevent.wsgi 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 для передачи этих заголовков или исправить их в middleware. Werkzeug поставляется с инструментом для исправления некоторых распространённых установок, но, возможно, вам нужно будет написать свой собственный WSGI-middleware для конкретных установок.
Вот простая конфигурация 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)
Доверие заголовкам
Пожалуйста, помните, что использование такого middleware вне прокси-настройки является проблемой безопасности, так как оно будет слепо доверять входящим заголовкам, которые могут быть подделаны злонамеренными клиентами.
Если вы хотите переписать заголовки из другого заголовка, вы можете использовать инструмент-исправления, подобный этому:
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.0.x/deploying/wsgi-standalone/