Установка виртуального окружения, Gunicorn и списка зависимостей

⏱ 35 мин · 🧩 заданий: 6

Подготовка проекта

Перед выкладкой убедитесь, что:

  • проект лежит в git-репозитории (GitHub, GitLab) и в нём нет секретов;
  • requirements.txt актуален: pip freeze > requirements.txt;
  • .gitignore исключает venv/, db.sqlite3, .env, media/, staticfiles/.

Настройки для продакшена

Секреты и параметры окружения — из переменных окружения:

import os
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent

SECRET_KEY = os.environ["DJANGO_SECRET_KEY"]
DEBUG = os.environ.get("DJANGO_DEBUG", "0") == "1"
ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS", "").split(",")
CSRF_TRUSTED_ORIGINS = [f"https://{h}" for h in ALLOWED_HOSTS if h]

STATIC_ROOT = BASE_DIR / "staticfiles"
MEDIA_ROOT = BASE_DIR / "media"

DEBUG = False

С DEBUG = True любой посетитель при ошибке увидит код, настройки и пути вашего проекта. В продакшене — только False.

Новый секретный ключ:

python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"

Django может сам проверить настройки безопасности:

python manage.py check --deploy

Установка на сервере

sudo apt install python3 python3-venv python3-dev git build-essential -y
cd ~
git clone https://github.com/you/blog.git
cd blog
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pip install gunicorn

Файл окружения /home/deploy/blog/.env:

DJANGO_SECRET_KEY=сгенерированный-ключ
DJANGO_DEBUG=0
DJANGO_ALLOWED_HOSTS=myblog.ru,www.myblog.ru
DB_NAME=blog
DB_USER=blog
DB_PASSWORD=надёжный-пароль
DB_HOST=localhost
chmod 600 .env

Для ручных команд загрузите переменные в текущую сессию:

set -a; source .env; set +a
python manage.py migrate
python manage.py collectstatic --noinput
python manage.py createsuperuser

collectstatic собирает статику всех приложений (включая админку) в STATIC_ROOT — её будет раздавать NGINX.

Gunicorn

Gunicorn — WSGI-сервер для продакшена: запускает несколько процессов-воркеров с вашим Django-приложением.

Проверка:

gunicorn --bind 0.0.0.0:8000 mysite.wsgi:application

Временно откройте порт (sudo ufw allow 8000) и зайдите на http://IP:8000 — сайт откроется без стилей (статику раздаст NGINX). Затем остановите (Ctrl+C) и закройте порт (sudo ufw delete allow 8000).

Число воркеров — по формуле 2 × ядра + 1 (для 1 ядра — 3).

Служба systemd

Чтобы Gunicorn работал постоянно, перезапускался при сбое и стартовал вместе с сервером, оформим его службой.

Сокет /etc/systemd/system/gunicorn.socket:

[Unit]
Description=gunicorn socket

[Socket]
ListenStream=/run/gunicorn.sock

[Install]
WantedBy=sockets.target

Служба /etc/systemd/system/gunicorn.service:

[Unit]
Description=gunicorn daemon for blog
Requires=gunicorn.socket
After=network.target

[Service]
User=deploy
Group=www-data
WorkingDirectory=/home/deploy/blog
EnvironmentFile=/home/deploy/blog/.env
ExecStart=/home/deploy/blog/venv/bin/gunicorn \
          --workers 3 \
          --bind unix:/run/gunicorn.sock \
          mysite.wsgi:application

[Install]
WantedBy=multi-user.target

Gunicorn слушает unix-сокет — файл, через который с ним будет общаться NGINX. Это быстрее и безопаснее открытого порта.

sudo systemctl daemon-reload
sudo systemctl enable --now gunicorn.socket
sudo systemctl status gunicorn.socket
curl --unix-socket /run/gunicorn.sock localhost   # первый запрос запустит службу
sudo systemctl status gunicorn

Полезные команды:

Команда Что делает
sudo systemctl restart gunicorn Перезапуск (после обновления кода)
sudo systemctl status gunicorn Состояние
sudo journalctl -u gunicorn -f Логи в реальном времени

Итог

  • Секреты — в .env на сервере (права 600), в коде — os.environ.
  • DEBUG = False, правильные ALLOWED_HOSTS, check --deploy.
  • Проект: git clone → venv → pip install -r requirements.txt → migrate → collectstatic.
  • Gunicorn запускается как служба systemd и слушает unix-сокет.

Практика решено 0 из 6

Вы не вошли — ответы проверяются, но прогресс не сохранится. Войти или зарегистрироваться.
Задание 1 Один вариант ответа

Почему нельзя использовать python manage.py runserver в продакшене?

Задание 2 Написать код

Сделайте настройки безопасными для продакшена: DEBUG берётся из переменной окружения DJANGO_DEBUG (истина только при значении "1"), SECRET_KEY — из DJANGO_SECRET_KEY (через os.environ[...]), ALLOWED_HOSTS — из DJANGO_ALLOWED_HOSTS, разделённых запятыми.

Задание 3 Ввод ответа

Какой командой запустить Gunicorn для проекта mysite на порту 8000 со всеми интерфейсами (для проверки)?

Задание 4 Написать код

Допишите секцию [Service] юнита systemd для Gunicorn: пользователь deploy, группа www-data, рабочая папка /home/deploy/blog, команда запуска — /home/deploy/blog/venv/bin/gunicorn с 3 воркерами, привязкой к сокету unix:/run/gunicorn.sock и приложением mysite.wsgi:application.

Задание 5 Один вариант ответа

Сколько воркеров Gunicorn рекомендует документация как отправную точку?

Задание 6 Практика (выполнить у себя)

Разверните проект на сервере, запустите Gunicorn как службу systemd и выполните sudo systemctl is-active gunicorn. Вставьте вывод.

Войдите, чтобы отмечать пройденные уроки.