Настройка сервера с помощью uWSGI и Nginx на Debian 9

lepiloff

Oct. 27, 2017, 8:47 a.m.

В этой статье я раскажу, как установить и настроить компоненты Nginx и uWsgi в системе Debian 8 (9), для поддержки и администрирования приложения на Dlango. На Ubuntu 16 не проверял, но по-идее ничем не отличается. В итоге мы получим рабочий проект на на нашем собственном VDS - сервере.

Для того, что бы начать настройку у нас должен быть установлен свежий Debian  c пользователем (не root) добавленным в sudo группу. Как это сделать можно прочитать в этой статье. Далее будет установлено виртуальное окружение, создан проект на Django, установлен и сконфигурирован uWSGI сервер и Nginx.

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

sudo apt-get update
sudo apt-get upgrade

 

Установка и настройка VirtualEnv и VirtualEnwWrapper

Проект устанавливаем в свое собственное виртуальное окружение, для изолирования его зависимостей от других проектов. Для этого установим модуль virtualenv, который содержит исходники Python и модуль virtualenvwrapper, предоставляющий некоторые дополнительный возможности для работы с virtualenv. Здесь и далее код будет приводиться для работы с Python 3. Оба компонента установим с помощью pip - пакетного менеджера Python. В Debian pip не является предустановленным пакетом, установим его самостоятельно

sudo apt-get install python3-pip

Теперь у нас есть pip  и мы можем выполнить глобальную установку virtualenv  и virtualenvwrapper

sudo pip3 install virtualenv virtualenvwrapper

После установки необходимо сконфигурировать наш shell для работы с virtualenvwrapper.

echo "export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3" >> ~/.bashrc
echo "export WORKON_HOME=~/Env" >> ~/.bashrc
echo "source /usr/local/bin/virtualenvwrapper.sh" >> ~/.bashrc
source ~/.bashrc

Теперь у нас в корневой дирректории появилась папка Env в которой будут храниться виртуальные окружения наших будущих проектов.

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

Для своего первого проекта мы создадим виртуальное окружение, используя команду из модуля virtualenvwrapper

mkvirtualenv mysite

Это создаст и активирует виртуальное окружение (ВО), установит в него Python и pip. Понять, что виртуальное окружение активировано можно по появившемуся в начале командной строки терминала имени вашего ВО, что то вроде (mysite)user@hostname:~$. Все установки, выполненные в ВО будут локальны и не оказываю влияние на другие
проекты.

Установка Django и создание проекта 

Вариант 1

(mysite)$ pip install django

 После того как Django установлен, можно перейти к созданию проекта. 

(mysite)$ django-admin.py startproject projectname

Эта команда создаст папку projectname в корневом каталоге, внутри которой будет еще один каталог с таким же именем  и главный управляющий файл manage.py


Вариант 2

Если проект уже существует на Github, то можно очень просто перенести его на сервер выполнив

(mysite)$ git clone https://github.com/yourname/projectname.git

Заходим в папку с проектом

(mysite)$ cd ~/projectname

Устанавливаем зависимости из файла requirements.txt

pip install -r requirements.txt

Либо выполняем чистую установку django как в первом варианте

 

Базу данных нового проекта можно выбрать из PostgreSQL либо MySQL. Я в своих пректах использую PostgreSQl, как ее установить и настроить можно почитать здесь

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

(mysite)$ cd ~/projectname

И последовательно введем

(mysite)$ python manage.py makemigrations
(mysite)$ python manage.py migrate

Осталось создать супеюзера для входа в панель администратора сайта. Надо будет ввести имя администратора и пароль для входа в учетную запись.

(mysite)$ python manage.py createsuperuser

В файле settings.py  в поле ALLOWED_HOSTS надо добавить IP-адрес нашего сайта(выдается хостером), либо доменное имя

ALLOWED_HOSTS = [ 'example.com', '103.0.113.9']

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

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

И выполнить команду, которая соберет все статические файлы пректа в одной папке static в корневой директории

(mysite)$ python manage.py collectstatic

Что бы протестировать проделанные установки и настройки  введите в виртуальном окружении команду

(mysite)$ ./manage.py runserver 0.0.0.0:8080

Это запустит сервер для разработки на порту 8080, откройте ваш сайт в боаузере по адресу

http://server_domain_or_IP:8080

где server_domain_or_IP - имя вашего домена или его IP адрес, выданный хостером. Если все сделано правильно, откроется окно приветствия. Посде того, как мы убедились в работоспособности проекта, закроем локальный сервер и перейдем к настройке uWSGI и Nginx.

 

Установка uWSGI

Мы будем устанавливать uWSGI глобально, это позволит в дальнейшем  управлять несколькими проектами на Django. Для начала установим python пакет python-dev.

sudo apt-get install python3-dev

Теперь все готово для установки uWSGI через pip

sudo pip3 install uwsgi

Создание конфигурационных файлов

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

