Как обслуживать приложения Flask с помощью uWSGI и Nginx в Ubuntu 16.04

Вступление

В этом руководстве мы будем настраивать простое приложение Python с использованием микро-фреймворка Flask в Ubuntu 16.04. Основная часть этой статьи будет посвящена тому, как настроить сервер приложений uWSGI для запуска приложения и Nginx в качестве внешнего прокси-сервера.

Предпосылки

Перед началом работы с этим руководством на вашем сервере должен быть настроен пользователь без полномочий root. Этот пользователь должен иметь права + sudo +, чтобы он мог выполнять административные функции. Чтобы узнать, как это настроить, следуйте нашему https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-16-04 руководство по настройке начального сервера].

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

Когда вы будете готовы продолжить, читайте дальше.

Установите компоненты из репозитория Ubuntu

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

Нам нужно обновить локальный индекс пакета, а затем установить пакеты. Необходимые пакеты зависят от того, использует ли ваш проект Python 2 или Python 3.

Если вы используете * Python 2 *, введите:

sudo apt-get update
sudo apt-get install python-pip python-dev nginx

Если вместо этого вы используете * Python 3 *, введите:

sudo apt-get update
sudo apt-get install python3-pip python3-dev nginx

Создать виртуальную среду Python

Далее мы настроим виртуальную среду, чтобы изолировать наше приложение Flask от других файлов Python в системе.

Начните с установки пакета + virtualenv с помощью` + pip`.

Если вы используете * Python 2 *, введите:

sudo pip install virtualenv

Если вы используете * Python 3 *, введите:

sudo pip3 install virtualenv

Теперь мы можем создать родительский каталог для нашего проекта Flask. Перейдите в каталог после его создания:

mkdir ~/
cd ~/

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

virtualenv

Это установит локальную копию Python и + pip + в каталог с именем ++ в каталоге вашего проекта.

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

source /bin/activate

Ваше приглашение изменится, чтобы указать, что вы сейчас работаете в виртуальной среде. Это будет выглядеть примерно так + () @: ~ / $ +.

Установите приложение для колб

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

Установите Flask и uWSGI

Мы можем использовать локальный экземпляр + pip + для установки Flask и uWSGI. Введите следующие команды, чтобы получить эти два компонента:

Note

pip install uwsgi flask

Создать образец приложения

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

Хотя ваше приложение может быть более сложным, мы создадим наше приложение Flask в одном файле, который мы назовем + myproject.py +:

nano ~//.py

В этом файле мы разместим код нашего приложения. По сути, нам нужно импортировать Flask и создать экземпляр объекта Flask. Мы можем использовать это для определения функций, которые должны запускаться при запросе определенного маршрута:

~ / MyProject / myproject.py

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
   return "<h1 style='color:blue'>Hello There!</h1>"

if __name__ == "__main__":
   app.run(host='0.0.0.0')

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

Если вы следовали руководству по первоначальной настройке сервера, у вас должен быть включен брандмауэр UFW. Чтобы протестировать наше приложение, нам нужно разрешить доступ к порту 5000.

Откройте порт 5000, набрав:

sudo ufw allow 5000

Теперь вы можете протестировать приложение Flask, набрав:

python .py

Посетите доменное имя или IP-адрес вашего сервера, а затем в браузере введите «+: 5000 +»:

http://:5000

Вы должны увидеть что-то вроде этого:

изображение: https: //assets.digitalocean.com/articles/nginx_uwsgi_wsgi_1404/test_app.png [Пример приложения Flask]

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

Создать точку входа WSGI

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

Мы назовем файл + wsgi.py +:

nano ~//wsgi.py

Файл невероятно прост, мы можем просто импортировать экземпляр Flask из нашего приложения и затем запустить его:

~ / MyProject / wsgi.py

from myproject import app

if __name__ == "__main__":
   app.run()

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

Настроить uWSGI

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

Тестирование uWSGI Serving

Первое, что мы сделаем, это протестируем, чтобы убедиться, что uWSGI может обслуживать наше приложение.

Мы можем сделать это, просто передав ему имя нашей точки входа. Он создается по имени модуля (как обычно, за вычетом расширения + .py +) и имени вызываемого в приложении приложения. В нашем случае это будет + wsgi: app.

Мы также укажем сокет, чтобы он запускался на общедоступном интерфейсе и протоколе, чтобы он использовал HTTP вместо двоичного протокола + uwsgi +. Мы будем использовать тот же номер порта, который мы открыли ранее:

uwsgi --socket 0.0.0.0:5000 --protocol=http -w wsgi:app

Перейдите к доменному имени или IP-адресу вашего сервера, добавив в конец веб-браузера +: 5000 +:

http://:5000

Вы должны увидеть вывод вашего приложения снова:

изображение: https: //assets.digitalocean.com/articles/nginx_uwsgi_wsgi_1404/test_app.png [Пример приложения Flask]

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

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

deactivate

Любые команды Python теперь снова будут использовать системную среду Python.

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

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

Поместим это в каталог нашего проекта и назовем его + myproject.ini +:

nano ~//.ini

Внутри мы начнем с заголовка + [uwsgi] +, чтобы uWSGI знал, как применить настройки. Мы зададим модуль, обратившись к нашему файлу + wsgi.py +, за исключением расширения и того, что вызываемый файл внутри файла называется «app»:

~ / MyProject / myproject.ini

