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
bme280 bmp280 gps mpu-6050 options stm32 ssd1331 ssd1306 eb-500 3d-printer soldering tim mpu-9250 dma watchdog piezo exti web raspberry-pi docker ngnix solar bluetooth foc html css brushless flask dc-dc capture gpio avr rs-232 mpx4115a atmega mongodb st-link barometer pwm nvic git java-script programmator dht11 hih-4000 pmsm encoder max1674 smd sensors rtc adc lcd motor timer meteo examples i2c usb flash sms rfid python esp8266 servo books bldc remap eeprom bkp battery ethernet uart usart displays led websocket nodemcu wifi
Архіви