← Назад к вопросам
Почему не стоит запускать приложение через manage.py в Django?
1.8 Middle🔥 171 комментариев
#Django
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Почему не стоит использовать manage.py для production Django приложений
Это очень важный вопрос о различии между development и production окружением. manage.py runserver предназначен ТОЛЬКО для локальной разработки, а не для реальных приложений.
1. manage.py runserver — это development сервер
Что такое manage.py runserver?
# Development сервер Django
$ python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
Starting development server at http://127.0.0.1:8000/
# Сервер автоматически перезагружается при изменении кода
# Это удобно для разработки, но опасно для production
Это сервер, встроенный в Django, предназначенный только для локальной разработки на одной машине.
2. Проблемы development сервера для production
Проблема 1: Однопоточная обработка
# manage.py runserver обрабатывает запросы последовательно
# Если приложение медленное, все остальные запросы ждут
from django.http import HttpResponse
import time
def slow_view(request):
time.sleep(5) # Медленная операция
return HttpResponse("Готово")
def fast_view(request):
return HttpResponse("Быстро")
# Если запрос пришёл в slow_view, fast_view будет ждать 5 секунд!
# В production это критическая проблема
Проблема 2: Нет обработки ошибок
# Если произойдёт ошибка в коде, development сервер может упасть
$ python manage.py runserver
# После ошибки
Traceback (most recent call last):
File "manage.py", line 8, in <module>
...
Exception: Something went wrong
# Приложение просто падает. Нет автоматического перезапуска.
Проблема 3: Нет производительности
# Development сервер не оптимизирован для скорости
# Время ответа значительно больше, чем на production сервере
# Development (manage.py runserver): ~500ms
# Production (gunicorn + nginx): ~50ms
# В production может быть 1000+ одновременных пользователей
# Development сервер может обработать максимум 1-2
Проблема 4: Нет сессионности
# Development сервер не может масштабироваться на несколько машин
# В production часто нужно распределение нагрузки
# Это невозможно с manage.py runserver
# Нужно использовать production сервер (gunicorn, uWSGI)
Проблема 5: Автоматическая перезагрузка при изменениях
# Development сервер пересчитывает весь проект при изменении файлов
# В production это может привести к потере текущих запросов
$ python manage.py runserver
Watching for file changes with StatReloader
# Когда вы сохраняете файл...
django.core.exceptions.ImproperlyConfigured:
# Сервер перезагружается, все текущие соединения разрываются
3. Правильное решение: Production сервер
Архитектура production приложения
Клиент
|
v
Nginx (обратный прокси, static файлы)
|
v
Gunicorn (WSGI сервер, несколько workers)
|
+-> Django процесс 1
+-> Django процесс 2
+-> Django процесс 3
+-> Django процесс 4
|
v
PostgreSQL (база данных)
Redis (кэш, сессии)
Gunicorn — правильный сервер приложений
# Установка
$ pip install gunicorn
# Запуск с 4 workers
$ gunicorn myproject.wsgi:application --workers 4 --bind 0.0.0.0:8000
# Вывод
[2024-03-23 10:30:45 +0000] [1234] [INFO] Starting gunicorn 21.0.0
[2024-03-23 10:30:45 +0000] [1234] [INFO] Listening at: http://0.0.0.0:8000
[2024-03-23 10:30:45 +0000] [1234] [INFO] Workers: 4
# Теперь может обработать много одновременных запросов
Конфигурация Gunicorn
# gunicorn.conf.py
import multiprocessing
# Число workers = 2 * CPU cores + 1
workers = multiprocessing.cpu_count() * 2 + 1
worker_class = 'sync' # или 'gevent' для асинхронности
worker_connections = 1000
max_requests = 1000
max_requests_jitter = 50
timeout = 30
keepalive = 2
bind = '0.0.0.0:8000'
accesslog = '/var/log/gunicorn/access.log'
errorlog = '/var/log/gunicorn/error.log'
loglevel = 'info'
4. Сравнение: Development vs Production
# development/settings.py (для разработки)
DEBUG = True # Показываем ошибки
ALLOWED_HOSTS = ['localhost', '127.0.0.1']
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'db.sqlite3',
}
}
# production/settings.py (для боевого сервера)
DEBUG = False # Скрываем ошибки
ALLOWED_HOSTS = ['example.com', 'www.example.com']
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'myapp_db',
'USER': 'myapp',
'PASSWORD': 'secure_password',
'HOST': 'db.example.com',
'PORT': '5432',
}
}
STATIC_ROOT = '/var/www/static/'
STATIC_URL = 'https://cdn.example.com/static/'
5. Полный stack для production
Docker Compose пример
version: '3.8'
services:
web:
image: myapp:latest
command: gunicorn myproject.wsgi:application --workers 4 --bind 0.0.0.0:8000
ports:
- "8000:8000"
environment:
- DEBUG=False
- DJANGO_SETTINGS_MODULE=myproject.settings.production
depends_on:
- db
- redis
volumes:
- ./static:/app/static
- ./media:/app/media
db:
image: postgres:15
environment:
- POSTGRES_DB=myapp_db
- POSTGRES_USER=myapp
- POSTGRES_PASSWORD=secure_password
volumes:
- ./data/postgres:/var/lib/postgresql/data
redis:
image: redis:7
ports:
- "6379:6379"
nginx:
image: nginx:latest
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./static:/static:ro
- ./media:/media:ro
depends_on:
- web
Nginx конфигурация
upstream django {
server web:8000; # Обращаемся к gunicorn
}
server {
listen 80;
server_name example.com www.example.com;
client_max_body_size 20M;
location /static/ {
alias /static/;
}
location /media/ {
alias /media/;
}
location / {
proxy_pass http://django;
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;
proxy_redirect off;
}
}
6. Сравнение производительности
# benchmark.py
import requests
import time
from concurrent.futures import ThreadPoolExecutor
def make_request():
return requests.get('http://localhost/api/data')
# Development (manage.py runserver)
# Результат: 5 запросов/сек, время ответа ~200ms
# Production (gunicorn + nginx)
# Результат: 500 запросов/сек, время ответа ~20ms
# Production в 100 раз быстрее!
7. Когда можно использовать manage.py?
# ✅ Правильное использование manage.py
# Локальная разработка
$ python manage.py runserver
# Миграции базы данных
$ python manage.py migrate
# Создание суперпользователя
$ python manage.py createsuperuser
# Загрузка данных
$ python manage.py loaddata fixtures.json
# Кастомные команды
$ python manage.py mycustom_command
# ❌ НИКОГДА в production
$ python manage.py runserver # Production запуск — ОПАСНО!
8. Правильный процесс запуска
# Локальная разработка
$ python manage.py migrate
$ python manage.py runserver
# Production
$ python manage.py migrate # Выполнить миграции
$ gunicorn myproject.wsgi:application --workers 4 # Запустить приложение
$ # Nginx уже проксирует трафик на gunicorn
Резюме
manage.py runserver:
- ✅ Хорош для локальной разработки
- ❌ Однопоточный
- ❌ Медленный
- ❌ Не масштабируется
- ❌ Нет балансировки нагрузки
- ❌ Нет обработки ошибок
Gunicorn (Production):
- ✅ Многопроцессный
- ✅ Быстрый
- ✅ Масштабируется
- ✅ Можно использовать несколько workers
- ✅ Правильная обработка ошибок
- ✅ Совместим с Nginx
Ключевые выводы
- manage.py runserver предназначен ТОЛЬКО для разработки — никогда не используй в production
- В production используй gunicorn или другой WSGI сервер — они специально разработаны для этого
- Используй несколько workers — для обработки множества одновременных запросов
- Поставь Nginx впереди — для проксирования трафика и раздачи статических файлов
- Настрой отдельные settings — development и production должны иметь разные конфигурации
Эта архитектура позволяет обслуживать тысячи пользователей одновременно и обеспечивает надёжность и производительность production приложения.