[uwsgi]
module = wsgi:app

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

~ / MyProject / myproject.ini

[uwsgi]
module = wsgi:app

master = true
processes = 5

Когда мы тестировали, мы выставили uWSGI на сетевой порт. Однако мы будем использовать Nginx для обработки реальных клиентских подключений, которые затем будут передавать запросы в uWSGI. Поскольку эти компоненты работают на одном и том же компьютере, предпочтительным является сокет Unix, поскольку он более безопасный и быстрый. Мы вызовем сокет + myproject.sock + и поместим его в этот каталог.

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

~ / MyProject / myproject.ini

[uwsgi]
module = wsgi:app

master = true
processes = 5

socket = .sock
chmod-socket = 660
vacuum = true

Последнее, что нам нужно сделать, это установить опцию + die-on-term +. Это может помочь гарантировать, что система инициализации и uWSGI имеют одинаковые предположения о том, что означает каждый сигнал процесса. Установка этого выравнивает два системных компонента, реализуя ожидаемое поведение:

~ / MyProject / myproject.ini

[uwsgi]
module = wsgi:app

master = true
processes = 5

socket = .sock
chmod-socket = 660
vacuum = true

die-on-term = true

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

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

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

Следующим этапом, о котором нам нужно позаботиться, является файл сервисного модуля systemd. Создание файла системного модуля позволит системе инициализации Ubuntu автоматически запускать uWSGI и обслуживать наше приложение Flask при каждой загрузке сервера.

Создайте файл модуля, заканчивающийся на .service в каталоге / etc / systemd / system, чтобы начать:

sudo nano /etc/systemd/system/.service

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

/etc/systemd/system/myproject.service

[Unit]
Description=uWSGI instance to serve
After=network.target

Далее мы откроем раздел + [Service] +. Мы укажем пользователя и группу, под которой мы хотим запустить процесс. Мы дадим право нашей учетной записи обычного пользователя на процесс, поскольку он владеет всеми соответствующими файлами. Мы передадим групповое владение группе + www-data, чтобы Nginx мог легко общаться с процессами uWSGI.

Затем мы отобразим рабочий каталог и установим переменную окружения + PATH +, чтобы система инициализации знала, где находятся наши исполняемые файлы для процесса (в нашей виртуальной среде). Затем мы укажем команду для запуска службы. Systemd требует, чтобы мы указали полный путь к исполняемому файлу uWSGI, который установлен в нашей виртуальной среде. Мы передадим имя файла конфигурации .ini, который мы создали в каталоге нашего проекта:

/etc/systemd/system/myproject.service

[Unit]
Description=uWSGI instance to serve
After=network.target

[Service]
User=
Group=www-data
WorkingDirectory=/home//
Environment="PATH=/home////bin"
ExecStart=/home////bin/uwsgi --ini .ini

Наконец, мы добавим раздел + [Install] +. Это скажет systemd, с чем связать этот сервис, если мы включим его при загрузке. Мы хотим, чтобы эта служба запускалась, когда обычная многопользовательская система запущена и работает:

/etc/systemd/system/myproject.service

[Unit]
Description=uWSGI instance to serve
After=network.target

[Service]
User=
Group=www-data
WorkingDirectory=/home//
Environment="PATH=/home////bin"
ExecStart=/home////bin/uwsgi --ini .ini

[Install]
WantedBy=multi-user.target

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

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

sudo systemctl start
sudo systemctl enable

Настройка запросов Nginx к прокси

Теперь наш сервер приложений uWSGI должен быть запущен и ожидает запросов к файлу сокета в каталоге проекта. Нам нужно настроить Nginx для передачи веб-запросов в этот сокет с использованием протокола + uwsgi +.

Начните с создания нового файла конфигурации блока сервера в каталоге + sites-available + в Nginx. Мы просто назовем это + myproject +, чтобы соответствовать остальной части руководства:

sudo nano /etc/nginx/sites-available/

Откройте блок сервера и скажите Nginx прослушивать порт 80 по умолчанию. Мы также должны указать ему использовать этот блок для запросов на доменное имя или IP-адрес нашего сервера:

/ И т.д. / Nginx / сайты Недоступные / MyProject

server {
   listen 80;
   server_name ;
}

Единственное, что нам нужно добавить - это блок местоположения, соответствующий каждому запросу. В этом блоке мы включим файл + uwsgi_params , который определяет некоторые общие параметры uWSGI, которые необходимо установить. Затем мы передадим запросы в сокет, который мы определили с помощью директивы ` uwsgi_pass +`:

/ И т.д. / Nginx / сайты Недоступные / MyProject

server {
   listen 80;
   server_name ;

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

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

Чтобы включить только что созданную конфигурацию блока сервера Nginx, свяжите файл с каталогом + sites-enabled +:

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

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

sudo nginx -t

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

sudo systemctl restart nginx

Последнее, что нам нужно сделать, это снова настроить наш брандмауэр. Нам больше не нужен доступ через порт 5000, поэтому мы можем удалить это правило. Затем мы можем разрешить доступ к серверу Nginx:

sudo ufw delete allow 5000
sudo ufw allow 'Nginx Full'

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

http://

Вы должны увидеть выходные данные своего приложения:

изображение: https: //assets.digitalocean.com/articles/nginx_uwsgi_wsgi_1404/test_app.png [Пример приложения Flask]

Note

Заключение

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

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

Related