Почему нельзя использовать встроенный сервер Django (runserver) в продакшене

Ответ

Команда manage.py runserver запускает легковесный сервер, предназначенный исключительно для разработки и отладки. Использовать его в продакшене небезопасно и неэффективно по нескольким причинам:

  1. Низкая производительность. Сервер является однопоточным и может обрабатывать только один запрос за раз. Под реальной нагрузкой он быстро станет узким местом и не сможет обслуживать конкурентных пользователей.

  2. Отсутствие аудита безопасности. Он не проходил тщательного тестирования на уязвимости, в отличие от промышленных серверов (Gunicorn, uWSGI), и не имеет встроенных механизмов защиты от многих видов атак.

  3. Неэффективная обработка статики. Встроенный сервер не предназначен для раздачи статических файлов (CSS, JS, изображения). В продакшене эту задачу должен выполнять специализированный веб-сервер, например, Nginx, который делает это гораздо быстрее.

Правильный стек для продакшена:

Обычно используется связка из веб-сервера (Nginx) и WSGI/ASGI-сервера (Gunicorn, uWSGI).

  • Nginx принимает входящие HTTP-запросы и отдает статику.
  • Gunicorn запускает несколько рабочих процессов вашего Django-приложения и обрабатывает динамические запросы, переданные от Nginx.

Пример запуска с Gunicorn:

# Установка WSGI-сервера
pip install gunicorn

# Запуск 4 рабочих процессов для обслуживания приложения
# myproject.wsgi - это путь к WSGI-файлу вашего проекта
gunicorn --workers 4 myproject.wsgi:application

Ответ 18+ 🔞

А, слушай, про эту команду manage.py runserver... Ну, это как взять детский велосипед с подстраховочными колёсами и попытаться на нём в Париж-Дакар заехать. Серьёзно, ёпта.

Этот сервер — он чисто для разработки, чтобы ты локально код свой тестировал, смотрел, как шаблоны отрисовываются. Выкатывать на нём проект в продакшен — это всё равно что прийти на стройку с пластиковым совочком и сказать «я сейчас вам тут фундамент заложу». Нахуй так нельзя.

Почему? Да потому что он, этот сервер, нихуя не умеет! Во-первых, он однопоточный. Представь: один кассир в «Пятёрочке» в час пик. Очередь до Москвы, а он один, сука, пробивает. Каждый следующий запрос ждёт, пока предыдущий не обосрётся. Под нагрузкой он просто накроется медным тазом, и всё, пиздец твоему сайту.

Во-вторых, безопасность. Этот сервер — как дверь из картона. Он не проходил никаких аудитов, в него не встроена защита от кучи известных атак. Использовать его на реальном сервере — это просто кричать всем хакерам: «Эй, пацаны, заходите, тут халява!».

Ну и в-третьих, статика. CSS, JS, картинки — он их раздаёт, конечно, но так, через жопу. Медленно и неэффективно. В продакшене этим должен заниматься специально обученный зверь.

Так как же надо, блядь?

Нормальный, рабочий стек выглядит так: Nginx + Gunicorn (или uWSGI).

  • Nginx — это крутой, быстрый веб-сервер. Он стоит на входе, принимает все запросы от пользователей, молниеносно отдаёт статику, а динамические запросы (те, что Django должен обработать) передаёт дальше.
  • Gunicorn — это уже WSGI-сервер. Его задача — запустить несколько копий (воркеров) твоего Django-приложения и кормить их этими самыми запросами от Nginx. Не один процесс, а сразу несколько — вот и многопоточность, на тебе.

Как это запустить, примерно:

Сначала ставим самого Гуникорна:

pip install gunicorn

А потом запускаем наше приложение, но уже не через runserver, а через него. Скажем, 4 воркера, чтобы сразу четыре запроса параллельно жрать могли:

# myproject.wsgi — это путь к WSGI-приложению твоего проекта
gunicorn --workers 4 myproject.wsgi:application

Вот это уже будет похоже на правду. А runserver оставь для локальной возни, в рот меня чих-пых.