Как обслуживать приложения Django с помощью uWSGI и Nginx в CentOS 7

Вступление

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

В этом руководстве мы продемонстрируем, как установить и настроить некоторые компоненты в CentOS 7 для поддержки и обслуживания приложений Django. Мы настроим сервер-контейнер приложений uWSGI для взаимодействия с нашими приложениями. Затем мы настроим Nginx для обращения прокси к uWSGI, предоставляя нам доступ к его функциям безопасности и производительности для обслуживания наших приложений.

Предпосылки и цели

Для выполнения этого руководства у вас должен быть свежий экземпляр сервера CentOS 7 с пользователем без полномочий root с настроенными привилегиями + sudo +. Вы можете узнать, как это настроить, запустив наше https://www.digitalocean.com/community/tutorials/initial-server-setup-with-centos-7 руководство по настройке на сервере[initial].

Мы будем устанавливать Django в двух разных виртуальных средах. Это позволит обрабатывать ваши проекты и их требования отдельно. Мы будем создавать два примера проектов, чтобы можно было выполнить все этапы в многопроектной среде.

Как только у нас появятся наши приложения, мы установим и настроим сервер приложений uWSGI. Это будет служить интерфейсом для наших приложений, которые будут транслировать клиентские запросы, используя HTTP-запросы на Python, которые наше приложение может обрабатывать. Затем мы настроим Nginx перед uWSGI, чтобы воспользоваться его высокопроизводительными механизмами обработки соединений и простыми в реализации функциями безопасности.

Давайте начнем.

Установите и настройте VirtualEnv и VirtualEnvWrapper

Мы будем устанавливать наши проекты Django в их собственных виртуальных средах, чтобы изолировать требования для каждого из них. Для этого мы будем устанавливать + virtualenv +, который может создавать виртуальные среды Python, и + virtualenvwrapper +, который добавляет некоторые улучшения удобства использования в рабочий процесс + virtualenv +.

Мы будем устанавливать оба этих компонента, используя + pip +, менеджер пакетов Python. Чтобы получить + pip +, нам сначала нужно включить репозиторий EPEL. Мы можем сделать это легко, набрав:

sudo yum install epel-release

После включения EPEL мы можем установить + pip +, набрав:

sudo yum install python-pip

Теперь, когда у вас установлено + 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

Это создаст виртуальную среду, установит Python и + pip + внутри нее, и активирует среду. Ваше приглашение изменится, чтобы указать, что вы сейчас работаете в новой виртуальной среде. Это будет выглядеть примерно так: + () @: ~ $ +. Значение в скобках - это имя вашей виртуальной среды. Любое программное обеспечение, установленное через + pip +, теперь будет установлено в виртуальной среде, а не в глобальной системе. Это позволяет нам изолировать наши пакеты для каждого проекта.

Нашим первым шагом будет установка самого Django. Мы можем использовать + pip для этого без` + sudo`, так как мы устанавливаем это локально в нашей виртуальной среде:

pip install django

С установленным Django мы можем создать наш первый пример проекта, набрав:

cd ~
django-admin.py startproject

Это создаст каталог с именем ++ в вашем домашнем каталоге. Внутри этого находится сценарий управления, используемый для обработки различных аспектов проекта, и другой каталог с тем же именем, используемый для размещения фактического кода проекта.

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

cd ~/

Начните с миграции базы данных, чтобы инициализировать базу данных SQLite, которую будет использовать наш проект. Вы можете настроить альтернативную базу данных для своего приложения, если хотите, но это выходит за рамки данного руководства:

./manage.py migrate

Теперь у вас должен быть файл базы данных с именем + db.sqlite3 + в каталоге вашего проекта. Теперь мы можем создать административного пользователя, набрав:

./manage.py createsuperuser

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

Затем откройте файл настроек проекта в текстовом редакторе:

nano /settings.py

Поскольку мы будем настраивать Nginx для обслуживания нашего сайта, нам необходимо настроить каталог, в котором будут храниться статические ресурсы нашего сайта. Это позволит Nginx обслуживать их напрямую, что положительно скажется на производительности. Мы скажем Django поместить их в каталог с именем + static + в базовом каталоге нашего проекта. Добавьте эту строку в конец файла, чтобы настроить это поведение:

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

Сохраните и закройте файл, когда вы закончите. Теперь соберите статические элементы нашего сайта и поместите их в этот каталог, набрав:

./manage.py collectstatic

Вы можете ввести «да», чтобы подтвердить действие и собрать статический контент. В вашем проекте появится новый каталог с именем + static +.

Со всем этим мы можем протестировать наш проект, временно запустив сервер разработки. Тип:

./manage.py runserver 0.0.0.0:8080

Это запустит сервер разработки на порт + 8080 +. Посетите доменное имя или IP-адрес вашего сервера, а затем в браузере + 8080 +:

