2026-09-18
Развертывание Django проекта на NGINX в Ubuntu (uWSGI + MariaDB)

Развертывание Django проекта на NGINX в Ubuntu (uWSGI + MariaDB)

Развёртывание Django-приложения разбивается на два этапа:

  1. Установка и настройка среды Python и uWSGI;
  2. Настройка веб-сервера NGINX.

Дополнительно рассмотрим подключение к MariaDB/MySQL.


Python, Django и uWSGI

apt-get install nginx uwsgi python3 uwsgi-plugin-python3 python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools
pip3 install virtualenv uwsgi django

Создаём каталоги для статики и медиа:

mkdir -p /var/www/my_app/static /var/www/my_app/media
chown www-data.www-data /var/www/my_app/media
chown www-data.www-data /var/www/my_app/static

Копируем приложение в /var/www/my_app. Примерная структура:

/var/www/my_app/
|-- app1
|   |-- __init__.py
|   |-- admin.py
|   |-- apps.py
|   |-- migrations/
|   |-- models.py
|   |-- static/
|   |-- templates/
|   |-- urls.py
|   |-- views.py
|-- my_app
|   |-- __init__.py
|   |-- asgi.py
|   |-- settings.py
|   |-- urls.py
|   |-- wsgi.py
|-- manage.py
|-- db.sqlite3

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

vi /var/www/my_app/my_app/settings.py
ALLOWED_HOSTS = ['www.example.com']

DATABASES = {
    'default': {
        # ...
    }
}

STATIC_ROOT = '/var/www/my_app/static'
MEDIA_ROOT = '/var/www/my_app/media'

где:

  • ALLOWED_HOSTS — разрешённые доменные имена сайта;
  • DATABASES — подключение к базе данных;
  • STATIC_ROOT / MEDIA_ROOT — каталоги статики и пользовательских файлов.

Собираем статику:

cd /var/www/my_app
python3 manage.py collectstatic

Настраиваем uWSGI:

vi /etc/uwsgi/apps-enabled/my_app.ini
[uwsgi]
chdir = /var/www/my_app
env = DJANGO_SETTINGS_MODULE=my_app.settings
wsgi-file = my_app/wsgi.py
max-requests = 5000
plugins = python3
processes = 5
threads = 2
master = true
die-on-term = true
socket = /run/uwsgi/my_app.sock
chmod-socket = 660
vacuum = true
uid = www-data
gid = www-data

где:

  • chdir — каталог проекта;
  • env — модуль настроек Django;
  • wsgi-file — путь до wsgi.py;
  • processes/threads — воркеры;
  • socket — сокет для связи с NGINX;
  • uid/gid — пользователь процесса.

Исправлены опечатки оригинала: guigid, chdir без ведущего слеша.

systemctl restart uwsgi

Настройка NGINX

vi /etc/nginx/conf.d/my_app.conf
server {
    listen 80;
    server_tokens off;
    server_name my_app my_app.domain.local;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:/run/uwsgi/my_app.sock;
    }

    location /static/ {
        alias /var/www/my_app/static/;
    }

    location /media/ {
        alias /var/www/my_app/media/;
    }
}
systemctl restart nginx

Подключение к базе данных MariaDB/MySQL

MariaDB

apt-get install mariadb-server
systemctl enable mariadb
mysqladmin -u root password

Django требует кодировку UTF-8. Правим конфигурацию клиента:

vi /etc/mysql/mariadb.conf.d/50-client.cnf
[mysql]
...
default-character-set = utf8mb4
vi /etc/mysql/mariadb.conf.d/50-mysql-clients.cnf
[mysql]
...
default-character-set = utf8mb4

Современная рекомендация — utf8mb4 (полный Unicode, включая эмодзи); utf8 в MySQL/MariaDB — это 3-байтовый вариант.

vi /etc/mysql/mariadb.conf.d/50-server.cnf
character-set-server = utf8mb4
collation_server = utf8mb4_unicode_ci
systemctl restart mariadb

Подготовка базы данных

Создайте базу, пользователя и выдайте права (см. инструкции по созданию БД и настройке прав).

Модуль для Python

apt-get install libmysqlclient-dev
pip3 install mysqlclient

Первая команда — библиотеки для сборки, вторая — клиент MySQL для Python.

Настройка подключения

vi /var/www/my_app/my_app/settings.py

Меняем sqlite на MySQL:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'database_name',
        'HOST': 'localhost',
        'USER': 'db_user',
        'PASSWORD': 'db_password',
        'OPTIONS': {'charset': 'utf8mb4'},
    }
}

где:

  • NAME — имя базы;
  • HOST — сервер БД;
  • USER — пользователь с правами на базу;
  • PASSWORD — пароль пользователя.

Проверка выборки

from django.db import connection
cursor = connection.cursor()
cursor.execute("SELECT * FROM users")
print(cursor.fetchall())

Пример извлекает всё содержимое таблицы users и выводит на экран.


Тонкости и подводные камни

  • utf8 vs utf8mb4 — для полного Unicode (эмодзи, редкие символы) используйте utf8mb4.
  • Сокет uWSGI — путь в uwsgi.ini и uwsgi_pass в NGINX должны совпадать.
  • uid/gid — в оригинальной инструкции была опечатка gui; правильный параметр — gid.
  • collectstatic — запускать после изменения STATIC_ROOT; статику отдаёт NGINX, а не Django.
  • ALLOWED_HOSTS — при обращении по IP или другому домену добавьте его, иначе 400 Bad Request.
  • mysqlclient — требует заголовков MySQL; при ошибках сборки ставьте default-libmysqlclient-dev или pkg-config.
  • uwsgi-plugin-python3 — обязателен, иначе uWSGI не запустит Python-приложение.
  • Права на mediawww-data должен иметь запись, иначе загрузка файлов упадёт.

Шпаргалка

apt-get install nginx uwsgi python3 uwsgi-plugin-python3 python3-pip python3-dev build-essential
pip3 install virtualenv uwsgi django mysqlclient
mkdir -p /var/www/my_app/{static,media}
# settings.py: ALLOWED_HOSTS, DATABASES, STATIC_ROOT, MEDIA_ROOT
python3 manage.py collectstatic
# /etc/uwsgi/apps-enabled/my_app.ini -> socket, chdir, wsgi-file
# /etc/nginx/conf.d/my_app.conf -> uwsgi_pass unix:/run/uwsgi/my_app.sock
systemctl restart uwsgi nginx

Проверено на: Ubuntu 22.04/24.04 + Django 5, uWSGI, MariaDB 10.11+.
Дата: Сентябрь 2026.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *