Django – это производительный веб-фреймворк для разработки приложений или сайтов в Python. Django также предоставляет простой сервер разработки для локального тестирования кода.
Примечание: Для производства необходимо искать более безопасный и мощный веб-сервер, так как этот сервер не справится с трафиком в режиме производства.
Данное руководство поможет установить и настроить в CentOS 7 все компоненты, необходимые для поддержки приложения и обработки клиентских запросов. Для этого будет использоваться сервер приложений uWSGI и обратный прокси-сервер Nginx.
Требования
Для выполнения данного руководства нужно предварительно настроить сервер CentOS 7 и создать не-root пользователя с доступом к sudo. Подробные инструкции по начальной настройке сервера и создании пользователей можно найти здесь.
Фреймворк Django в данном руководстве будет установлен в два разных виртуальных окружения Python, что позволит удовлетворить все индивидуальные требования каждого приложения.
После запуска приложения нужно настроить сервер приложений uWSGI, который будет использоваться в качестве интерфейса приложения и переформатировать запросы HTTP в вызовы Python. После этого нужно настроить обратный прокси-сервер Nginx.
Установка и настройка VirtualEnv и VirtualEnvWrapper
Проекты Django будут установлены в индивидуальное виртуальное окружение. Для этого нужно установить инструменты virtualenv (создаёт виртуальную среду Python) и virtualenvwrapper (добавляет несколько полезных функций virtualenv).
Для установки инструментов используйте pip, пакетный менеджер Python. Установить pip можно из репозитория EPEL. Сначала включите EPEL:
sudo yum install epel-release
Теперь можно установить pip:
sudo yum install python-pip
Теперь выполните глобальную установку virtualenv и virtualenvwrapper.
sudo pip install virtualenv virtualenvwrapper
Теперь можно настроить оболочку с помощью сценария virtualenvwrapper. Все виртуальные окружения будут помещены в каталог Env в домашнем каталоге. Чтобы настроить это, используется переменная WORKON_HOME. Добавьте её в сценарий инициализации оболочки.
echo "export WORKON_HOME=~/Env" >> ~/.bashrc
echo "source /usr/bin/virtualenvwrapper.sh" >> ~/.bashrc
Чтобы иметь доступ к новым функциям в текущей сессии, выполните команду:
source ~/.bashrc
Теперь в домашнем каталоге есть каталог Env, в котором хранятся виртуальные окружения проектов.
Создание проекта Django
Теперь нужно создать два виртуальных окружения и запустить два проекта.
Создание первого проекта Django
Создайте виртуальное окружение с помощью команд, доступных благодаря инструменту virtualenvwrapper.
Чтобы создать первое виртуальное окружение, введите:
mkvirtualenv firstsite
Эта команда создаст виртуальное окружение по имени firstsite, а также установит локальную версию Python и pip, которые можно использовать для создания изолированной среды разработки проекта. Командная строка изменится, указывая, что текущей средой является виртуальная среда Python
(firstsite)user@hostname:~$
В скобках указано имя текущего виртуального окружения. Теперь всё программное обеспечение, загруженное с помощью pip, будет установлено в индивидуальное окружение первого проекта и никак не повлияет на общее состояние системы.
Сначала нужно установить Django:
pip install django
Теперь создайте первый тестовый проект:
cd ~
django-admin.py startproject firstsite
Эта команда создаст в домашнем каталоге каталог firstsite. В нём хранится сценарий для управления новым проектом и ещё один одноимённый каталог, в котором будет находиться код проекта.
Откройте каталог первого уровня:
cd ~/firstsite
Для начала нужно переместить БД, чтобы инициализировать базу данных SQLite для проекта.
Примечание: При желании можно создать базу данных для приложения самостоятельно, но это выходит за рамки данного руководства.
./manage.py migrate
Теперь в домашнем каталоге есть файл БД по имени db.sqlite3. Создайте администратора.
./manage.py createsuperuser
Выберите имя пользователя, укажите контактный адрес электронной почты, а затем выберите и подтвердите пароль.
Затем откройте файл настроек проекта:
nano firstsite/settings.py
Теперь нужно создать отдельный каталог для хранения статических файлов сайта. Так Nginx сможет обслуживать их напрямую, а это улучшит производительность. Поместите каталог static в корневом каталоге проекта. Добавьте в конец конфигурационного файла следующую строку:
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
Сохраните и закройте файл. Соберите статические файлы в этом каталоге:
./manage.py collectstatic
В каталоге проекта появится новый каталог static.
Теперь протестируйте проект, временно запустив сервер разработки.
./manage.py runserver 0.0.0.0:8080
Это запустит сервер разработки на порт 8080. В браузере посетите свой домен или IP:
http://server_domain_or_IP:8080
На экране должна появиться такая страница:
It worked!
Congratulations on your first Django-powered page. [...]
Добавьте в ссылку сегмент /admin, чтобы получить доступ к форме аутентификации администратора. Введите учётные данные администратора, и на экране появится панель управления.
После этого можно остановить сервер разработки. Нажмите CTRL-C в терминале. Теперь можно приступать к разработке второго проекта.
Разработка второго проекта
Второй проект создаётся точно так же, как первый.
Вернитесь в домашний каталог и создайте второе виртуальное окружение. Установите Django.
cd ~
mkvirtualenv secondsite
pip install django
После этого откроется окружение нового проекта.
Создайте второй проект и откройте его каталог:
django-admin.py startproject secondsite
cd ~/secondsite
Инициализируйте базу данных и создайте пользователя с правами администратора:
./manage.py migrate
./manage.py createsuperuser
Откройте файл settings:
nano secondsite/settings.py
Добавьте каталог статических файлов строку:
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
Сохраните и закройте файл. Соберите статические файлы в этот каталог.
./manage.py collectstatic
Запустите сервер разработки:
./manage.py runserver 0.0.0.0:8080
Сайт будет доступен по ссылке:
http://server_domain_or_IP:8080
Ссылка на интерфейс администратора:
http://server_domain_or_IP:8080/admin
Чтобы остановить сервер, нажмите CTRL-C.
Отключение виртуального окружения
Теперь нужно отключить виртуальное окружение, поскольку разработка проектов завершена:
deactivate
Чтобы вернуться в виртуальное окружение любого из проектов, введите:
workon firstsite
или
workon secondsite
В дальнейшей работе виртуальное окружение не нужно, потому отключите его:
deactivate
Сервер приложений uWSGI
Теперь нужно настроить uWSGI – сервер приложений, взаимодействующий с приложениями с помощью простого интерфейса WSGI.
Примечание: Больше информации о uWSGI можно найти в этом руководстве.
Установка uWSGI
В данном руководстве нужно установить uWSGI глобально – так будет проще обрабатывать несколько проектов Django.
Установите зависимости сервера:
sudo yum install python-devel gcc
Теперь установите uWSGI.
sudo pip install uwsgi
Чтобы быстро протестировать сервер, передайте ему данные одного из сайтов. Например, можно попробовать обслужить первый проект:
uwsgi --http :8080 --home /home/user/Env/firstsite --chdir /home/user/firstsite -w firstsite.wsgi
Теперь uWSGI использует виртуальное окружение каталога ~/Env, чтобы получить доступ к каталогу проекта и использовать файл wsgi.py для обслуживания проекта. Сервер обслуживает HTTP на порте 8080. Откройте доменное имя или IP-адрес сервера в браузере, укажите порт 8080 (статические элементы интерфейса, как CSS, например, не будут работать). Чтобы остановить сервер, нажмите CTRL-C.
Создание конфигурационного файла
Запуск uWSGI из командной строки хорошо подходит для тестирования, но в реальном развёртывании это очень неудобно. Запустите сервер в режиме Emperor mode, что позволяет ведущему процессу управлять отдельными приложениями автоматически. Для этого используются конфигурационные файлы.
Создайте каталог для хранения таких файлов и откройте его:
sudo mkdir -p /etc/uwsgi/sites
cd /etc/uwsgi/sites
Теперь нужно создать конфигурационный файл для каждого проекта. uWSGI может читать конфигурации разных форматов. В данном руководстве используется формат ini.
Создайте файл для первого проекта:
sudo nano firstsite.ini
Добавьте заголовок [uwsgi], под которым нужно поместить все настройки. Добавьте несколько переменных, чтобы сделать файл более универсальным. Сразу после заголовка добавьте переменную project с именем проекта. Переменная uid будет хранить имя пользователя с доступом к sudo. Затем добавьте переменную base, в которой нужно указать путь к домашнему каталогу.
[uwsgi]
project = firstsite
username = user
base = /home/%(username)
Теперь нужно настроить uWSGI для поддержки проекта. Измените корневой каталог проекта с помощью опции chdir. Скомбинировать указанный домашний каталог и имя проекта можно с помощью синтаксиса %(переменная). Во время чтения файла это значение будет заменено.
Затем импортируйте callable application из файла wsgi.py в каталоге проекта.
[uwsgi]
project = firstsite
username = user
base = /home/%(username)
chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application
Создайте главный процесс с 5 рабочими процессами.
[uwsgi]
project = firstsite
username = user
base = /home/%(username)
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 = firstsite
username = user
base = /home/%(username)
chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application
master = true
processes = 5
uid = %(username)
socket = /run/uwsgi/%(project).sock
chown-socket = %(username):nginx
chmod-socket = 660
vacuum = true
Настройка первого проекта завершена. Сохраните и закройте файл.
Преимущество переменных в конфигурационных файлах состоит в том, что их можно повторно использовать. Скопируйте файл первого проекта и используйте его в качестве шаблона для настройки второго сайта.
sudo cp /etc/uwsgi/sites/firstsite.ini /etc/uwsgi/sites/secondsite.ini
Откройте скопированный файл:
sudo nano /etc/uwsgi/sites/secondsite.ini
В файле нужно изменить только переменную project.
[uwsgi]
project = firstsite
username = user
base = /home/%(username)
chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application
master = true
processes = 5
uid = %(username)
socket = /run/uwsgi/%(project).sock
chown-socket = %(username):nginx
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. Больше настроек можно найти в документации uWSGI.
[Unit]
Description=uWSGI Emperor service
[Service]
ExecStartPre=/usr/bin/bash -c 'mkdir -p /run/uwsgi; chown user:nginx /run/uwsgi'
ExecStart=/usr/bin/uwsgi --emperor /etc/uwsgi/sites
Restart=always
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all
Теперь осталось добавить раздел [Install]. Он отвечает за автоматический запуск сервиса. Настройте сервис для работы в многопользовательской системе.
[Unit]
Description=uWSGI Emperor service
[Service]
ExecStartPre=/usr/bin/bash -c 'mkdir -p /run/uwsgi; chown user:nginx /run/uwsgi'
ExecStart=/usr/bin/uwsgi --emperor /etc/uwsgi/sites
Restart=always
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all
[Install]
WantedBy=multi-user.target
Сохраните и закройте файл.
Пока что запустить этот сервис невозможно, поскольку он зависит от пользователя www-data. Сервис будет доступен после установки и настройки Nginx.
Nginx как обратный прокси-сервер
Загрузите пакет Nginx из стандартного репозитория системы.
sudo yum install nginx
После установки Nginx отредактируйте главный конфигурационный файл:
sudo nano /etc/nginx/nginx.conf
В нём нужно создать дополнительные блоки server для каждого сайта:
http {
. . .
include /etc/nginx/conf.d/*.conf;
server {
}
server {
}
server {
listen 80 default_server;
server_name localhost;
. . .
Эти блоки будут хранить настройки сайтов uWSGI.
Сначала нужно указать номер порта и доменное имя сайта.
server {
listen 80;
server_name firstsite.com www.firstsite.com;
}
Укажите местонахождение статических файлов.
server {
listen 80;
server_name firstsite.com www.firstsite.com;
location = favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/user/firstsite;
}
}
Добавьте блок location для обслуживания всех остальных запросов. Добавьте параметры uwsgi из файла /etc/nginx/uwsgi_params и передайте трафик на сокет:
server {
listen 80;
server_name firstsite.com www.firstsite.com;
location = favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/user/firstsite;
}
location / {
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/firstsite.sock;
}
}
Сохраните виртуальный хост.
Используйте этот код как шаблон для виртуального хоста второго проекта.
Замените все данные о firstsite информацией о secondsite. Измените server_name, указав домен второго проекта. Замените каталог статических файлов и сокет. В результате должно получиться так:
server {
listen 80;
server_name secondsite.com www.secondsite.com;
location = favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/user/secondsite;
}
location / {
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/secondsite.sock;
}
}
Сохраните файл.
Проверьте ошибки в синтаксисе:
sudo nginx -t
Осталось выполнить всего одну задачу. Дело в том, что Nginx обслуживает файлы напрямую, а потому веб-серверу нужен доступ к соответствующим каталогам. Передайте Nginx право на выполнение в файлов домашнего каталога.
Для этого нужно добавить пользователя Nginx в группу текущего пользователя, а затем дать группе право на выполнение.
sudo usermod -a -G user nginx
chmod 710 /home/user
Теперь запустите Nginx и uWSGI:
sudo systemctl start nginx
sudo systemctl start uwsgi
Теперь оба проекта доступны по доменным именам. Проверьте работу проектов и интерфейсов. Если всё работает должным образом, включите автозапуск сервисов:
sudo systemctl enable nginx
sudo systemctl enable uwsgi
Примечание: После настройки обратного прокси-сервера Nginx настоятельно рекомендуется защитить подключения при помощи сертификатов SSL/TLS. В противном случае все данные будут передаваться в виде простого текста и легко могут быть перехвачены злоумышленниками. Сервис Let’s Encrypt позволяет получить бесплатный сертификат. Подробнее об этом – здесь.
Заключение
Теперь сервер приложений uWSGI обслуживает два приложения Django, которые находятся в индивидуальных виртуальных окружениях.