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

Вступление

Фреймворк web2py - это мощный и простой в использовании инструмент для быстрой разработки полнофункциональных веб-приложений на Python. С помощью web2py вы можете легко разрабатывать и управлять своими приложениями с помощью административного веб-интерфейса.

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

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

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

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

Загрузите web2py Framework

Нашим первым шагом будет загрузка самой фреймворка web2py. Это поддерживается в репозитории + git + на GitHub, поэтому лучший способ скачать его - с самим + git +.

Мы можем скачать и установить + git + из репозиториев CentOS по умолчанию, набрав:

sudo yum install git

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

git clone --recursive https://github.com/web2py/web2py.git ~/

Платформа web2py будет загружена в каталог с именем + myapp + в вашем домашнем каталоге.

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

cd ~/

Административный интерфейс должен быть защищен SSL, чтобы мы могли сделать простой самоподписанный сертификат, чтобы проверить это. Создайте ключ сервера и сертификат, набрав:

openssl req -x509 -new -newkey rsa:4096 -days 3652 -nodes -keyout .key -out .crt

Вам нужно будет заполнить некоторую информацию для генерируемого вами сертификата. Единственная часть, которая действительно имеет значение в этих обстоятельствах, это поле + Common Name +, которое должно ссылаться на доменное имя или IP-адрес вашего сервера:

. . .

Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:New York
Locality Name (eg, city) []:New York City
Organization Name (eg, company) [Internet Widgits Pty Ltd]:DigitalOcean
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:[email protected]

Когда вы закончите, ключ SSL и сертификат должны быть в каталоге вашего приложения. Они будут называться + .key и` + .ctrl` соответственно.

После этого мы можем запустить веб-интерфейс web2py, чтобы протестировать его. Для этого мы можем набрать:

python web2py.py -k .key -c .crt -i 0.0.0.0 -p 8000

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

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

https://:8000

Убедитесь, что вы используете + https + вместо + http + в указанном выше адресе. Вы будете предупреждены, что ваш браузер не распознает сертификат SSL:

изображение: https: //assets.digitalocean.com/articles/web2py_uwsgi_nginx_centos7/ssl_warning.png [предупреждение web2py SSL]

Это ожидается, так как мы подписали наш собственный сертификат. Нажмите на ссылку «Дополнительно» или любую другую ссылку, которую дает вам ваш браузер, а затем перейдите на сайт, как и планировалось. Вы увидите интерфейс web2py:

изображение: https: //assets.digitalocean.com/articles/web2py_uwsgi_nginx_centos7/welcome_app.png [приложение приветствия web2py]

Нажав на кнопку «Административный интерфейс» справа, вы сможете ввести пароль, выбранный вами при запуске сервера, и перейти на сайт администрирования:

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

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

Когда вы закончите осматриваться, введите CTRL-C обратно в окно терминала. Мы протестировали наше приложение и продемонстрировали, что к нему можно получить доступ в Интернете, когда запущен сервер разработки web2py.

Установите и настройте uWSGI

Теперь, когда у нас работает приложение web2py, мы можем настроить 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 по всему миру. Прежде чем мы сможем установить uWSGI, нам нужно установить + pip +, менеджер пакетов Python и файлы разработки Python, на которые опирается uWSGI. Нам также понадобится компилятор для создания реального двоичного файла. Чтобы получить + pip +, нам нужно будет использовать репозиторий EPEL, который содержит дополнительные пакеты.

Мы можем активировать EPEL-репозиторий, набрав:

sudo yum install epel-release

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

sudo yum install python-devel python-pip gcc

Теперь мы можем установить uWSGI глобально с помощью + pip +, набрав:

sudo pip install uwsgi

Контейнерный сервер приложений uWSGI взаимодействует с приложениями Python, используя спецификацию интерфейса WSGI. Фреймворк web2py содержит файл, предназначенный для предоставления этого интерфейса в каталоге + handlers +. Чтобы использовать файл, нам нужно переместить его из каталога в основной каталог проекта:

mv ~//handlers/wsgihandler.py ~/

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

uwsgi --http :8000 --chdir ~/ -w wsgihandler:application

Это должно запустить приложение снова на порт 8000. На этот раз, поскольку мы не используем сертификат и ключ SSL, он будет обслуживаться по обычному HTTP вместо HTTPS. Вы можете проверить это снова в своем браузере, используя протокол + http +. Вы не сможете проверить интерфейс администратора, потому что web2py отключает это, когда шифрование недоступно.

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

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

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

Создайте каталог в + / etc / uwsgi / sites для хранения ваших настроек и затем перейдите в этот каталог:

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

Мы назовем наш файл конфигурации + myapp.ini +:

sudo nano .ini

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

[uwsgi]
chdir = /home//
module = wsgihandler:application

Далее нам нужно указать, что мы хотим, чтобы uWSGI работал в режиме master. Мы хотим создать пять рабочих процессов:

[uwsgi]
chdir = /home//
module = wsgihandler:application

master = true
processes = 5

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

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

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

[uwsgi]
chdir = /home//
module = wsgihandler:application

master = true
processes = 5

uid =
socket = /run/uwsgi/.sock
chown-socket = :nginx
chmod-socket = 660
vacuum = true

Наш файл конфигурации uWSGI теперь готов. Сохраните и закройте файл.

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

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

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

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

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

[Unit]
Description=uWSGI Emperor service

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

