Настройка веб сервера для Python, Django, Nginx, Mysql (MariaDB)

Настройка веб сервера для Python, Django, Nginx, Mysql (MariaDB)

В данной статье рассмотрим процесс настройки веб сервера Nginx для запуска на нем фреймворка Django, написанного на языке Python. Использовать будем ОС, Ubuntu 20.04. В качестве СУБД будет Mysql(MariaDB)

Содержание

Введение

Один из наиболее популярных фреймворков, с точки зрения безопасности  - это Django. 
Django написан на языке Python и применяется такими известными проектами как Instagram, WatchApp. Разработка сайта на нём удобна и компактна. Но при выводе проекта в продакшн часто возникают проблемы. Ни каждый программист знаком с настройкой веб сервера СУБД и т.д.
Именно для таких людей эта статья. Последовательность действий проверена и точно работает. Можно использовать как пошаговое руководство. Настройки сделаны с учетом рекомендаций разработчиков.      

 

Описание тестового стенда

  • ОС Ubuntu Desktop 20.04
  • СУБД MariaDB
  • Веб сервер Nginx
  • Фреймворк Django 3.2
  • Python 3

План работ. Краткое описание действий

  1. Обновить список пакетов
  2. Установить и настроить Mysql(MariaDB)
  3. Установить pip, Python 3 и virtualenv  
  4. Создать и активировать виртуальное окружение 
  5. Установить Django, Gunicorn и адаптер(mysqlclient) для подключения к MariaDB
  6. Настроить Django (settings.py)
  7. Проверка работы Django и Gunicron
  8. Настроить запуск службы и сокета Gunicron
  9. Установка и настройка веб сервера Nginx

Обновление пакетов

Первым делом обновим список пакетов

sudo apt update

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

sudo apt install mariadb-server

 После установки запустим скрипт настройки сервера MariaDB

sudo mysql_secure_installation

 

Во время настройки:

  • Установим пароль для пользователя root (Change the root password?)
  • Удалим анонимных пользователей (Remove anonymous users?)
  • Отключим удаленный логин через учетную запись root (Disallow root login remotely?)
  • Удалим тестовую базу данных (Remove test database and access to it?)
  • Перезапустим привилегии для их активации (Reload privilege tables now?)

После начальной настройки создадим пользователя и базу данных для нашего проекта Django

Подключаемся к MariaDB

sudo mariadb

 Создаём пользователя django-user, базу данных djangodb. Назначаем пользователю djangouser права на БД djangodb

CREATE DATABASE djangobd CHARACTER SET UTF8;
CREATE USER djangouser@localhost IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON djangobd.* TO djangouser@localhost;
FLUSH PRIVILEGES;
exit

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

Устанавливаем pip, Python 3 и virtualenv

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

sudo apt install python3 python3-pip python3-dev python3-virtualenv curl libmysqlclient-dev

Создаём и активируем виртуальное окружение для нашего проекта Django

Наш проект будем создавать в домашнем каталоге пользователя, который был создан специально для проекта Django. В нашем случаи это user

Создаём каталог djandodir и переходим в него

mkdir ~/djangodir
cd ~/djangodir

В этом каталоге будем хранить наши проекты и статические файлы. 
Создаем виртуальную среду env с помощью virtualenv и активируем её

virtualenv env
source env/bin/activate

Обратите внимание после активации командная строка изменится на:
(env)user@host:~/djangodir$

После активации можно переходить к установке нужных нам пакетов: django, gunicorn, mysqlclient.

Устанавливаем Django, Gunicorn и адаптер(mysqlclient)

В виртуальном окружении устанавливаем Django, Gunicorn и адаптер(mysqlclient)

pip install django gunicorn mysqlclient

mysqlclient нужен для подключения Django к созданной ранее базы данных MariaDB (djangobd)

Создание проекта Django и его настройка

После подготовки сервера СУДБ и виртуального окружения можно переходить к созданию проекта Django. Для примера просто установим базовую версию Django. Будет доступна стартовая страница и админка

Создаем проект Django

django-admin.py startproject mydjango ~/djangodir

Обратите внимание, что мы создаём проект mydjango в каталоге djangodir

Настраиваем Django

Настройка происходит в файле ~/djangodir/mydjango/settings.py

nano ~/djangodir/mydjango/settings.py

Заполняем директиву ALLOWED_HOSTS

Тут нужно указать адрес с которого будет отвечать сервер.
Например: localhost, 127.0.0.1, itobereg.ru, 192.168.0.2
В нашем случаи укажем:

ALLOWED_HOSTS = ['localhost','127.0.0.1','192.168.0.122']

Заполняем директиву DATABASES

В нашем случае мы используем коннектор для MariaDB (django.db.backends.mysql), имя БД (djangobd), пользователь и пароль (djangouser, password)

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'djangobd',
        'HOST': 'localhost',
        'USER': 'djangouser',
        'PASSWORD': 'password',
    }
}

Заполняем директиву TIME_ZONE

TIME_ZONE = 'Asia/Yekaterinburg'

