VPS для Django на production: gunicorn детально
Production-деплой Django — это gunicorn как WSGI-сервер, nginx впереди и правильно собранная статика. Пройдём весь путь по шагам: venv, gunicorn под systemd через сокет, nginx, collectstatic и TLS.
Содержание
Схема production-деплоя
['Встроенный сервер runserver не предназначен для боевой эксплуатации. На production Django запускают через WSGI-сервер — чаще всего gunicorn, который держит пул воркеров и обрабатывает параллельные запросы.', 'Перед gunicorn ставят nginx: он терминирует TLS, отдаёт статику и медиа, а динамику проксирует в gunicorn через unix-сокет. Такая связка стабильна и хорошо держит нагрузку.', '- gunicorn — WSGI-сервер, воркеры под запросы.
- nginx — TLS, статика, reverse proxy.
- collectstatic — сбор статики в одну папку для nginx.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK и США. Оплата картой РФ и по СБП.
Арендовать VPS для DjangoПодготовка окружения
['Ставим Python, создаём виртуальное окружение и заводим зависимости. Отдельный пользователь повышает безопасность.', 'sudo apt update\nsudo apt install -y python3 python3-venv python3-pip nginx git\nsudo mkdir -p /opt/djangoapp && cd /opt/djangoapp\npython3 -m venv venv\nsource venv/bin/activate\npip install -r requirements.txt gunicorn']
Настройки Django для прода
['В settings.py переключаем режим: выключаем DEBUG, задаём ALLOWED_HOSTS и путь для собранной статики. Секретный ключ берём из окружения.', "DEBUG = False\nALLOWED_HOSTS = ['example.com', 'www.example.com']\nSTATIC_ROOT = '/opt/djangoapp/staticfiles'\nSTATIC_URL = '/static/'\nSECRET_KEY = os.environ['DJANGO_SECRET_KEY']", 'Собираем статику и применяем миграции:', 'python manage.py collectstatic --noinput\npython manage.py migrate', 'Для базы данных на production почти всегда берут PostgreSQL. Параметры подключения выносите в переменные окружения, а не хардкодьте в settings.py — так один и тот же код работает и локально, и на сервере.', 'sudo apt install -y postgresql libpq-dev\nsudo -u postgres createdb djangoapp\npip install psycopg2-binary']
gunicorn под systemd через сокет
['Надёжнее всего запускать gunicorn на unix-сокете и управлять им через systemd. Число воркеров обычно берут как 2 × ядра + 1.', '[Unit]\nDescription=gunicorn for Django\nAfter=network.target\n\n[Service]\nUser=appuser\nWorkingDirectory=/opt/djangoapp\nExecStart=/opt/djangoapp/venv/bin/gunicorn \\\n --workers 3 \\\n --bind unix:/opt/djangoapp/gunicorn.sock \\\n myproject.wsgi:application\nRestart=always\nEnvironment=DJANGO_SECRET_KEY=changeme\n\n[Install]\nWantedBy=multi-user.target', 'sudo systemctl daemon-reload\nsudo systemctl enable --now gunicorn\nsudo systemctl status gunicorn\njournalctl -u gunicorn -f', 'Для плавных деплоев без сброса всех соединений gunicorn поддерживает graceful reload по сигналу HUP: мастер поднимает новых воркеров и мягко гасит старых. Это удобно связать с командой перезапуска после выкатки кода.', 'sudo systemctl reload gunicorn']
nginx: статика и проксирование
['nginx сам отдаёт файлы из STATIC_ROOT, а динамику передаёт в сокет gunicorn. Это разгружает Python и ускоряет отдачу ассетов.', 'server {\n listen 80;\n server_name example.com;\n location /static/ {\n alias /opt/djangoapp/staticfiles/;\n }\n location / {\n proxy_pass http://unix:/opt/djangoapp/gunicorn.sock;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Forwarded-Proto $scheme;\n }\n}', 'sudo nginx -t && sudo systemctl reload nginx\nsudo apt install -y certbot python3-certbot-nginx\nsudo certbot --nginx -d example.com']
Ресурсы, железо и частые ошибки
['Django-проекты часто упираются в БД и CPU при обработке шаблонов и запросов. AMD EPYC + NVMe у MAATRIX дают быстрый диск для PostgreSQL и отзывчивый рантайм, тарифы от $8/мес и ежедневные бэкапы удобны для боевого сайта. Локации UK/США и оплата из России (карта РФ, СБП, крипта, MAAT) закрывают вопрос зарубежного сервера.', '- DEBUG=True на проде — утечка стектрейсов и настроек, серьёзная дыра.
- Забыли collectstatic — стили и админка без оформления.
- Пустой ALLOWED_HOSTS — Django отвечает ошибкой Bad Request (400).
- Права на сокет — nginx (www-data) должен иметь доступ к gunicorn.sock.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK и США. Оплата картой РФ и по СБП.
Арендовать VPS для DjangoЧастые вопросы
gunicorn или uwsgi?
Оба зрелые WSGI-серверы. gunicorn проще в настройке и документации, поэтому его чаще выбирают для Django. uwsgi гибче, но сложнее.
Сколько воркеров gunicorn нужно?
Стартовая формула — 2 × число ядер + 1. Подбирайте под реальную нагрузку и объём RAM, следя за потреблением памяти на воркер.
Как обслуживать медиа-файлы?
Загружаемые пользователями медиа отдавайте через отдельный location в nginx с alias на MEDIA_ROOT, не через Django.