Для фактической команды запуска, указанной в директиве ExecStart, мы укажем на исполняемый файл uwsgi. Мы скажем ему, чтобы он работал в «режиме Императора», позволяя ему управлять несколькими приложениями, используя файлы, найденные в / 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 мы можем изменить конфигурацию блока сервера. Мы отредактируем основной файл конфигурации Nginx:

sudo nano /etc/nginx/nginx.conf

Приложение web2py определяет, подключаетесь ли вы по обычному HTTP или с использованием шифрования SSL. Из-за этого наш файл фактически будет содержать один блок сервера для каждого. Мы начнем с серверного блока, настроенного на работу с портом 80.

Измените + server_name +, указав имя домена или IP-адрес, по которому ваш сайт должен быть доступен. После этого мы создадим блок + location {} +, который будет соответствовать запросам на статическое содержимое. По сути, мы хотим использовать регулярные выражения для сопоставления запросов, заканчивающихся на + / static / +, с предшествующим компонентом пути. Мы хотим отобразить эти запросы в каталог + Applications + в нашем проекте web2py. Убедитесь, что вы указали домашний каталог вашего пользователя и имя приложения:

server {
   listen                  80 default_server;
   server_name             ;
   root                    /usr/share/nginx/html;

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





   . . .

После этого нам нужно настроить блок + location / {} + для передачи запросов в наш сокет uWSGI. Нам просто нужно включить файл параметров uWSGI, упакованный с Nginx, и передать запросы в настроенный сокет (в нашем файле uWSGI + .ini +):

server {
   listen                  80 default_server;
   server_name             ;
   root                    /usr/share/nginx/html;

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

   location ~* /(\w+)/static/ {
       root /home/user/myapp/applications/;
   }

   location / {


   }
}

   . . .

Это будет все, что нам нужно для нашего первого блока сервера.

В нижней части файла, но внутри закрывающей скобки блока + http {} +, создайте еще один блок + server {} +. Мы будем использовать это для настройки соединений SSL.

Начните с основ. Этот блок сервера будет прослушивать соединения через порт 443, порт SSL по умолчанию. Мы установим доменное имя или IP-адрес сервера, как мы делали для блока сервера порта 80. Чтобы запустить реальную конфигурацию SSL, мы укажем, что SSL должен быть включен для этого блока, и мы укажем путь к сертификату SSL и ключ, который должен использоваться для шифрования соединения. Мы будем перемещать файлы туда на мгновение:

http {
   . . .
   server {
       listen 80;
       . . .
   }








}

Мы продолжим работу с образцом SSL, предназначенным для установления принятых протоколов и шифров. После этого мы можем установить тот же блок + location / {} +, который мы настроили в блоке сервера порта 80:

http {
   . . .
   server {
       listen 80;
       . . .
   }
   server {
       listen 443;
       server_name ;

       ssl on;
       ssl_certificate /etc/nginx/ssl/myapp.crt;
       ssl_certificate_key /etc/nginx/ssl/myapp.key;









   }
}

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

Заключительные шаги

Далее нам нужно переместить SSL-сертификаты в каталог, который мы указали. Сначала создайте каталог:

sudo mkdir -p /etc/nginx/ssl

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

sudo mv ~//.crt /etc/nginx/ssl
sudo mv ~//.key /etc/nginx/ssl

Измените разрешения, чтобы пользователи без полномочий root не могли получить доступ к этому каталогу:

sudo chmod 700 /etc/nginx/ssl

Пользователь + nginx + должен иметь доступ к каталогу наших приложений, чтобы он мог напрямую обслуживать статические файлы по мере необходимости. CentOS очень строго блокирует домашний каталог каждого пользователя, поэтому мы добавим пользователя + nginx + в нашу группу пользователей, чтобы мы могли открыть минимальные разрешения, необходимые для его работы.

Добавьте пользователя + nginx + в свою группу, напечатав это. Замените ваше имя пользователя на + user + в команде ниже:

sudo usermod -a -G  nginx

Теперь мы дадим нашей группе пользователей права на выполнение для нашего каталога, что позволит процессу Nginx входить и получать доступ к содержимому в пределах:

chmod 710 /home/

Теперь проверьте файл конфигурации Nginx на наличие синтаксических ошибок:

sudo nginx -t

Если нет сообщений о синтаксических ошибках, мы можем запустить Nginx:

sudo service nginx start

Мы также можем запустить наш сервис uWSGI:

sudo service uwsgi start

Последнее, что нам нужно сделать, это скопировать файл параметров нашего приложения, чтобы он правильно читался при обслуживании соединений через порт 443. Он содержит пароль, который мы настроили для административного интерфейса. Нам просто нужно скопировать его в новое имя, которое указывает порт 443 вместо порта 8000:

cp ~//parameters_8000.py ~//parameters_443.py

Благодаря этому вы сможете получить доступ к своему серверу, используя доменное имя или IP-адрес сервера. Используйте + https +, если вы хотите войти в административный интерфейс.

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

sudo systemctl enable nginx
sudo systemctl enable uwsgi

Заключение

В этом руководстве мы настроили пример проекта web2py для практического развертывания. Мы настроили uWSGI для взаимодействия между нашим приложением и клиентскими запросами. Затем мы настроили Nginx перед uWSGI, чтобы разрешить SSL-соединения и эффективно обрабатывать запросы клиентов.

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

Related