Настройка Nginx и Gunicorn для Django-проекта: от установки Python до SSL
Развертывание Django-приложения на сервере — частая задача для тех, кто хочет создать свой веб-сайт или приложение на Python. Но не всегда есть время погружаться в документацию каждого сервиса и думать, как связать их все вместе. Если вам это знакомо — просто следуйте за инструкцией. Мы пошагово разберем весь процесс: от установки Python до настройки SSL.
Зачем нам Django, Gunicorn и Nginx
- Django — веб-фреймворк на Python, который упрощает создание сложных веб-приложений. Он включает ORM для работы с базами данных и систему маршрутизации запросов.
- Gunicorn — WSGI-сервер, который запускает Django-приложение и обрабатывает входящие HTTP-запросы, распределяя их между процессами.
- Nginx — веб-сервер, который мы будем использовать как реверс-прокси перед Gunicorn. Nginx балансирует нагрузку и обрабатывает статические файлы.
Вместе они помогут нам развернуть проект на сервере.
Мы создадим в панели управления виртуальную машину (ВМ). Этот вариант удобен, например, когда у вас нет своего сервера или мощности вашего ПК не соответствуют требованиям разработанного приложения. Вместо входа по паролю настроим на ВМ аутентификацию по SSH-ключу.
В нашем руководстве мы используем Ubuntu 22.04, однако большинство команд подойдут и для других дистрибутивов Linux.
Обновление пакетов apt
Перед установкой сервисов убедимся, что все пакеты на нашем сервере обновлены. Это поможет избежать возможных проблем с нарушенными зависимостями из-за старых версий пакетов. Для этого выполняем команду:
sudo apt update && sudo apt upgrade -y
Когда система обновится, перейдем к развертыванию проекта.
Установка Python
Django и Python не могут быть отделены друг от друга, поэтому теперь нам нужно установить Python и сопутствующие пакеты, такие как система управления пакетами pip и модуль venv для создания виртуальных окружений:
sudo apt install python3 python3-pip python3-venv -y
После окончания установки проверим, что Python установлен успешно:
python3 --version
Если в выводе вы увидели версию установленного Python, значит, установка удалась.
Создание аккаунта PostgreSQL и базы данных
Django включает в себя ORM — технологию, которая позволяет связать написанный код и базу данных. По умолчанию фреймворк использует легкую и быструю базу данных SQLite. Однако в продакшн-средах и условиях высоких нагрузок рекомендуется использовать базы данных вроде PostgreSQL. Именно ее мы и рассмотрим в нашей инструкции.
Установим БД командой:
sudo apt install postgresql postgresql-contrib -y
Перейдем к созданию базы данных и ее пользователя:
sudo -u postgres psql
В PostgreSQL выполняем:
CREATE DATABASE mydb;
CREATE USER myuser WITH PASSWORD 'mypassword’;
ALTER ROLE myuser SET client_encoding TO 'utf8’;
ALTER ROLE myuser SET default_transaction_isolation TO 'read committed’;
GRANT ALL PRIVILEGES ON DATABASE mydb TO myuser;
После выполнения выходим из PostgreSQL:
\q
Настройка виртуальной среды Python для Django
Даже несмотря на то, что мы разворачиваем проект на специальной виртуальной машине, рекомендуется работать в виртуальной изолированной среде. Это помогает создать повторяемое и предсказуемое окружение для выполнения проекта. А еще — позволяет избежать проблемы несовместимости различных библиотек в проекте.
Создадим виртуальное окружение следующими командами:
mkdir ~/testproject && cd ~/testproject
python3 -m venv venv
source venv/bin/activate
Убедимся в активации виртуального окружения: проверим, что после выполнения последней команды в терминале слева от имени пользователя появилась надпись (venv).
Выйти из окружения можно при помощи команды deactivate.
Установка Django, Gunicorn и psycopg2
После активации виртуальной среды установим в ней необходимые пакеты и зависимости:
pip install django gunicorn psycopg2-binary
Здесь psycopg2 — это специальный адаптер для связи Django c PostgreSQL, который включает API-спецификацию баз данных для Python.
Создание проекта на Django
Пришло время создать Django-проект. Для этого вводим команду, которая создаст внутри папки testproject всю базовую структуру проекта, включая основные файлы и каталоги.
django-admin startproject testproject .
Настройка проекта
За настройки проекта отвечает файл settings.py. Он содержит конфигурацию базы данных, статических файлов, безопасности и локализации. В файле мы укажем ранее созданные параметры для подключения к PostgreSQL, настроим разрешения по подключению и укажем порт для соединения с БД.
Открываем файл settings.py и приводим блок DATABASES к следующему виду:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydb',
'USER': 'myuser',
'PASSWORD': 'mypassword',
'HOST': 'localhost',
'PORT': '5432',
}
}
Также не забываем в settings.py прописать STATIC_ROOT для указания места, куда Django сложит статические файлы:
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
В поле ALLOWED_HOSTS указываем адреса или домены, которым разрешено устанавливать соединение с Django-приложением:
ALLOWED_HOSTS = [ ‘first_address_or_domain_name’, ‘second_address_or_domain_name’ ]
После редактирования файла настроек применяем изменения в базе данных через миграции и создаем суперпользователя для входа в админ-панель Django:
python manage.py migrate
python manage.py createsuperuser
Из этой панели мы можем решить большинство задач, которые могут появиться при администрировании сайта или приложения. Например, создать пользователя, изменить отображение разделов или поменять права.
Создание файлов сокета и systemd
Теперь можем перейти к сокету Gunicorn и systemd-юниту. Сначала создадим сокет. Он понадобится для передачи данных между процессами внутри нашей системы.
Например, мы бы могли передавать HTTP-запросы на конкретный порт для связи Gunicorn и Nginx. Однако сокет позволит уменьшить затрату ресурсов на обработку запросов и вместе с тем упростит конфигурацию нашего проекта.
В директории /etc/systemd/system/ создадим файл gunicorn.socket:
[Unit]
Description=Gunicorn socket
[Socket]
ListenStream=/run/gunicorn.sock
[Install]
WantedBy=sockets.target
Теперь перейдем к созданию systemd-юнита — конфигурационного файла, в котором мы описываем имя, зависимости, выполняемые команды и все остальные сопутствующие параметры для запуска процесса в менеджере системы современных дистрибутивов Linux.
Для этого в директории /etc/systemd/system/ создаем файл gunicorn.service:
[Unit]
Description=Gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=user
Group=www-data
WorkingDirectory=/home/user/testproject
ExecStart=/home/user/testproject/venv/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/run/gunicorn.sock \
testproject.wsgi:application
[Install]
WantedBy=multi-user.target
Не забудьте указать правильный путь к своему проекту и имя пользователя.
Активация сокета и проверка systemd
Мы создали необходимые конфигурационные файлы для systemd, теперь пришло время активации юнитов:
systemctl enable {gunicorn.socket,gunicorn.service}
systemctl start {gunicorn.socket,gunicorn.service}
Первой командой мы задаем системе директиву активировать сервис при загрузке системы, второй — запускаем сервис. Проверить, что сервис успешно запущен, можно командой:
systemctl status gunicorn
Если в выводе видно, что сервис в состоянии active (running), то все сделано верно.
Настройка Nginx
Приступим к настройке другого ключевого игрока нашего приложения — Nginx. Он может выполнять разные роли: от почтового сервера до балансировщика нагрузки. В рамках статьи Nginx будет выступать в качестве прокси-сервера.
Устанавливаем Nginx:
apt install nginx
Теперь переходим к его настройке. Создадим конфигурационный файл командой
vim /etc/nginx/sites-available/testproject
Внутри файла укажем настройки прокси-сервера:
server {
listen 80; # порт, который сервер прослушивает для входящих соединений
server_name server_address_or_domain_name; # адрес или домен, по которому будет доступен сервер
location = /favicon.ico { access_log off; log_not_found off; } # указываем серверу игнорировать проблемы, связанные со значком веб-страницы
location /static/ { # определяем расположение статичных файлов нашего проекта
root /home/user/testproject;
}
location / { # задаем параметр перенаправления всех запросов на созданный gunicorn socket
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
}
После создания конфигурации мы, наконец, можем запустить прокси-сервер. Для начала создадим символическую ссылку на файл с нашей конфигурацией в директории /etc/nginx/sites-enabled:
ln -s /etc/nginx/sites-available/testproject /etc/nginx/sites-enabled
Теперь проверим, правильно ли сконфигурирован Nginx:
nginx -t
После выполнения команды в терминале должно отобразиться следующее:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Если что-то пошло не так, перепроверьте конфиг на ошибки в синтаксисе. Если с конфигурацией все в порядке, запускаем наш прокси-сервер:
systemctl restart nginx
Запуск проекта
Следующим шагом перезапускаем Gunicorn-сервис. При повторном запуске он применит все изменения и запустит Django-проект. Как вы уже, наверное, запомнили, делается это через systemctl:
systemctl restart gunicorn
Открываем браузер и заходим по адресу или домену нашего сервера. В случае правильной настройки вы увидите приветственную страницу Django.
Ранее мы создавали superuser для входа в административную панель Django. Теперь у вас появился доступ к панели по адресу http://server_address_or_domain_name/admin/.
Получение SSL/TLS-сертификата
Перед публикацией приложения в сеть рекомендуется получить и установить SSL/TLS-сертификат. Уже давно работа веб-сайтов и приложений по HTTPS является актуальным стандартом — это помогает обеспечить шифрование трафика и защиту данных.
Самый простой способ получения сертификата — установить утилиту Certbot от Let’s Encrypt. Если вы решили завернуть весь свой проект в контейнеры, можете воспользоваться Docker-образом для Certbot. Но мы пойдем классическим путем:
apt install certbot python3-certbot-nginx -y
Запустим получение сертификата и автоматически обновим конфигурацию Nginx.
certbot --nginx -d example.com -d www.example.com
certbot install –nginx
Вместо example.com укажите доменное имя вашего сервера.
Let’s Encrypt выдает сертификаты сроком действия 90 дней, по истечении этого периода сертификат нужно обновить. Этот механизм направлен на повышение безопасности, чтобы с заданной периодичностью обновлялись ключи сертификата.
Проверим автоматическое обновление сертификата командой:
certbot renew --dry-run
Заключение
Теперь вы знаете, как развернуть Django-проект при помощи Nginx и Gunicorn. Если у вас еще нет готового проекта, но уже хочется научиться пользоваться фреймворком Django, можете обратить внимание на курс от Selectel «Разработка на Django для новичков».
И не останавливайтесь на обучении. Дальше — больше: тюнинг веб-сервера, масштабирование приложения и повышение отказоустойчивости при помощи нескольких инстансов и балансировщика. Но об этом мы расскажем в другой раз.