Установка uWSGI и настройка Nginx для Django-проектов

Просмотры: 1366
Категория: Администрирование
Создано: 24 ноября 2020
Тэги: CentOS Linux Python

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

python manage.py runserver

Однако для реального "боевого" сервера нужно решение понадежнее. Чаще всего выбирают связку Nginx + uWSGI. Как нам говорит Википедия uwsgi - веб-сервер и сервер веб-приложений, первоначально реализованный для запуска приложений Python через протокол WSGI. В свою очередь WSGI (Web Server Gateway Interface) - стандарт взаимодействия между Python-программой, выполняющейся на стороне сервера, и самим веб-сервером. В этой заметке я рассматриваю как развернуть uWSGI на сервере (CentOS 7). Предполагается, что Nginx уже установлен, также предполагается, что установлен Python 3. Если он ставился из исходников, то исполняемые файлы лежат, скорее всего, в /usr/local/bin. Исходя из всего этого, давайте установим uWSGI в нашу систему.

Прежде всего установим сам сервис

sudo pip3 install uwsgi

Проверяем установку. Для этого создадим файл test.py следующего содержания

def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [b"Hello World"]

И тестируем uWSGI

uwsgi --http :8000 --wsgi-file test.py

В браузере (или с помощью curl) переходим по адресу ourserver.com:8000. Если видим надпись "Hello, World", значит установка прошла успешно.

Подготавливаем Django-проект. Загружаем наши файлы на сервер или через FTP, или ещё лучше используя Git. Пусть наш сайт располагается в каталоге /home/django/mysite. Запускаем виртуальное окружение (из домашней директории /home/django)

source mysite/venv/bin/activate

Переходим в каталог сайта и создаём директории для статики и медиа:

cd mysite

mkdir media

mkdir static

Редактируем файл settings.py

vim mysite/mysite/settings.py

Прописываем пути к статике и медиа:

STATIC_URL='/static/'
STATIC_ROOT='/home/django/mysite/static'

MEDIA_URL='/media/'
MEDIA_ROOT='/home/django/mysite/media'

Делаем миграцию, собираем статику, создаём суперпользователя и запускаем тестовый сервер:

cd mysite

python manage.py migrate

python manage.py collectstatic

python manage.py createsuperuser

python manage.py runserver

Проверяем работу сервера по адресам http://127.0.0.1:8000 и http://127.0.0.1/admin/. Должно всё работать. Если что-то идёт не так, читаем внимательно вывод python об ошибках и исправляем их. Останавливаем сервер и деактивируем виртуальное окружение.

deactivate

С прицелом на то, что у нас будет несколько сайтов с uwsgi, запускать uwsgi будем в режиме императора. Настройки для каждого сайта будем хранить в отдельном каталоге /etc/uwsgi/vassals. Создаём его

sudo mkdir -p /etc/uwsgi/vassals

Создаём конфигурационный файл для императора

sudo vim /etc/uwsgi/emperor.ini

следующего содержания

[uwsgi]
emperor = /etc/uwsgi/vassals
vassals-inherit = /etc/uwsgi/vassal-default.ini
uid = www-data
gid = www-data

Конфигурационные файлы для каждого сайта будем складывать в директорию /etc/uwsgi/vassals. Об этом говорит первая строчка этого файла. Вторая говорит о том, что для каждого вассала общие параметры нужно брать из файла /etc/uwsgi/vassal-default.ini . Создаём его

sudo vim /etc/uwsgi/vassal-default.ini

И наполняем следующим содержанием:

[uwsgi]

autoload = true

master = true
workers = 2
no-orphans = true

pidfile = /run/uwsgi/%N.pid
socket = /run/uwsgi/%N.socket
chmod-socket = 660

logto = /var/log/uwsgi/%N.log
log-date = true

Директории для pid-файла и сокета можно изменить на другие. Важно лишь установить для соответствующих каталогов нужные права на запись и чтение. Наконец, в /etc/uwsgi/vassals создаём файл конфигурации нашего сайта:

sudo vim /etc/uwsgi/vassals/mysite.ini

Наполняем его приблизительно следующим содержанием:

[uwsgi]
virtualenv = /home/django/mysite/venv
chdir = /home/django/mysite/mysite
pythonpath = ..
env = DJANGO_SETTINGS_MODULE=mysite.settings
wsgi-file = mysite/wsgi.py
workers = 1

Теперь нужно создать файл для управления сервисом uwsgi с помощью системного демона systemd.

sudo vim /etc/systemd/system/emperor.uwsgi.service

Записываем приблизительно следующее:

[Unit]
Description=uWSGI Emperor
After=syslog.target

[Service]
ExecStart=/usr/local/bin/uwsgi --ini /etc/uwsgi/emperor.ini
RuntimeDirectory=uwsgi
User=www-data
Group=www-data
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all

[Install]
WantedBy=multi-user.target

И запускаем сервис uwsgi:

sudo systemctl start emperor.uwsgi

Проверяем статус запущенного сервиса:

sudo systemctl status emperor.uwsgi

Если есть какие-то ошибки - исправляем. Как правило ошибки возникают из-за неправильных прав на каталоги и файлы, которые uwsgi использует в своей работе. Если всё прошло хорошо и ошибки исправлены, переходим к последнему действию - настройке nginx.

sudo vim /etc/nginx/conf.d/mysite.conf

и наполняем его таким содержанием, внося поправки для своего сайта:

server {
    server_name mysite.yourserver.com;  # пишем свой реальный адрес
 
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    access_log /var/log/nginx/mysite.access.log;
    error_log /var/log/nginx/mysite.error.log;

    ssl_certificate /etc/nginx/nginx.crt;  # пишем сюда пути к сертификатам
    ssl_certificate_key /etc/nginx/nginx.key;

    location /static/ {
            alias /home/django/mysite/static/; # реальный путь к статическим файлам
    }

    location / {
            include uwsgi_params;
            uwsgi_pass      unix:/tmp/mysite.socket; # путь к сокету
    }


    error_page 404 /index.php;
}

И не забываем в своем django-проекте в файле settings.py прописать в списке ALLOWED_HOSTS доменное имя своего реального сайта. Проверяем конфигурацию nginx:

sudo nginx -t

Если ошибок обнаружено не было, перезапускаем nginx

sudo systemctl restart nginx

и через браузер проверяем работу своего сайта. В конце ставим uwsgi на автоматический запуск при загрузки системы:

sudo systemctl enable uwsgi

Система готова к работе. Если в django-проект вносятся в дальнейшем изменения, не забываем перезапускать императора uwsgi.