Как установить Django, Nginx и Gunicorn на виртуальный сервер

    Команда Simple-Server
    03.06.2026
    13 мин

    Материал подготовлен командой Simple-Server для администраторов VPS и выделенных серверов. Команды и пути проверяйте на тестовой машине перед production.

    Кратко о задаче

    Рекомендуем для экспериментов в рамках изучения материала развернуть отдельную виртуальную машину, арендованную у провайдера Simple-Server. Главное, чтобы на ней сразу же была инсталлирована свежая операционная система Ubuntu с базовыми настройками файрвола и созданным пользователем с привилегиями sudo.

    Настройки из инструкции не рекомендуется выполнять под пользователем root — мы будем описывать работу именно под пользователем с привилегиями sudo.

    Инсталлируем пакеты из репозитория Ubuntu

    Первоначально скачаем обновления пакетов apt, чтобы пользоваться их актуальными релизами. Следом загрузим Python 3:

    sudo apt update sudo apt install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx curl

    Команда установит pip, файлы Python, дальше на их основе мы развернем Gunicorn, СУБД**** PostgreSQL и установим библиотеки, какие понадобятся для работы с Django, а также веб-сервер Nginx.

    Создадим БД и аккаунт в PostgreSQL

    В системе Postgres стандартно применяется аутентификация «peer authentication». Такой подход позволяет обходиться без ввода логина-пароля, если название аккаунта операционки совпадает с пользователем самой базы данных. При желании можно использовать sudo, для этого передадим его системе путем ввода команды:

    Теперь в диалоговом окне PostgreSQL создадим базу данных под свой проект:

    CREATE DATABASE myproject;

    Следом пользователя с надежным паролем:

    CREATE USER myprojectuser WITH PASSWORD 'password';

    Чтобы упростить дальнейшую работу, сразу зададим ряд настроек. Например, изменим кодировку на UTF-8, зададим схему изоляции транзакций «read committed», установим часовой пояс:

    ALTER ROLE myprojectuser SET client_encoding TO 'utf8'; ALTER ROLE myprojectuser SET default_transaction_isolation TO 'read committed'; ALTER ROLE myprojectuser SET timezone TO 'UTC';

    Теперь для нового пользователя надо открыть доступ на администрирование БД:

    GRANT ALL PRIVILEGES ON DATABASE myproject TO myprojectuser;

    По завершении настройки закроем диалоговое окно PostgreSQL.

    Настройка СУБД Postgres завершена, идем дальше.

    Создадим виртуальную среду Python

    Нам понадобится доступ к использованию команды virtualenv, его мы получим через pip:

    sudo -H pip3 install --upgrade pip sudo -H pip3 install virtualenv

    После инсталляции сделаем новый каталог, где будут размещены проектные модули, и сразу зайдем туда:

    mkdir ~/myprojectdir cd ~/myprojectdir

    И развернем виртуальную среду Python:

    Команда сделает подпапку myprojectenv, куда локально будет инсталлирована версия – Python и pip. После инсталляции проведем активацию:

    source myprojectenv/bin/activate

    После ввода последней команды строка поменяет вид, она показывает: пользователь теперь будет вводить команды в виртуальной среде. Примерный вариант окна:

    (myprojectenv)user@host:~/myprojectdir$

    Теперь пришло время для установки Django, Gunicorn и адаптера psycopg2 PostgreSQL:

    pip install django gunicorn psycopg2-binary

    Обязательные для работы компоненты установлены.

    Сделаем свой проект Django и настроим его

    Складывать файлы будем в ранее указанный каталог. В нем система сделает отдельную папку для размещения фактического кода, скрипта управления:

    django-admin startproject myproject ~/myprojectdir

    Команда явно задает название каталога ~/myprojectdir.

    Поменяем настройки проекта

    Запустим конфигурационный файл на редактирование:

    nano ~/myprojectdir/myproject/settings.py

    В самый верх файла добавьте:

    Далее необходимо найти директиву ALLOWED_HOSTS. Ей определены адреса, разрешенные для соединения с экземпляром Django. Запросы остальных хостов будут отклонены автоматически. Здесь надо перечислить нужные IP или домены, ограничив их квадратными скобками.

    ALLOWED_HOSTS = ['your_server_domain_or_IP', 'second_domain_or_IP', . . ., 'localhost']

    Следом перейдите в раздел, начинающийся со слова DATABASES. В нем мы поменяем назначение базы данных на PostgreSQL. Также зададим условие использовать адаптер psycopr2, имя самой БД, а также пользователя с паролем.

    DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'myproject', 'USER': 'myprojectuser', 'PASSWORD': 'password', 'HOST': 'localhost', 'PORT': '', } }

    Остается в «хвосте» внести параметр, фиксирующий место, где хранить статичные файлы. Это понадобится для Nginx, который мы настроим в паре с PostgreSQL.

    STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, 'static/')

    При закрытии файла обязательно согласитесь с сохранением изменений.

    Завершим задачу настройки

    Скопируем изначальную схему БД:

    ~/myprojectdir/manage.py makemigrations ~/myprojectdir/manage.py migrate

    Создадим аккаунт, администрирующий проект:

    ~/myprojectdir/manage.py createsuperuser

    Придумайте имя, пароль и укажите актуальный email. Если планируется собирать весь статичный контент в одной папке, укажите ее явно:

    ~/myprojectdir/manage.py collectstatic

    Команда потребует подтверждения, после чего файлы переместятся в папку static. Зададим возможность подключения в брандмауэре UFW:

    По умолчанию указанный порт заблокирован, как и остальные, еще незадействованные.

    Далее запустим сервер разработки Django, выполнив команду:

    ~/myprojectdir/manage.py runserver 0.0.0.0:8000

    Теперь можно проверить указанный в настройках IP или домен путем ввода в адресную строку браузера:

    http://server_domain_or_IP:8000

    Если откроется страница индекса Django, то все работает. Сразу лучше добавить к адресу путь/admin и пробно зайти в систему под заданным именем-паролем. После аутентификации будет предоставлен доступ к панели администратора. Можно закрывать терминал, где мы производили настройку нажатием комбинации < Ctrl+C>.

    Создадим файлы сокета и systemd для Gunicorn

    Сокет Gunicorn появляется при старте systemd, после чего прослушивает подключения. Но сначала создадим файл с привилегиями sudo:

    sudo nano /etc/systemd/system/gunicorn.socket

    В нем мы сделаем новый раздел [Unit], куда внесем описательную часть сокета, раздел [Socket], при помощи которого определим его размещение и [Install] для обеспечения установки в указанное время:

    [Unit] Description=gunicorn socket [Socket] ListenStream=/run/gunicorn.sock [Install] WantedBy=sockets.target

    При закрытии файла обязательно согласитесь на сохранение изменений. Перейдем к служебному файлу systemd. Его также надо создать и открыть на редактирование:

    sudo nano /etc/systemd/system/gunicorn.service

    Начнем с раздела [Unit], где укажем метаданные и зависимости – описание службы, предписание инициализировать ее только после подтверждения связи с хостом.

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

    Перейдем к разделу [Service]. В нем зададим пользовательскую учетку и группу, под которой планируем запускать процесс. В этом материале укажем в качестве владельца пользователя, потому что он таковым формально и является. Зададим группу www-data, карту рабочей папки и команду, запускающую службы. В качестве примера используем 3 процесса:

    [Unit] Description=gunicorn daemon Requires=gunicorn.socket After=network.target [Service] User=user Group=www-data WorkingDirectory=/home/user/myprojectdir ExecStart=/home/user/myprojectdir/myprojectenv/bin/gunicorn \ --access-logfile - \ --workers 3 \ --bind unix:/run/gunicorn.sock \ myproject.wsgi:application

    В «хвосте» внесем раздел [Install]. В нем будем хранить информацию, куда systemd привязывать эти службы, если они будут активированы при загрузке.

    [Unit] Description=gunicorn daemon Requires=gunicorn.socket After=network.target [Service] User=user Group=www-data WorkingDirectory=/home/user/myprojectdir ExecStart=/home/user/myprojectdir/myprojectenv/bin/gunicorn \ --access-logfile - \ --workers 3 \ --bind unix:/run/gunicorn.sock \ myproject.wsgi:application [Install] WantedBy=multi-user.target

    Все, можно закрывать файл с сохраненными изменениями. Попробуем стартовать сокет Gunicorn:

    sudo systemctl start gunicorn.socket sudo systemctl enable gunicorn.socket

    Проверим файл сокета Gunicorn

    Статус процесса и сам факт того, получилось ли у него стартовать, можно проверить командой:

    sudo systemctl status gunicorn.socket

    Обязательно убедитесь, что файл gunicorn.sock присутствует в папке /run:

    Результат проверки будет выведен на экран:

    /run/gunicorn.sock: socket

    Если при старте systemctl status выпала ошибка – в папке /run нет guricorn.sock – это сигнализирует, что сокет Gunicorn фактически не создан. Выяснить причину поможет журнал:

    sudo journalctl -u gunicorn.socket

    Перед повторным запуском рекомендуем проверить содержимое разделов, которые мы вносили выше – не закралась ли там ошибка.

    Диагностируем активацию сокета

    Важно учитывать, что при запуске gunicorn.socket служба gunicorn.service неактивна. Проверить это можно командой:

    sudo systemctl status gunicorn gunicorn.service - gunicorn daemon Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled) Active: inactive (dead)

    Продиагностируем активацию сокета установлением коннекта через curl:

    curl --unix-socket /run/gunicorn.sock localhost

    Если данные отображаются в HTML-формате, все отлично – Gunicorn стартовал и готов обслуживать программы на Django. Проверим службу командой:

    sudo systemctl status gunicorn

    Если при выводе отражаются ошибки, искать первопричину надо начинать с журнала:

    sudo journalctl -u gunicorn

    Также желательно вручную сверить содержимое файла gunicorn.service. Можно перезапустить демона для повторного считывания данных по Gunicorn:

    sudo systemctl daemon-reload sudo systemctl restart gunicorn

    До устранения любых ошибок продолжать дальше нельзя.

    Настроим Nginx как прокси для Gunicorn

    Сначала сделаем и откроем модуль в папке Nginx sites-available:

    sudo nano /etc/nginx/sites-available/myproject

    Запустим редактирование файла и внесем инструкцию прослушивать порт 80, отвечать на домен или IP-адрес нашего хоста:

    server { listen 80; server_name server_domain_or_IP; }

    Следующим шагом зададим инструкцию игнорировать любые проблемы, связанные с поиском favicon. И укажем, где расположены статичные ресурсы, перенесенные нами ранее в каталог по пути ~/myprojectdir/static.

    server { listen 80; server_name server_domain_or_IP; location = /favicon.ico { access_log off; log_not_found off; } location /static/ { root /home/user/myprojectdir; } }

    Последним шагом создадим блок location / {}, который задаст соответствие любым запросам. В него внесем файл proxy_params, поставляемый в типовом наборе Nginx. Тогда поступающие данные будут перекидываться прямо в сокет.

    Закроем файл с сохранением изменений. И активируем его путем привязки к папке sites-enabled:

    sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled

    Также на этом этапе добавим пользователя www-data в группу текущего пользователя. Для этого выполним:

    sudo usermod -a -G ${USER} www-data

    Продиагностируем Nginx на предмет ошибок в синтаксисе:

    Если все работает без перебоев, перезапустим веб-сервер:

    sudo systemctl restart nginx

    По завершении настройки Django с Postgres и Nginx правило доступа к серверу разработки через порт 8000 можно удалять, потому что весь трафик будет направляться на порт 80:

    sudo ufw delete allow 8000 sudo ufw allow 'Nginx Full'

    Теперь для пробы можно подключиться к нашему хосту по домену или напрямую через IP-адрес. Но перед началом реальной разработки рекомендуем защитить трафик при помощи протокола SSL/TSL. Ведь по умолчанию вся информация передается по сети без шифрования, включая и пароли (в простом текстовом формате).

    Простейший вариант – установить сертификат от Let’s Encrypt. Его возможностей достаточно для защиты информации, передаваемой в обе стороны, на хост и с хоста разработчика.


    Нужен сервер для практики? Арендуйте VPS/VDS в России — root-доступ, NVMe, DDoS-защита и поддержка 24/7.

    VPS для проекта

    VPS с root-доступом, NVMe и поддержкой 24/7 на Simple-Server.

    StarterVDS

    490₽

    в месяц

    1 ядро

    1 ГБ RAM

    20 ГБ NVMe

    • 1 IPv4
    • KVM
    • Root-доступ
    • Безлимитный трафик
    Заказать VPS
    Рекомендуем

    PerformanceVDS

    1190₽

    в месяц

    2 ядра

    4 ГБ RAM

    60 ГБ NVMe

    • 1 IPv4
    • KVM
    • Root-доступ
    • Базовая DDoS-защита
    Заказать VPS

    Нужна другая конфигурация или чистый VPS без панели?

    Все тарифы VPS

    Похожие статьи, которые могут быть вам интересны