В этой статье я раскажу, как установить и настроить компоненты 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