Обслуживание приложений Flask с помощью Nginx и Gunicorn в Ubuntu
Материал посвящен использованию Flask в Ubuntu. В рамках статьи рассмотрим основы функционирования Gunicorn и Nginx для развертывания прокси под Frontend.
Подготовка к проекту
Нам понадобится хост с предустановленной Ubuntu. Желательно создать на сервере обычного пользователя с правами sudo. Например, арендуйте готовую к эксплуатации удаленную машину у провайдера Timeweb Cloud.
Также понадобится:
- Инсталлировать веб-сервер Nginx.
- Зарегистрировать домен.
- Настроить записи DNS:
- А с указанием публичного IP в графе your_domain.
- А аналогично, но с добавлением www.
Желательно иметь представление о спецификации WSGI. Это поможет понять, как Gunicorn обменивается данными и командами с приложениями Flask.
Инсталлируем компоненты
В рамках подготовки к работе постановим менеджер pip, с его помощью мы будем манипулировать компонентами Python. Плюс скачаем файлы, требуемые для создания ряда элементов Gunicorn. Но предварительно скачаем обновления пакетов и установим python3-pip, он нужен для организации среды разработки:
sudo apt update
sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools
Зададим настройки виртуальной среде Python
Виртуальные окружения позволяют разделять зависимости приложений, размещенных на одном сервере. Первый этап:
sudo apt install python3-venv
Вторым этапом сделаем родительскую директорию, где будем хранить весь проект Flask. И сразу перейдем в нее:
mkdir ~/myproject
cd ~/myproject
Третьим этапом организуем непосредственно виртуальную среду Python:
python3 -m venv myprojectenv
Все используемые впоследствии файлы будут сохраняться в папке myprojectenv. Остается провести активацию:
source myprojectenv/bin/activate
Результат будет заметен по изменившемуся виду командной строки. Она примет такой вид: (myprojectenv)user@host:~/myproject$
Настроим приложение Flask
Обновим pip:
pip install -U pip
Следом загрузим Flask и Gunicorn:
pip install gunicorn flask
Создадим свой модуль
Теперь применим Flask для создания простейшей программы. Но важно учитывать, что данную микроструктуру чаще берут в качестве дополнительного модуля, т.к. в ней минимум инструментов из тех, что обычно актуальны при веб-разработке. В качестве примера создадим простой вариант под названием myproject.py:
nano ~/myproject/myproject.py
В указанный файл мы сохраним код программы. При запуске будет импортирован Flask и создан экземпляр объекта. Например, вот так:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "<h >Hello!<h1>"
if __name__ == "__main__":
app.run(host='0.0.0.0')
После внесения изменений закройте файл с сохранением. Теперь проверим работоспособность кода, но сначала настроим брандмауэр, чтобы тот разрешал трафик по порту 5000.
sudo ufw allow 5000
Теперь система готова к тесту программного модуля Flask:
python myproject.py
Теперь откроем наш домен по IP с указанием порта:
http://your_server_ip:5000
В окне браузера увидим «Hello!». Завершим сессию и отключим сервер нажатием комбинации <Ctrl+C> (в терминале).
Сделаем точку входа WSGI
Переходим к созданию файла, который послужит нам точкой входа в разрабатываемую программу. Он «подскажет» серверу Gunicorn, каким образом обмениваться данными с ним.
nano ~/myproject/wsgi.py
Перенесем экземпляр Flask в только что созданный файл, после чего откроем его:
from myproject import app
if __name__ == "__main__":
app.run()
По итогу закроем его.
Настроим Gunicorn
Перед продолжением работы убедимся, что сервер Gunicorn способен правильно обрабатывать нашу программу. Выполняется это передачей наименования точки входа без расширения и имени вызываемого элемента. Возьмем, например, wsgi:app. Еще в команде понадобится указать номер порта с интерфейсом:
cd ~/myproject
gunicorn --bind 0.0.0.0:5000 wsgi:app
Перейдем в браузер и введем IP нашего сервера с портом под номером 5000:
http://your_server_ip:5000
Программа выдаст сообщение «Hello!». Завершим работу нажатием кнопок <Ctrl + C> в окне терминала. И отключим виртуальную среду:
deactivate
После этого все команды Python будут иметь отношение только к общей системной среде. Если работать с виртуальной придется постоянно, есть смысл запускать ее автоматически вместе с операционкой. С этой целью сгенерируем файл автозагрузки. Сначала создадим *.service и разместим в папке /etc/systemd/system:
sudo nano /etc/systemd/system/myproject.service
Первоначально [Unit], куда обычно вносят метаданные и зависимости, внесем описание службы и зададим условие инициализировать «виртуалку» после подтверждения наличия связи:
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target
В блоке [Service] укажем аккаунт и группу, от имени которых будет запускаться процесс.
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target
[Service]
User=username
Group=www-data
Следующим шагом укажем переменную PATH, чтобы при активизации система сразу «понимала», где брать требуемые файлы (в «виртуалке»).
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target
[Service]
User=username
Group=www-data
WorkingDirectory=/home/username/myproject
Environment="PATH=/home/username/myproject/myprojectenv/bin"
ExecStart=/home/username/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
Следует учитывать, что для systemd нужно указывать полный путь к файлу Gunicorn, размещенному в «виртуалке».
В итоге добавим раздел [install] и внесем в него:
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target
[Service]
User=user
Group=www-data
WorkingDirectory=/home/user/myproject
Environment="PATH=/home/user/myproject/myprojectenv/bin"
ExecStart=/home/user/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 wsgi:app
[Install]
WantedBy=multi-user.target
Все, файл systemd подготовлен. Закройте его с сохранением изменений. И можно запускать службу Guricorn (сразу настроим ее загрузку вместе с операционкой):
sudo systemctl start myproject
sudo systemctl enable myproject
Остается проверить ее текущее состояние:
sudo systemctl status myproject
Настроим Nginx
Переходим к работе с веб-сервером Nginx (Gunicorn не используется в качестве фронтенд-сервера, и обычно настраивается реверс-прокси. В нашем случае это будет Nginx). Сначала создадим файл с конфигурацией в директории с sites-available, назовем его myproject.
sudo nano /etc/nginx/sites-available/myproject
В нем укажем веб-серверу прослушивать порт 80 и использовать серверный блок при всех запросах нашего домена:
server {
listen 80;
server_name your_domain www.your_domain;
}
Следом добавим location, где укажем proxy_params, определяющий параметры настраиваемого прокси.
server {
listen 80;
server_name your_domain www.your_domain;
location / {
include proxy_params;
proxy_pass http://unix:/home/username/myproject/myproject.sock;
}
}
Закроем файл с сохранением изменений. И применим новую конфигурацию путем привязки к директории sites-enabled.
sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
Перезапустим Nginx:
sudo nginx -s reload
Завершим настройку внесением изменений в параметры брандмауэра. Например, правило насчет доступа через порт 5000 нам уже не понадобится, его можно смело удалять. Вместо него внесем другой, для открытия подключения к серверу Nginx:
sudo ufw delete allow 5000
sudo ufw allow 'Nginx Full'
Попробуйте зайти на наш сервер из браузера – http://your_domain. Программа выдаст сообщение «Hello!»
Защитим наше решение
Последняя задача в этом материале – установка SSL сертификата для защиты трафика. Мы рекомендуем получить бесплатный SSL Let’s Encrypt с помощью Certbot. Рекомендуемый способ установки Certbot — через snap, который уже предустановлен в Ubuntu.
Подробную инструкцию по выпуску SSL можно найти в официальной документации Certbot.
Выполните команду ниже, чтобы убедиться, что используется последняя версия snapd:
sudo snap install core; sudo snap refresh core
Если ранее вы устанавливали какие-то пакеты Certbot с помощью пакетного менеджера apt, удалите их командой:
sudo apt-get remove certbot
Установите certbot через snap:
sudo snap install --classic certbot
Выполните следующее, чтобы убедиться, что команда certbot может быть запущена:
sudo ln -s /snap/bin/certbot /usr/bin/certbot
Выполните команду ниже, чтобы получить сертификат и автоматически внести необходимые изменений в конфигурацию nginx:
sudo certbot --nginx
Certbot будет автоматически обновлять сертификат. Вы можете протестировать обновление, запустив команду:
sudo certbot renew --dry-run
После проверьте открытие домена https://your_domain в браузере. Помимо традиционного результата в виде сообщения «Hello!», должен появиться замочек, подтверждающий защиту сайта.
Выводы
Вот мы и разобрались, как работать в микрофреймворке Flask на сервере Ubuntu с применением виртуальной среды Python. Система довольно гибкая, свободно обеспечивает работу приложений практически без структурных ограничений.