- en
- Language: ru
- Documentation version: 1.1.x
Автономные контейнеры WSGI¶
Существуют популярные серверы, написанные на Python, которые содержат приложения WSGI и обслуживают HTTP. Эти серверы работают отдельно; вы можете обращаться к ним через прокси-сервер с вашего веб-сервера. Обратите внимание на раздел Настройки прокси-сервера, если у вас возникнут проблемы.
Gunicorn¶
<
$ 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 Router:
$ uwsgi --http 127.0.0.1:5000 --module myproject:app
Для более оптимизированной настройки смотрите configuring uWSGI and 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, зрелой, неблокирующей событийно-управляемой сетевой библиотекой. 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)