Развернуть Django на VPS с нуля: пошаговая инструкция
К концу инструкции у вас будет сайт на Django, работающий на VPS через Gunicorn и Nginx, доступный по вашему домену. На всё уйдёт около полутора-двух часов, если не считать регистрацию домена.

К концу этой инструкции ваш проект на Django будет открываться в браузере по домену или IP-адресу, отдаваться через Nginx и переживать перезагрузку сервера — процесс запустится сам через systemd. Всё делается на чистом Ubuntu-сервере (VPS), команды даны для Ubuntu 22.04 LTS и Django 5.x. Если у вас Debian 12 — команды почти те же, отличаются мелочи в именах пакетов.
Речь именно про VPS, а не про виртуальный хостинг вроде «shared». На дешёвом shared-хостинге Django чаще всего не запустить нормально: там нет доступа к systemd и своей версии Python. Берите VPS — минимальной конфигурации (1 CPU, 1 ГБ RAM) для учебного проекта хватит.
Что нужно иметь до начала
Проверьте это прямо сейчас, чтобы не упереться в середине:
- VPS с Ubuntu 22.04 и root-доступом или пользователем с
sudo. IP-адрес сервера у вас должен быть. - SSH-клиент. На macOS и Linux это встроенный терминал, на Windows — PowerShell или PuTTY.
- Готовый проект Django в репозитории (GitHub, GitLab) либо локально. Если проекта нет — ниже создадим пустой.
- Домен — по желанию. Без домена сайт откроется по IP. Если домен есть, заранее направьте A-запись на IP сервера у регистратора (это отдельная тема, здесь не разбираем).
Термины WSGI и Gunicorn встретятся ниже — пояснение к ним в сноске в конце.
Шаг 1. Подключиться к серверу и обновить систему
Подключитесь по SSH, подставив свой IP:
ssh root@ВАШ_IP_СЕРВЕРАОбновите список пакетов и сами пакеты:
sudo apt update && sudo apt upgrade -yПроверка: команды отработали без красных строк с ERR. Если система предложит перезагрузку — сделайте sudo reboot и подключитесь заново через минуту.
Шаг 2. Поставить Python, pip и Nginx
Ubuntu 22.04 идёт с Python 3.10 — для Django 5.x это подходит (нужен минимум 3.10). Ставим модуль виртуального окружения и веб-сервер:
sudo apt install python3-pip python3-venv nginx -yПроверка: команда python3 --version покажет версию 3.10.x, а nginx -v — версию Nginx.
Шаг 3. Создать пользователя и папку проекта
Работать под root — плохая привычка. Заведите отдельного пользователя (замените django на любое имя):
sudo adduser django
sudo usermod -aG sudo django
su - djangoДальше всё делаем от его имени. Перейдите в домашнюю папку и создайте каталог проекта:
cd ~
mkdir myproject && cd myprojectШаг 4. Настроить виртуальное окружение и установить Django
Создайте и активируйте окружение:
python3 -m venv venv
source venv/bin/activateПосле активации в начале строки терминала появится (venv). Установите Django и Gunicorn:
pip install django gunicornЕсли проект уже есть — скопируйте его сюда (через git clone или scp) и поставьте зависимости командой pip install -r requirements.txt. Если проекта нет, создайте пустой для проверки:
django-admin startproject config .Проверка: в папке появился файл manage.py и каталог config.
Шаг 5. Разрешить домен и собрать статику
Django по умолчанию не пускает запросы с чужих хостов. Откройте файл настроек config/settings.py и найдите ALLOWED_HOSTS. Впишите туда IP и домен:
ALLOWED_HOSTS = ['ВАШ_IP_СЕРВЕРА', 'example.com']В самом низу файла добавьте строку, куда собирать статические файлы (если её ещё нет):
import os
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')Примените миграции и соберите статику:
python manage.py migrate
python manage.py collectstatic --noinputПроверка: появилась папка staticfiles, а migrate создал файл db.sqlite3 (для учебного проекта SQLite подойдёт; для боевого берите PostgreSQL — это отдельная настройка).
Шаг 6. Проверить, что Gunicorn поднимает проект
Запустите вручную, чтобы убедиться, что приложение живое. Замените config на имя каталога, где лежит wsgi.py:
gunicorn --bind 0.0.0.0:8000 config.wsgiПроверка: в браузере откройте http://ВАШ_IP_СЕРВЕРА:8000 — увидите либо стартовую страницу Django с ракетой, либо ваш проект. Стили пока не подхватятся — так и должно быть, статику отдаст Nginx позже. Остановите Gunicorn сочетанием Ctrl+C.
Если страница на порту 8000 открылась — самое сложное позади. Дальше только обвязка, чтобы процесс не падал и работал по обычному 80-му порту.
Шаг 7. Настроить автозапуск через systemd
Чтобы Gunicorn запускался сам и перезапускался при падении, опишем службу. Создайте файл:
sudo nano /etc/systemd/system/gunicorn.serviceВставьте содержимое, подставив своё имя пользователя и путь к проекту:
[Unit]
Description=gunicorn daemon for Django
After=network.target
[Service]
User=django
Group=www-data
WorkingDirectory=/home/django/myproject
ExecStart=/home/django/myproject/venv/bin/gunicorn \
--workers 3 \
--bind unix:/home/django/myproject/gunicorn.sock \
config.wsgi:application
[Install]
WantedBy=multi-user.targetЗдесь Gunicorn слушает не TCP-порт, а Unix-сокет — так Nginx общается с ним быстрее и без выхода в сеть. Включите и запустите службу:
sudo systemctl daemon-reload
sudo systemctl start gunicorn
sudo systemctl enable gunicornПроверка: sudo systemctl status gunicorn покажет зелёное active (running). В папке проекта появится файл gunicorn.sock.
Шаг 8. Настроить Nginx как фронт
Nginx принимает запросы на 80-м порту, отдаёт статику сам, а всё остальное передаёт Gunicorn через сокет. Создайте конфиг сайта:
sudo nano /etc/nginx/sites-available/myprojectВставьте, подставив свой домен или IP в server_name и свои пути:
server {
listen 80;
server_name example.com ВАШ_IP_СЕРВЕРА;
location /static/ {
alias /home/django/myproject/staticfiles/;
}
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://unix:/home/django/myproject/gunicorn.sock;
}
}Включите сайт, отключите дефолтный и проверьте синтаксис:
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl restart nginxПроверка: nginx -t ответит syntax is ok и test is successful. Откройте http://ВАШ_IP_СЕРВЕРА без порта — сайт открылся, стили на месте.
Открыть порты, если сайт не грузится
Если у вас включён файрвол ufw, разрешите Nginx:
sudo ufw allow 'Nginx Full'
sudo ufw allow OpenSSHУ многих провайдеров есть ещё и внешний файрвол в панели управления — проверьте, что там открыты порты 80 и 443.
Если не получилось
Самые частые проблемы новичков и что с ними делать:
- 502 Bad Gateway. Nginx не достучался до Gunicorn. Проверьте
sudo systemctl status gunicorn— служба должна быть running. Частая причина: неверный путь к сокету в конфиге Nginx или у Nginx нет прав войти в домашнюю папку пользователя. Смотритеsudo tail /var/log/nginx/error.log. - DisallowedHost at /. Домен или IP не вписан в
ALLOWED_HOSTS. Добавьте, сохраните и перезапустите:sudo systemctl restart gunicorn. - Стили не грузятся, сайт без оформления. Не совпал путь в
location /static/с реальнымSTATIC_ROOT, либо вы забылиcollectstatic. Проверьте, что папкаstaticfilesсуществует и путь вaliasзаканчивается слэшем. - ModuleNotFoundError при старте Gunicorn. Неверное имя модуля в
config.wsgi:application. Загляните, как называется каталог с файломwsgi.py, и подставьте это имя. - Сайт вообще не открывается, браузер крутит. Порт закрыт файрволом провайдера или
ufw. Откройте порты, как в разделе выше.
Что делать дальше
Рабочий минимум готов, но для боевого сайта не хватает трёх вещей. Первое — HTTPS: поставьте бесплатный сертификат Let's Encrypt через утилиту certbot, она сама допишет конфиг Nginx. Второе — вынесите секретный ключ и DEBUG=False из settings.py в переменные окружения: с DEBUG=True на проде вы показываете посетителям трассировку с внутренностями. Третье — если проект серьёзнее учебного, переезжайте с SQLite на PostgreSQL.
После настройки следите за одним показателем в первую очередь — потреблением памяти: три воркера Gunicorn на 1 ГБ RAM могут упереться в лимит, тогда система начнёт убивать процессы. Смотрите free -m и логи journalctl -u gunicorn.
Редактор изображений: Убрать лишнее, заменить фон, добавить объект, расширить кадр — на вашем изображении.
Спросить за 20 ₽Источники: Django documentation — How to deploy with WSGI (Gunicorn), Gunicorn documentation
Частые вопросы
У меня Python 3.12, а не 3.10. Инструкция подойдёт?
Что делать, если после перезагрузки сервера сайт не открылся?
Можно ли обойтись без Nginx и запускать только Gunicorn?
SQLite подойдёт для настоящего сайта?
Я получаю 400 Bad Request вместо сайта. Что не так?
Как обновить проект после изменений в коде?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.