Python: нужен ли gunicorn для Flask?

Чтобы ответить на этот вопрос надо ответить на более простые вопросы.

Является ли Flask веб-сервером?

Нет. Flask это микро-framework для разработки веб-приложений. Однако если набрать python3 main.py, то увидим, что скрипт вполне себе запускается и отвечает на http запросы по порту 5000/tcp. Дело в том, что Flask в качестве development веб-сервера использует "Werkzeug wsgi server". Потому умеет обрабатывать http запросы из под коробки.

Безопасно ли использовать Flask без gunicorn?

Да. Безопасность в Flask обеспечивается на уровне кода. Если не обрабатывать ошибки, то можно заметить, что при возникновении ошибок Flask показывает трассировку прямо в браузере, где можно увидеть и название скрипта и часть кода, а это уже плюс к уязвимости. Чтобы избежать таких проблем достаточно добавить обработчик ошибок:

@app.errorhandler(Exception)
def server_error(err):
    app.logger.error(f"App error: {err}")
    return "Forbidden", 403

@app.errorhandler(ZeroDivisionError)
def server_error(err):
    app.logger.error(f"Server error: {err}")
    return "Cannot divide by 0", 500

Теперь при возникновении ошибок будет отдаваться http code 403, а при возникновении ошибок деления на ноль будет показывать http code 500. Иными словами, если код плохой, то использование gunicorn не даст никаких преимуществ.

Тогда почему рекомендуется использовать wsgi сервер?

Все дело банально в производительности. Когда код запускается на development сервере, то создается только один instance, который если сдохнет или будет занят большим количеством запросов, то приложение ляжет. Посмотрим как происходит запуск того же gunicorn:

gunicorn --workers 3 --bind unix:myproject.sock wsgi:app

Тут мы видим, что gunicorn запускается с тремя воркерами (они же instance или в плане веб-серверов дочерние процессы) и использует unix socket вместо tcp socket. Три воркера уже будут обрабатывать гораздо больше запросов, чем один, а использование unix socket позволяет избегать ограничений tcp хотя появляются другие ограничения связанные с файловыми дескрипторами, но это уже другая тема.

А нужен ли Nginx?

Советую использовать nginx абсолютно везде. Во-первых, вам в любом случае понадобятся SSL сертификаты, а wsgi серверы вряд ли заточены на их использование. Во-вторых, вам в любом случае понадобится frontend, который будет кэшировать статику для повышения производительности и экономии трафика. Также nginx дает плюс к безопасности (например, можно ограничить количество запросов с одного адреса).

Вывод

Приложение простое? Используйте development сервер. Приложению критична производительность? Используйте wsgi сервер. Хотите безопасность? Пишите безопасный код.

P.S. не забывайте отключать debugger на продакшне или хотя бы добавьте в nginx правило:

location ^~ /console {
	return 404;
}
Показать комментарии