Home » Настройка Django с Postgres, Nginx и Gunicorn на Ubuntu
Настройка Django с Postgres, Nginx и Gunicorn на Ubuntu

Настройка Django с Postgres, Nginx и Gunicorn на Ubuntu

Разворачивание Django-приложения на продакшене — это такая штука, которая может превратиться в настоящий квест для разработчика. Особенно когда дело касается связки Django + PostgreSQL + Nginx + Gunicorn на Ubuntu. Казалось бы, что может пойти не так? Но практика показывает, что подводных камней здесь хватает.

Эта статья — это твой практический гайд по настройке полноценного продакшн-окружения для Django. Мы разберём архитектуру, пройдём все этапы установки и конфигурации, а также рассмотрим типичные проблемы и способы их решения. Никаких “поверхностных” инструкций — только проверенные команды, реальные конфиги и практические советы.

Как это работает: архитектура связки

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

В нашей связке каждый компонент выполняет свою роль:

  • Nginx — веб-сервер, который принимает HTTP-запросы от клиентов, обрабатывает статику и проксирует динамические запросы к Gunicorn
  • Gunicorn — WSGI-сервер, который запускает Django-приложение в нескольких процессах
  • Django — твоё приложение, которое генерирует динамический контент
  • PostgreSQL — база данных для хранения данных приложения

Поток запроса выглядит так: Клиент → Nginx → Gunicorn → Django → PostgreSQL

Компонент Роль Преимущества Альтернативы
Nginx Reverse proxy, статика Высокая производительность, малое потребление памяти Apache, Caddy
Gunicorn WSGI-сервер Простота настройки, стабильность uWSGI, Waitress
PostgreSQL База данных ACID, расширения, производительность MySQL, SQLite

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

Для начала нам нужен сервер с Ubuntu. Если у тебя его ещё нет, можешь заказать VPS или выделенный сервер.

Обновляем систему и устанавливаем базовые пакеты:

sudo apt update
sudo apt upgrade -y
sudo apt install -y python3 python3-pip python3-venv git curl wget nginx

Создаём пользователя для приложения (это хорошая практика безопасности):

sudo adduser --system --group --home /opt/myapp myapp
sudo usermod -a -G www-data myapp

Установка и настройка PostgreSQL

PostgreSQL — это мощная объектно-реляционная СУБД, которая отлично подходит для Django. Устанавливаем её:

sudo apt install -y postgresql postgresql-contrib python3-psycopg2
sudo systemctl start postgresql
sudo systemctl enable postgresql

Создаём базу данных и пользователя для Django:

sudo -u postgres psql

В консоли PostgreSQL выполняем:

CREATE DATABASE myapp_db;
CREATE USER myapp_user WITH PASSWORD 'your_strong_password';
ALTER ROLE myapp_user SET client_encoding TO 'utf8';
ALTER ROLE myapp_user SET default_transaction_isolation TO 'read committed';
ALTER ROLE myapp_user SET timezone TO 'UTC';
GRANT ALL PRIVILEGES ON DATABASE myapp_db TO myapp_user;
\q

Важно: Замени ‘your_strong_password’ на реально сильный пароль. Можешь сгенерировать его командой:

openssl rand -base64 32

Подготовка Django-приложения

Переходим в директорию приложения и создаём виртуальное окружение:

sudo mkdir -p /opt/myapp
sudo chown myapp:myapp /opt/myapp
sudo -u myapp -i
cd /opt/myapp
python3 -m venv venv
source venv/bin/activate

Устанавливаем Django и необходимые пакеты:

pip install django gunicorn psycopg2-binary

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

django-admin startproject myproject .

Настраиваем settings.py для продакшена. Создаём файл settings/production.py:

mkdir -p myproject/settings
touch myproject/settings/__init__.py
touch myproject/settings/production.py

Содержимое production.py:

from .base import *

DEBUG = False
ALLOWED_HOSTS = ['your-domain.com', 'www.your-domain.com', 'server-ip']

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'myapp_db',
        'USER': 'myapp_user',
        'PASSWORD': 'your_strong_password',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

STATIC_URL = '/static/'
STATIC_ROOT = '/opt/myapp/static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = '/opt/myapp/media/'

# Безопасность
SECURE_SSL_REDIRECT = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True

Выполняем миграции и собираем статику:

python manage.py migrate --settings=myproject.settings.production
python manage.py collectstatic --settings=myproject.settings.production --noinput

Настройка Gunicorn

Gunicorn — это Python WSGI HTTP Server для UNIX. Он служит интерфейсом между Django и веб-сервером. Создаём конфигурационный файл:

nano /opt/myapp/gunicorn.conf.py

Содержимое файла:

bind = "127.0.0.1:8000"
workers = 3
worker_class = "sync"
worker_connections = 1000
max_requests = 1000
max_requests_jitter = 100
timeout = 30
keepalive = 2
preload_app = True
daemon = False
user = "myapp"
group = "myapp"
tmp_upload_dir = None
errorlog = "/opt/myapp/logs/gunicorn_error.log"
accesslog = "/opt/myapp/logs/gunicorn_access.log"
access_log_format = '%({X-Real-IP}i)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"'

Создаём директорию для логов:

mkdir -p /opt/myapp/logs

Тестируем запуск Gunicorn:

cd /opt/myapp
source venv/bin/activate
gunicorn myproject.wsgi:application -c gunicorn.conf.py --settings=myproject.settings.production

Если всё работает, создаём systemd-сервис для автозапуска:

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

