Flask✙Gunicorn✙Nginx➭😎


01.09.2020

Це покрокова інструкція, як підняти у продакшені додаток, написаний на 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 автором цієї статті.

Бажаю успіхів.

Смотри также:

Web-dev склерозник
Коментарі:
Додати коментар
Code
* - обов'язкові поля

Архіви