После директивы STATIC_URL = '/static/' добавляем строку

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

Эта строка указывает где будут храниться статические файлы, такие как css, js и т.д.
Это нужно для того чтобы веб сервер Nginx мог их обрабатывать напрямую.
После этого запускаем стандартные скрипты Django для создания и настройки БД

~/djangodir/manage.py makemigrations
~/djangodir/manage.py migrate

 Создаём администратора Django

~/djangodir/manage.py createsuperuser

Создаём каталог static и переносим туда статические фалы из проекта. В нашем случаи это будут файлы для админки Django

~/djangodir/manage.py collectstatic

Проверяем работу Django, запустив сервер разработки

~/djangodir/manage.py runserver 0.0.0.0:8000

После этого проект Django должен быть доступен по адресу http://server_domain_or_IP:8000
Если все работает, завершаем работу сервера разработки и переходим к проверке Gunicron

Проверка работы Gunicron

Нам нужно убедиться что Gunicron может обслуживать наше приложение Django. Для этого запустим модуль WSGI нашего проекта.

cd ~/djangodir
gunicorn --bind 0.0.0.0:8000 mydjango.wsgi

Обратите внимание на то как мы указали название файла mydjango.wsgi (файл называется wsgi.py)
После запуска мы так же как и на прошлом шаге должны иметь возможность зайти на веб страницу Django.
Если всё работает нажимаем Ctrl+C и завершаем работу Gunicron

После этого выходим из виртуальной среды

deactivate

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

Создание сокета и службы для запуска Gunicron  

На данный момент у нас есть рабочий проект на Django и рабочий Gunicron. Следуя рекомендациям разработчиков Gunucron, создадим сокет, который будет слушать подключения к серверу и запускать по необходимости Gunicron.

Создание сокета gunicorn.socket

Создаём файл /etc/systemd/system/gunicorn.socket

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

В файл gunicorn.socket прописываем следующее

[Unit]
Description=gunicorn socket

[Socket]
ListenStream=/run/gunicorn.sock

[Install]
WantedBy=sockets.target

В этом файле мы создали три раздела:

  • [Unit] - описание
  • [Socket] - указываем расположение сокета
  • [Install] - описываем установку сокета

Создание файла службы gunicorn.service

Создаём файл /etc/systemd/system/gunicorn.service

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

Обратите внимание, имена службы и сокета должны быть одинаковые (gunicorn.socket и gunicorn.service)

В файл gunicorn.service прописываем следующее

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

[Service]
User=user
Group=www-data
WorkingDirectory=/home/user/djangodir
ExecStart=/home/user/djangodir/env/bin/gunicorn \
          --access-logfile - \
          --workers 3 \
          --bind unix:/run/gunicorn.sock \
          mydjango.wsgi:application

[Install]
WantedBy=multi-user.target

Обратите внимание мы запускаем службу от пользователя user, которого специально для этого создали.
Не запускает службу от пользователя root - это очень вредный и небезопасный совет (используется во многих инструкциях в интернете)

Запуск и активация сокета gunicorn.socket

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

После успешного запуска будет создан файл сокета /run/gunicorn.sock если файл не создался значит сокет на запустился и нужно искать ошибку. Это можно сделать с помощью команды journalctl

sudo journalctl -u gunicorn.socket

Если сокет запустился (создался файл /run/gunicorn.sock) переходим к проверке работы службы gunicorn.service
На данный момент служба находится в неактивном состоянии так как нет обращения на сокет. Это можно увидеть запустив проверку статуса

sudo systemctl status gunicorn

В ответ мы получим: Active: inactive (dead)

Gunicorn.service Active: inactive (dead)
Gunicorn.service Active: inactive (dead)


Чтобы служба стала активна нужно обратиться на сокет. Для этого мы используем утилиту Curl 

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

После этого снова проверим статус службы gunicorn

sudo systemctl status gunicorn
Gunicorn.service Active: active (running)
Gunicorn.service Active: active (dead)

Статус должен стать: Active: active (running)

Если все получилось переходим к установке и настройке веб сервера Nginx. Если возникают ошибки изучаем файл журналов и исправляем ошибки.

sudo journalctl -u gunicorn

Обратите внимание. После любого изменений в файле gunicorn.service нужно обязательно перезапустить демона и gunicron

sudo systemctl daemon-reload
sudo systemctl restart gunicorn

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

Устанавливаем веб сервер Nginx

sudo apt install nginx

 После установки создаем файл настроек /etc/nginx/sites-available/mydjango

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

Добавляем в него следующие настройки

server {
    listen 80;
    server_name 192.168.0.122;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /home/user/djangodir;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/run/gunicorn.sock;
    }
}

сохраняем и активируем наш файл с настройками

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

 Проверяем на ошибки созданный нами файл конфигурации

sudo nginx -t

Если ошибок нет, перезапускаем веб сервер Nginx

sudo systemctl restart nginx

 После того как Nginx перезагрузится должен появится доступ к нашему проекту Django по указанному ip адресу (в нашем случаи это 192.168.0.122)