http://:8080

Вы должны увидеть страницу, которая выглядит следующим образом:

изображение: https: //assets.digitalocean.com/articles/django_uwsgi_nginx_1404/sample_site.png [пример сайта Django]

Добавьте + / admin + в конец URL-адреса в адресной строке браузера, и вы попадете на страницу входа администратора:

изображение: https: //assets.digitalocean.com/articles/django_uwsgi_nginx_1404/admin_login.png [логин администратора Django]

Используя учетные данные администратора, которые вы выбрали с помощью команды + createuperuser +, войдите на сервер. После этого вы получите доступ к интерфейсу администрирования:

изображение: https: //assets.digitalocean.com/articles/django_uwsgi_nginx_1404/admin_interface.png [интерфейс администратора Django]

После тестирования этой функции остановите сервер разработки, введя CTRL-C в своем терминале. Теперь мы можем перейти к нашему второму проекту.

Создать второй проект

Второй проект будет создан точно так же, как и первый. Мы сократим объяснение в этом разделе, увидев, как вы уже завершили это один раз.

Вернитесь в свой домашний каталог и создайте вторую виртуальную среду для вашего нового проекта. Установите Django внутри этой новой среды после ее активации:

cd ~
mkvirtualenv
pip install django

Новая среда будет создана и изменена на, оставив предыдущую виртуальную среду. Этот экземпляр Django полностью отделен от другого, который вы настроили. Это позволяет вам управлять ими независимо и настраивать по мере необходимости.

Создайте второй проект и перейдите в каталог проекта:

django-admin.py startproject
cd ~/

Инициализируйте базу данных и создайте пользователя с правами администратора:

./manage.py migrate
./manage.py createsuperuser

Откройте файл настроек:

nano /settings.py

Добавьте местоположение для статических файлов, как вы делали в предыдущем проекте:

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

Сохраните и закройте файл. Теперь соберите статические элементы в этот каталог, набрав:

./manage.py collectstatic

Наконец, запустите сервер разработки, чтобы протестировать сайт:

./manage.py runserver 0.0.0.0:8080

Вы должны проверить обычный сайт по адресу:

http://:8080

Также войдите на сайт администратора:

http://:8080/admin

Когда вы подтвердите, что все работает должным образом, введите CTRL-C в своем терминале, чтобы остановить сервер разработки.

Отказ от виртуальной среды

Поскольку теперь мы закончили с частью руководства по Django, мы можем деактивировать нашу вторую виртуальную среду:

deactivate

Если вам снова понадобится работать на любом из ваших сайтов Django, вам следует активировать соответствующие среды. Вы можете сделать это используя команду + workon +:

workon

Or:

workon

Опять же, отключите, когда вы закончите работу над своими сайтами:

deactivate

Настройка сервера приложений uWSGI

Теперь, когда у нас есть два готовых к работе проекта Django, мы можем настроить uWSGI. uWSGI - это сервер приложений, который может взаимодействовать с приложениями через стандартный интерфейс WSGI. Чтобы узнать больше об этом, прочитайте https://www.digitalocean.com/community/tutorials/how-to-set-up-uwsgi-and-nginx-to-serve-python-apps-on-ubuntu-14-04 # определения и понятия [этот раздел] нашего руководства по настройке uWSGI и Nginx в Ubuntu 14.04.

Установка uWSGI

В отличие от руководства, указанного выше, в этом руководстве мы будем устанавливать uWSGI по всему миру. Это создаст меньше трения при работе с несколькими проектами Django. Прежде чем мы сможем установить uWSGI, нам нужны файлы разработки Python, на которые опирается программное обеспечение. Нам также нужен компилятор. Мы можем получить оба из них, используя + yum +:

sudo yum install python-devel gcc

Теперь, когда файлы разработки доступны, мы можем установить uWSGI глобально через + pip +, набрав:

sudo pip install uwsgi

Мы можем быстро протестировать этот сервер приложений, передав ему информацию для одного из наших сайтов. Например, мы можем сказать ему, чтобы он обслуживал наш первый проект, набрав:

uwsgi --http :8080 --home /home//Env/ --chdir /home// -w .wsgi

Здесь мы сказали uWSGI использовать нашу виртуальную среду, расположенную в каталоге + ~ / Env +, перейти в каталог нашего проекта и использовать файл + wsgi.py +, хранящийся в нашем внутреннем каталоге ++ обслуживать файл. Для демонстрации мы сказали, чтобы он служил HTTP на порту + 8080 +. Если вы перейдете к доменному имени или IP-адресу сервера в своем браузере, после чего добавится +: 8080 +, вы снова увидите свой сайт (статические элементы в интерфейсе + / admin + еще не будут работать). Когда вы закончите тестирование этой функции, введите CTRL-C в терминале.

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

