Настройка Nginx и Gunicorn для Django-проекта - от установки Python до SSL

Настройка 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).

Выполняем код — видим venv.
Выполняем код — видим 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), то все сделано верно.

В терминале появилось active.

Настройка 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 для новичков».

И не останавливайтесь на обучении. Дальше — больше: тюнинг веб-сервера, масштабирование приложения и повышение отказоустойчивости при помощи нескольких инстансов и балансировщика. Но об этом мы расскажем в другой раз.