sudo mkdir -p /etc/uwsgi/sites
cd /etc/uwsgi/sites 

В этой папке создадаи файл с расширением .ini и откроем его в текстовом редакторе

sudo nano projectname.ini

Содержимое файла должно начинаться с заголовка [uwsgi], вся остальная информация сдедует за ним. Также мы будем использовать переменные, для того чтобы сделать файл более универсальным в использовании. После заголовка добавим переменную project со значением идентичным названию вашего проекта. Далее следует переменная uid, которая содержит имя sudo-юзера. Также необходимо добавить переменную base, содержащую путь к домашнему каталогу пользователя. Будем использовать конструкцию  %(variable_name). В конечном итоге получим структуру
/etc/uwsgi/sites/projectname.ini

[uwsgi]
project = projectname
uid = username
base = /home/%(uid)  

На основании этих переменных продолжим дополнять файл

chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application
master = true
processes = 5

Теперь нужно настроить прослушивание соединений. Ранее для тестирования uWSGI использовались HTTP и сетевой порт, но есть варианты и получше. Например, вместо порта можно использовать сокет. Этот вариант безопаснее и обеспечивает более высокую производительность. Сокеты используют не HTTP, а uwsgi – быстрый бинарный протокол для взаимодействия uWSGI с другими серверами. Nginx имеет встроенную поддержку uwsgi при проксировании. Также следует изменить права на сокет. Опция vacuum автоматически очистит файл сокета после остановки сервиса.
В итоге получаем файл 

[uwsgi]
project = projectname
uid = username
base = /home/%(uid)
chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application
master = true
processes = 5
socket = /run/uwsgi/%(project).sock
chown-socket = %(uid):www-data
chmod-socket = 660
vacuum = true

Настройка проекта завершена, сохраните и закройте файл.

Системный Unit-файл для uWSGI

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

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

Файл начинается с раздела [Unit], в котором хранятся метаданные и другая информация о сервисе (например, его описание).

[Unit]
Description=uWSGI Emperor service

Затем добавьте раздел [Service]. Директива ExecStartPre запускает указанные в ней компоненты. В данном случае она создаст каталог /run/uwsgi, принадлежащий текущему пользователю и группе www-data.

Директива ExecStart запускает сервис, в данном случае uwsgi в режиме Emperor mode. Также нужно добавить компоненты, необходимые для поддержки процесса system. 
Теперь осталось добавить раздел [Install]. Он отвечает за автоматический запуск сервиса. Настройте сервис для работы в многопользовательской системе.

[Unit]
Description=uWSGI Emperor service
[Service]
ExecStartPre=/bin/bash -c 'mkdir -p /run/uwsgi; chown username:www-data /run/uwsgi'
ExecStart=/usr/local/bin/uwsgi --emperor /etc/uwsgi/sites
Restart=always
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all
[Install]
WantedBy=multi-user.target

Сохраните и закройте файл.

Пока что запустить этот сервис невозможно, поскольку он зависит от пользователя www-data. Сервис будет доступен после установки и настройки Nginx.

 

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

После того, как uwsgi установлен и запущен остается только установить и сконфигурировать прокси-сервер Nginx. Это делается привычном нам способом

sudo apt-get install nginx

Когда Nginx установлен, мы создаем конфигурационный файл  для нашего проекта.

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

Внутрь него мы добавим блок server, в котором укажем номер порта и доменное имя по которому наш сайт будет доступен.

server {
    listen 80;
    server_name projectname.com www.projectname.com;
}

Следующим шагом, укажем nginx игнорировать сообщение об ошибке если фавикон не будет найден. Так же мы добавим расположение папки статических файлов.

server {
    listen 80;
    server_name projectname.com www.projectname.com;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /home/username/projectname;
    }

Добавим блок location для обслуживания всех остальных запросов. Добавьте параметры uwsgi из файла /etc/nginx/uwsgi_params и передайте трафик на сокет:

server {
    listen 80;
    server_name projectname.com www.projectname.com;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /home/username/projectname;
    }
    location / {
include         uwsgi_params;
uwsgi_pass      unix:/run/uwsgi/projectname.sock;
}
    

На этом конфигурирование закончено и мы можем сохранить и закрыть файл.

Далее создадим ссылки на новый конфигурационный файл в Nginx директорриии sites-enabled 

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

Проверим правильность синтаксиса

sudo nginx -t

Если получим такой вывод: 

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

То у нас все впорядке мы можем перезагрузить Nginx

sudo systemctl restart nginx

И запустить сервер приложений uWSGI

sudo systemctl start uwsgi

Если вы используете ufw, добавьте следующие строки

sudo ufw delete allow 8080
sudo ufw allow 'Nginx Full'

Для того чтобы оба сервиса при загрузке стартовали автоматически добавьте

sudo systemctl enable nginx
sudo systemctl enable uwsgi 

debian, django, nginx, uwsgi, ubuntu