Запуск uWSGI из командной строки полезен для тестирования, но не особенно полезен для реального развертывания. Вместо этого мы будем запускать uWSGI в «режиме Emperor», который позволяет главному процессу автоматически управлять отдельными приложениями с помощью набора файлов конфигурации.

Создайте каталог, в котором будут храниться ваши файлы конфигурации. Поскольку это глобальный процесс, мы создадим каталог с именем + / etc / uwsgi / sites для хранения ваших файлов конфигурации. Перейдите в каталог после его создания:

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

В этом каталоге мы разместим наши файлы конфигурации. Нам нужен файл конфигурации для каждого из проектов, которые мы обслуживаем. Процесс uWSGI может принимать файлы конфигурации в различных форматах, но мы будем использовать файлы + .ini + из-за их простоты.

Создайте файл для вашего первого проекта и откройте его в текстовом редакторе:

sudo nano .ini

Внутри мы должны начать с заголовка раздела + [uwsgi] +. Вся наша информация будет идти под этим заголовком. Мы также собираемся использовать переменные, чтобы сделать наш файл конфигурации более пригодным для повторного использования. После заголовка установите переменную с именем + project + с именем вашего первого проекта. Установите другую переменную с вашим обычным именем пользователя, которому принадлежат файлы проекта. Добавьте переменную с именем + base +, которая использует ваше имя пользователя для определения пути к домашнему каталогу вашего пользователя:

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

Далее нам нужно настроить uWSGI, чтобы он правильно обрабатывал наш проект. Нам нужно перейти в корневую директорию проекта, установив опцию + chdir +. Мы можем объединить настройки домашнего каталога и имени проекта, которые мы установили ранее, используя синтаксис +% () +. Это будет заменено значением переменной при чтении конфигурации.

Аналогичным образом мы укажем виртуальную среду для нашего проекта. Установив модуль, мы можем точно указать, как взаимодействовать с нашим проектом (импортируя вызываемое «приложение» из файла + wsgi.py + в каталоге нашего проекта). Конфигурация этих элементов будет выглядеть так:

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

chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application

Мы хотим создать мастер-процесс с 5 работниками. Мы можем сделать это, добавив это:

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

chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application

master = true
processes = 5

Далее нам нужно указать, как uWSGI должен прослушивать соединения. В нашем тесте uWSGI мы использовали HTTP и сетевой порт. Однако, поскольку мы собираемся использовать Nginx в качестве обратного прокси-сервера, у нас есть лучшие варианты.

Вместо использования сетевого порта, поскольку все компоненты работают на одном сервере, мы можем использовать сокет Unix. Это более безопасно и обеспечивает лучшую производительность. Этот сокет не будет использовать HTTP, но вместо этого будет реализован протокол uWSGI + uwsgi +, который является быстрым двоичным протоколом, предназначенным для связи с другими серверами. Nginx может прокси-сервер, используя протокол + uwsgi +, так что это наш лучший выбор.

Нам нужно установить пользователя, который будет запускать процесс. Мы также изменим разрешения и владельца сокета, потому что мы будем предоставлять веб-серверу доступ для записи. Сам сокет будет помещен в каталог + / run / uwsgi + (мы вскоре создадим этот каталог), куда и uWSGI, и Nginx смогут добраться до него. Мы установим опцию + вакуум +, чтобы файл сокета автоматически очищался при остановке службы:

[uwsgi]
project =
username =
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

На этом настройка нашего первого проекта uWSGI завершена. Сохраните и закройте файл.

Преимущество настройки файла с использованием переменных состоит в том, что он делает его невероятно простым для повторного использования. Скопируйте файл конфигурации вашего первого проекта, чтобы использовать его в качестве основы для вашего второго файла конфигурации:

sudo cp /etc/uwsgi/sites/.ini /etc/uwsgi/sites/.ini

Откройте второй файл конфигурации в текстовом редакторе:

sudo nano /etc/uwsgi/sites/.ini

Нам нужно всего лишь изменить одно значение в этом файле, чтобы оно работало для нашего второго проекта. Измените переменную + project + именем, которое вы использовали для второго проекта:

[uwsgi]
project =
username =
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

Сохраните и закройте файл, когда вы закончите. Ваш второй проект должен быть готов к работе сейчас.

Создайте системный файл модуля для uWSGI

Теперь у нас есть файлы конфигурации, которые нам нужны для обслуживания наших проектов Django, но мы до сих пор не автоматизировали процесс. Далее мы создадим файл модуля Systemd для автоматического запуска uWSGI при загрузке.

Мы создадим файл модуля в каталоге + / etc / systemd / system, где хранятся созданные пользователем файлы модуля. Мы назовем наш файл + uwsgi.service +:

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