Содержимое сервиса:

[Unit]
Description=Gunicorn instance to serve myapp
After=network.target

[Service]
User=myapp
Group=myapp
WorkingDirectory=/opt/myapp
Environment="PATH=/opt/myapp/venv/bin"
Environment="DJANGO_SETTINGS_MODULE=myproject.settings.production"
ExecStart=/opt/myapp/venv/bin/gunicorn myproject.wsgi:application -c /opt/myapp/gunicorn.conf.py
ExecReload=/bin/kill -s HUP $MAINPID
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target

Запускаем и включаем сервис:

sudo systemctl daemon-reload
sudo systemctl start myapp
sudo systemctl enable myapp
sudo systemctl status myapp

Настройка Nginx

Nginx будет выступать в роли reverse proxy и обрабатывать статические файлы. Создаём конфигурацию сайта:

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

Содержимое конфигурации:

server {
    listen 80;
    server_name your-domain.com www.your-domain.com;
    
    client_max_body_size 100M;
    
    location = /favicon.ico { access_log off; log_not_found off; }
    
    location /static/ {
        alias /opt/myapp/static/;
        expires 30d;
        add_header Cache-Control "public, no-transform";
    }
    
    location /media/ {
        alias /opt/myapp/media/;
        expires 7d;
        add_header Cache-Control "public, no-transform";
    }
    
    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_connect_timeout 30s;
        proxy_send_timeout 30s;
        proxy_read_timeout 30s;
    }
}

Активируем конфигурацию:

sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Настройка SSL с Let’s Encrypt

Для продакшена обязательно нужен SSL. Устанавливаем Certbot:

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.com -d www.your-domain.com

Настраиваем автоматическое обновление сертификатов:

sudo crontab -e

Добавляем строку:

0 2 * * * /usr/bin/certbot renew --quiet

Мониторинг и логирование

Для отслеживания работы приложения настроим ротацию логов:

sudo nano /etc/logrotate.d/myapp

Содержимое:

/opt/myapp/logs/*.log {
    daily
    missingok
    rotate 52
    compress
    delaycompress
    notifempty
    create 644 myapp myapp
    postrotate
        systemctl reload myapp
    endscript
}

Типичные проблемы и их решения

Проблема Симптом Решение
502 Bad Gateway Nginx не может подключиться к Gunicorn Проверь статус сервиса myapp, логи Gunicorn
Статика не загружается CSS/JS файлы возвращают 404 Проверь права доступа к директории static
Медленная работа БД Долгие запросы к PostgreSQL Настрой индексы, оптимизируй запросы
Высокая нагрузка Большое потребление CPU/RAM Увеличь количество workers в Gunicorn

Оптимизация производительности

Для улучшения производительности можно применить несколько трюков:

  • Настройка PostgreSQL — отредактируй /etc/postgresql/*/main/postgresql.conf
  • Кеширование — используй Redis для кеширования Django
  • Компрессия — включи gzip в Nginx
  • CDN — используй CDN для статических файлов

Пример оптимизации PostgreSQL:

sudo nano /etc/postgresql/12/main/postgresql.conf

Добавь строки:

shared_buffers = 256MB
effective_cache_size = 1GB
maintenance_work_mem = 64MB
checkpoint_completion_target = 0.9
wal_buffers = 16MB
default_statistics_target = 100
random_page_cost = 1.1

Автоматизация деплоя

Создай простой скрипт для автоматического деплоя:

nano /opt/myapp/deploy.sh

Содержимое скрипта:

#!/bin/bash
cd /opt/myapp
source venv/bin/activate
git pull origin main
pip install -r requirements.txt
python manage.py migrate --settings=myproject.settings.production
python manage.py collectstatic --settings=myproject.settings.production --noinput
sudo systemctl restart myapp
sudo systemctl reload nginx
echo "Deploy completed successfully!"

Сделай скрипт исполняемым:

chmod +x /opt/myapp/deploy.sh

Альтернативные решения

Хотя связка Django + PostgreSQL + Nginx + Gunicorn является стандартом де-факто, существуют и другие варианты:

  • uWSGI вместо Gunicorn — более гибкий, но сложнее в настройке
  • Apache с mod_wsgi — классическое решение, но менее производительное
  • Docker-контейнеры — упрощает деплой, но добавляет слой абстракции
  • Kubernetes — для enterprise-решений с высокой нагрузкой

Интересный факт: Gunicorn был создан в 2010 году как форк Ruby-сервера Unicorn, адаптированный для Python. Название расшифровывается как “Green Unicorn” и отсылает к использованию greenlet для асинхронности.

Заключение и рекомендации

Настройка Django с PostgreSQL, Nginx и Gunicorn — это проверенное временем решение, которое обеспечивает стабильную работу приложения в продакшене. Главные преимущества этой связки:

  • Высокая производительность и стабильность
  • Хорошая масштабируемость
  • Богатая экосистема и документация
  • Активное сообщество и поддержка

Рекомендую использовать эту связку для большинства Django-проектов. Для небольших проектов с низкой нагрузкой можно обойтись более простыми решениями, а для высоконагруженных систем стоит рассмотреть контейнеризацию и оркестрацию.

Помни о регулярном обновлении компонентов, мониторинге производительности и создании резервных копий. Безопасность — это не опция, а обязательное требование для любого продакшн-окружения.

Полезные ссылки для дальнейшего изучения:


В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.

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

Leave a reply

Your email address will not be published. Required fields are marked