Как обслуживать колбу с помощью Gunicorn и Nginx в Ubuntu 16.04

Вступление

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

Предпосылки

Перед началом работы с этим руководством на вашем сервере должен быть настроен пользователь без полномочий root. У этого пользователя должны быть праваsudo, чтобы он мог выполнять административные функции. Чтобы узнать, как это настроить, следуйте нашимinitial server setup guide.

Чтобы узнать больше о спецификации WSGI, которую наш сервер приложений будет использовать для связи с нашим приложением Flask, вы можете прочитать связанный разделthis guide. Понимание этих концепций облегчит следовать этому руководству.

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

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

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

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

Если вы используете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 ~/myproject
cd ~/myproject

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

virtualenv myprojectenv

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

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

source myprojectenv/bin/activate

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

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

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

Установите колбу и Gunicorn

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

Note

[.note] # Независимо от того, какую версию Python вы используете, когда виртуальная среда активирована, вы должны использовать командуpip (неpip3).
#

pip install gunicorn flask

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

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

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

nano ~/myproject/myproject.py

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

~/myproject/myproject.py

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "

Hello There!

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

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

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

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

sudo ufw allow 5000

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

python myproject.py

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

http://server_domain_or_IP:5000

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

Flask sample app

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

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

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

Назовем файлwsgi.py:

nano ~/myproject/wsgi.py

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

~/myproject/wsgi.py

from myproject import app

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

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

Тестирование способности Gunicorn служить проекту

Прежде чем двигаться дальше, мы должны проверить, что Gunicorn может правильно.

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

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

cd ~/myproject
gunicorn --bind 0.0.0.0:5000 wsgi:app

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

http://server_domain_or_IP:5000

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

Flask sample app

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

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

deactivate

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

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

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

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

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

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

/etc/systemd/system/myproject.service

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

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

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

Мы скажем ему запустить 3 рабочих процесса (при необходимости измените это). Мы также укажем ему создать и привязать файл сокета Unix в каталоге нашего проекта под названиемmyproject.sock. Мы установим значение umask007, чтобы файл сокета был создан, предоставляя доступ владельцу и группе, ограничивая при этом другой доступ. Наконец, нам нужно передать имя файла точки входа WSGI и вызываемый Python внутри:

/etc/systemd/system/myproject.service

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

[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myproject
Environment="PATH=/home/sammy/myproject/myprojectenv/bin"
ExecStart=/home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app

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

/etc/systemd/system/myproject.service

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

[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myproject
Environment="PATH=/home/sammy/myproject/myprojectenv/bin"
ExecStart=/home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app

[Install]
WantedBy=multi-user.target

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

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

sudo systemctl start myproject
sudo systemctl enable myproject

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

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

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

sudo nano /etc/nginx/sites-available/myproject

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

/etc/nginx/sites-available/myproject

server {
    listen 80;
    server_name server_domain_or_IP;
}

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

/etc/nginx/sites-available/myproject

server {
    listen 80;
    server_name server_domain_or_IP;

    location / {
        include proxy_params;
        proxy_pass http://unix:/home/sammy/myproject/myproject.sock;
    }
}

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

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

sudo ln -s /etc/nginx/sites-available/myproject /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://server_domain_or_IP

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

Flask sample app

Note

[.Примечание]##

После настройки Nginx следующим шагом должна стать защита трафика на сервере с использованием SSL / TLS. Это важно, потому что без него вся информация, включая пароли, отправляется по сети в виде простого текста.

Самый простой способ получить SSL-сертификат для защиты вашего трафика - использовать Let Encrypt. Следуйтеthis guide, чтобы настроить Let's Encrypt с Nginx на Ubuntu 16.04.

Заключение

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

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

Related