Flask✙Gunicorn✙Nginx➭😎
Це покрокова інструкція, як підняти в продакшені додаток, написаний на Flask, за допомогою GUNICORN та NGNIX. Отже, ми створили web-додаток за допомогою мікрофреймвока Flask. Ми його запускали та тестували на http://localhost:5000/. Але, в такому вигляді, на робочому сервері йому жити - не можна. Він не потягне навантаження і це може бути небезпечно. Як його підняти в продакшені? Для цього ми будемо використовувати GUNICORN і NGNIX.
Що таке GUNICORN?
GUNICORN - це web-сервер для web-додатків, написаних на python. Саме GUNICORN керує процесами Вашого додатка, створює й обслуговує з'єднання і, власне, є "адаптером" між вашим додатком на Flask і зовнішнім світом. Але сам GUNICORN в зовнішній світ виставляти не будемо. Перед ним буде Web-сервер Nginx, який буде виконувати функцію реверсного проксі.
Що таке NGNIX і нахалєра він потрібен?
NGNIX - дуже крутий та швидкий web-сервер. Він буде віддавати статичні файли - це він робить дуже швидко, а все, що стосується web-додатка, - буде перенаправляти на GUNICORN. Таким чином знизиться навантаження на web-додаток. Надалі можна буде підняти декілька серверів з вашим додатком, а на NGNIX - налаштувати балансер. Але в цьому прикладі ми такого робити не будемо.
Крок 1. Підготовка сервера Ubuntu
Встановлюємо все необхідне:
sudo apt update
sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools
Як Ви помітили, ми встановлюємо інструментарій для Python.
Крок 2. Створення віртуального середовища Python
Віртуальне середовище Python допоможе створити своє "болото" де ми будемо тихо булькати і не пускати сюди чужих бегемотиків, і нам буде затишно, комфортно і плювати ми хотіли на те, що там буде коїтися зовні. Тобто, ми створимо ізольоване середовище і встановимо туди ті модулі Python, які нам потрібні. Це не вплине на те, що встановлено зовні в системі, і встановлення або оновлення модулів Python в системі не буде впливати на наше віртуальне середовище. Назвемо його myblog_env.
python3.6 -m venv myblog_env
source myblog_env/bin/activate
Тепер все, що ми робимо і встановлюємо, стосується тільки нашого середовища. Встановлюємо потрібні модулі:
pip install wheel
pip install gunicorn flask
Далі встановлюємо модулі, які використовували в додатку. Наприклад:
pip install svglib
pip install Pillow
Перевіряємо чи стартує наш додаток:
python ./myblog_app.py
Крок 3. Налаштування додатка Flask
Створюємо WSGI Entry Point. Тобто файл myblog_wsgi.py:
from myblog_app import app
if __name__ == "__main__":
app.run()
Для перевірки стартуємо Gunicorn:
gunicorn --bind 0.0.0.0:5000 myblog_wsgi:app
Якщо не стартує - розбираємось, чого. Частіше за все треба встановити забуті модулі Python. Pip3 вам в поміч.
Як все буде OK зупиняємо gunicorn (Ctrl+C :) ) - виходимо з віртуального середовища:
deactivate
Крок 4. Налаштовуємо сервіс Gunicorn
У директорії /etc/systemd/system створюємо файл з розширенням .service. Наприклад: myblog.service
sudo nano /etc/systemd/system/myblog.service
[Unit]
Description=Gunicorn instance to serve myproject
After=network.target
[Service]
User=andre
Group=www-data
WorkingDirectory=/home/andre/myblog
Environment="PATH=/home/andre/myblog/myblog_env/bin"
ExecStart=/home/andre/myblog/myblog_env/bin/gunicorn --workers 3 --bind unix:myblog.sock -m 007 myblog_wsgi:app
[Install]
WantedBy=multi-user.target
ЗВЕРНІТЬ Увагу!
--bind unix:myblog.sock - створить сокет, а не "підніме прослуховування на порту".
Group=www-data - необхідно для того, щоб NGNIX мав права доступу до сокета.
--workers 3 - скільки воркерів буде працювати одночасно. Більше навантаження - треба більше workers. Більше workers - треба більше пам'яті і потужніший проц. Не вистачає ресурсів - тоді вже піднімаємо другий сервер і крутимо Nginx, як балансер.
Пробуємо стартувати сервіс:
sudo systemctl start myblog
Має бути створено сокет (myblog.sock) в WorkingDirectory (/home/andre/myblog)
Зупинити сервіс можна командою:
sudo systemctl stop myblog
Попробували? Тепер запустіть.
Використання сокету унеможливлює доступ зовні, тому що "нєфіг шастать" - безпека, всі діла...
Крок 5. Налаштування Nginx
Створюємо файл з налаштуваннями сайту:
sudo nano /etc/nginx/sites-available/myblog
server {
listen 80;
server_name blog.avislab.com;
location / {
include proxy_params;
proxy_pass http://unix:/home/andre/myblog/myblog.sock;
}
}
Зверніть увагу!
proxy_pass http://unix:/home/andre/myblog/myblog.sock; - це шлях до сокета сервісу.
Вмикаємо:
sudo ln -s /etc/nginx/sites-available/myblog /etc/nginx/sites-enabled
Перевіряємо чи немає помилок:
sudo nginx -t
Як все норм - пересмикуємо Nginx:
sudo systemctl restart nginx
Крок 6. HTTPS
А SSL де? Для того, щоб отримати халявний SSL і автоматично поновлювати сертифікат, користуємо Certbot.
sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository universe
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install certbot python-certbot-nginx
Запускаємо "магію":
sudo certbot --nginx
certbot поставе кілька запитань і сам підправить конфіг сайту і закріпить сертифікат і все, що потрібно.
Тест автоматичного поновлення:
sudo certbot renew --dry-run
Крок 6. HTTP2
Якщо web-проєкт публічний, рекомендую додати http2 до рядка, де прописаний listen. Дуже його любить google. Він прямо не може жити без http2 і гугломірялка буде нарікати, що гуглоботику не вистачає http2. Давайте не будемо ображати тваринку. Приклад куди всунути http2:
server {
server_name blog.avislab.com;
location / {
include proxy_params;
proxy_pass http://unix:/home/andre/myblog/myblog.sock;
}
listen 443 ssl http2; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/blog.avislab.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/blog.avislab.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
Приблизно так налаштований і працює цей блог, який Ви зараз читаєте, бо він теж написаний на Flask автором цієї статті.
Бажаю успіхів.
Смотри также:
- Flask. Установка и первое приложение
- Flask. JSON
- Flask + SQLite + JSON
- Flask > db_class > SQLite
- Flask. Model. ООП для работы с данными
- Flask, CORS, JSON-файл
- Flask + Vue. Финальный пример
Tags
web java-script bmp280 adc bldc stm32 rs-232 programmator 3d-printer flash pwm sms motor docker raspberry-pi meteo gps ngnix bme280 timer ssd1331 mpu-6050 bkp battery rfid st-link tim mpx4115a ssd1306 encoder atmega pmsm wifi options rtc examples nvic soldering mongodb esp8266 books lcd foc flask barometer bluetooth ethernet brushless uart watchdog servo gpio solar git remap dma usart eb-500 smd nodemcu sensors displays html python capture dht11 led i2c eeprom piezo exti websocket max1674 usb dc-dc avr hih-4000 css mpu-9250
Архіви