Начните с раздела + [Unit] +, который используется для указания метаданных. Мы просто разместим описание нашего сервиса здесь:

[Unit]
Description=uWSGI Emperor service

Далее мы откроем раздел + [Service] +. Мы будем использовать директиву + ExecStartPre +, чтобы настроить части, которые нам нужны для запуска нашего сервера. Это обеспечит создание каталога + / run / uwsgi + и то, что наш обычный пользователь владеет им с группой Nginx в качестве владельца группы. Оба + mkdir + с флагом + -p + и команда + chown + возвращаются успешно, даже если они уже существуют. Это то, что мы хотим.

Для фактической команды запуска, указанной директивой + ExecStart +, мы укажем на исполняемый файл + uwsgi +. Мы скажем ему, чтобы он работал в «режиме Emperor», позволяя ему управлять несколькими приложениями, используя файлы, которые он находит в + / etc / uwsgi / sites +. Мы также добавим части, необходимые Systemd для правильного управления процессом. Они взяты из документации uWSGI here:

[Unit]
Description=uWSGI Emperor service

[Service]
ExecStartPre=/usr/bin/bash -c 'mkdir -p /run/uwsgi; chown :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 :nginx /run/uwsgi'
ExecStart=/usr/bin/uwsgi --emperor /etc/uwsgi/sites
Restart=always
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all

[Install]
WantedBy=multi-user.target

Когда вы закончите с этим, сохраните и закройте файл.

На этом этапе мы не сможем успешно запустить службу, поскольку она зависит от доступности пользователя + nginx +. Нам нужно будет подождать, чтобы запустить сервис uWSGI, пока не будет установлен Nginx.

Установите и настройте Nginx в качестве обратного прокси

Теперь, когда uWSGI настроен и готов к работе, мы можем установить и настроить Nginx в качестве нашего обратного прокси-сервера. Это можно загрузить и установить с помощью + yum +:

sudo yum install nginx

После установки Nginx мы можем отредактировать основной файл конфигурации:

sudo nano /etc/nginx/nginx.conf

В этом файле рядом с существующим блоком сервера мы создадим дополнительный блок сервера для каждого из наших сайтов:

http {

   . . .

   include /etc/nginx/conf.d/*.conf;







   server {
       listen 80 default_server;
       server_name localhost;

       . . .

Созданные нами блоки будут содержать конфигурацию для наших сайтов uWSGI. Мы рассмотрим директивы, которые нам нужны в первом блоке сервера.

Во-первых, нам нужно сообщить блоку сервера, на какой номер порта и имя домена он должен отвечать. Мы предполагаем, что у вас есть доменное имя для каждого из ваших сайтов:

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

Далее мы сообщим Nginx, что нам не нужно беспокоиться о пропавшем фавиконе. Затем мы укажем каталог, в который были собраны статические ресурсы нашего первого сайта, когда запрашиваются эти файлы. Nginx может передать их прямо клиенту из этого каталога:

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

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

Затем мы создаем блок местоположения для всех запросов, который будет передавать все дополнительные запросы прямо в uWSGI. Мы включим параметры + uwsgi +, найденные в файле + / etc / nginx / uwsgi_params +, и передадим трафик в сокет, настроенный сервером uWSGI:

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

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

   location / {
       include uwsgi_params;
       uwsgi_pass unix:/run/uwsgi/firstsite.sock;
   }
}

На этом наш первый серверный блок завершен.

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

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

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

   location / {
       include uwsgi_params;
       uwsgi_pass unix:/run/uwsgi/.sock;
   }
}

Когда вы закончите с этим шагом, сохраните и закройте файл.

Проверьте синтаксис файла Nginx, чтобы убедиться, что у вас нет ошибок:

sudo nginx -t

Если об ошибках не сообщается, наш файл в хорошем состоянии.

У нас есть еще одна задача, которую мы должны выполнить, чтобы наши сайты работали правильно. Поскольку Nginx обрабатывает статические файлы напрямую, ему необходим доступ к соответствующим каталогам. Нам нужно дать ему исполняемые разрешения для нашего домашнего каталога, который является единственным битом разрешений, которого ему не хватает.

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

sudo usermod -a -G  nginx
chmod 710 /home/

Теперь мы можем запустить сервер Nginx и процесс uWSGI:

sudo systemctl start nginx
sudo systemctl start uwsgi

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

Если все идет хорошо, вы можете включить обе службы для автоматического запуска при загрузке, набрав:

sudo systemctl enable nginx
sudo systemctl enable uwsgi

Заключение

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

Django упрощает создание проектов и приложений, предоставляя множество общих частей, позволяя вам сосредоточиться на уникальных элементах. Используя общую цепочку инструментов, описанную в этой статье, вы можете легко обслуживать созданные вами приложения с одного сервера.

Related