ДЕПЛОЙ DJANGO НА VPS

GUNICORN, NGINX, POSTGRESQL

Деплой Django на сервер

Деплой Django на VPS

PostgreSQL, Gunicorn, Nginx, HTTPS

Что понадобится

VPS на Ubuntu 22.04 или 24.04, минимум 2 ГБ памяти, домен и полчаса времени. Схема классическая: Nginx принимает запросы снаружи, Gunicorn запускает Django, PostgreSQL хранит данные, systemd следит, чтобы процессы не падали.

Шаг 1. Подготовить сервер

adduser deploy
usermod -aG sudo deploy
ufw allow OpenSSH
ufw allow "Nginx Full"
ufw enable

Работать под root постоянно не стоит: одна опечатка в команде обходится дорого.

Шаг 2. Установить пакеты и базу

sudo apt update
sudo apt install python3-venv python3-pip postgresql nginx
sudo -u postgres createuser --interactive
sudo -u postgres createdb blogdb

Шаг 3. Код и окружение

cd /var/www
git clone git@github.com:user/blog.git
cd blog
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

В requirements.txt фиксируйте версии: Django, Gunicorn, psycopg2-binary, whitenoise. Иначе через месяц сборка на сервере даст другой результат.

Шаг 4. Настройки для продакшна

Три вещи, без которых деплой опасен: отключённый режим отладки, реальный домен в ALLOWED_HOSTS и секретный ключ из переменной окружения, а не из репозитория.

DEBUG = False
ALLOWED_HOSTS = ["majorsky.ru", "www.majorsky.ru"]
SECRET_KEY = os.environ["DJANGO_SECRET_KEY"]

Файл .env с ключами не коммитится, права на него — только у владельца.

Шаг 5. Gunicorn и systemd

gunicorn config.wsgi:application --bind 127.0.0.1:8000 --workers 3

Три воркера — правило «два ядра плюс один». Чтобы процесс перезапускался после падения и перезагрузки, создайте юнит /etc/systemd/system/blog.service с рабочим каталогом, командой запуска и Restart=always, затем включите его через systemctl enable --now blog.

Шаг 6. Nginx

Nginx отдаёт статику и проксирует остальное на Gunicorn. В конфиге сайта важны два блока: location /static/ с путём к собранной статике и location / с проксированием на порт 8000.

Перед первым запуском соберите статику: python manage.py collectstatic. Если её раздаёт сам Django через WhiteNoise, блок /static/ можно не писать — но для больших проектов Nginx быстрее.

Шаг 7. HTTPS

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d majorsky.ru -d www.majorsky.ru

Certbot сам пропишет сертификат и настроит редирект с HTTP. Продление автоматическое, проверяется таймером systemd.

Чек-лист перед запуском

  • Режим отладки выключен, ALLOWED_HOSTS заполнен, секреты вне репозитория.
  • Миграции применены, суперпользователь создан.
  • Статика собрана и отдаётся, в консоли браузера нет 404.
  • Настроены резервные копии базы, хотя бы ежедневные.
  • Включён файрвол, доступ к PostgreSQL снаружи закрыт.

Частые ошибки

  • 502 Bad Gateway. Gunicorn не запущен или слушает другой порт. Смотрите журнал: journalctl -u blog -n 50.
  • DisallowedHost. Домен не добавлен в ALLOWED_HOSTS — Django блокирует запрос специально.
  • Стили не грузятся. Забыли collectstatic либо путь в конфиге Nginx не совпадает с каталогом статики.
  • Сайт падает через сутки. Обычно заканчивается память: проверьте число воркеров и размер базы.

Нужен сайт на Django, а не статья?

Сделаю проект под ключ: модели данных, админка, интеграции с 1С и оплатой, REST API, деплой на ваш сервер с HTTPS и резервными копиями. С 2009 года, по договору, с поддержкой после запуска.

ОБСУДИТЬ ПРОЕКТ

Полезно по теме: обзор Django, установка, модели и ORM, views и URL.