One place for hosting & domains

      Обслуживание

      Обслуживание приложений Flask с Gunicorn и Nginx в Ubuntu 18.04


      Введение

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

      Предварительные требования

      Перед началом прохождения этого обучающего модуля вам потребуется следующее:

      • Сервер с установленной операционной системой Ubuntu 18.04 и пользователь без привилегий root и с привилегиями sudo. Следуйте указаниям нашего руководства по начальной настройке сервера.
      • Веб-сервер Nginx, установленный в соответствии с шагами 1 и 2 модуля Установка Nginx в Ubuntu 18.04.
      • Доменное имя, настроенное так, чтобы указывать на ваш сервер. Вы можете приобрести его на Namecheap или получить бесплатно на Freenom. Вы можете узнать, как указывать домены на DigitalOcean, из соответствующей документации по доменам и DNS. Обязательно создайте следующие записи DNS:

        • Запись A, где your_domain указывает на публичный IP-адрес вашего сервера.
        • Запись A, где www.your_domain указывает на публичный IP-адрес вашего сервера.
      • Знакомство со спецификацией WSGI, которую сервер Gunicorn будет использовать для взаимодействия с вашими приложениями Flask. В этом обсуждении более подробно рассказывается о WSGI.

      Шаг 1 — Установка компонентов из хранилищ Ubuntu

      Первым шагом будет установка всех необходимых нам элементов из хранилищ Ubuntu. Она включает установку pip, диспетчера пакетов Python, который будет управлять нашими компонентами Python. Также мы получим файлы разработки Python, необходимые для создания некоторых компонентов Gunicorn.

      Вначале обновим локальный индекс пакетов и установим пакеты, которые позволят нам создать нашу среду Python. Мы установим пакет python3-pip, а также еще несколько пакетов и средств разработки, необходимых для создания надежной среды программирования:

      • sudo apt update
      • sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools

      С этими пакетами мы перейдем к созданию виртуальной среды для нашего проекта.

      Шаг 2 — Создание виртуальной среды Python

      Теперь мы настроим виртуальную среду, чтобы изолировать наше приложение Flask от других файлов Python в системе.

      Для начала установим пакет python3-venv, который установит модуль venv:

      • sudo apt install python3-venv

      Затем создадим родительский каталог для нашего проекта Flask. Перейдите в каталог после его создания:

      • mkdir ~/myproject
      • cd ~/myproject

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

      • python3.6 -m venv myprojectenv

      Локальные копии Python и pip будут установлены в каталог myprojectenv в каталоге вашего проекта.

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

      • source myprojectenv/bin/activate

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

      Шаг 3 — Настройка приложения Flask

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

      Вначале мы установим wheel с локальным экземпляром pip, чтобы убедиться, что наши пакеты будут устанавливаться даже при отсутствии архивов wheel:

      Примечание. Если виртуальная среда активна, то вне зависимости от того, какую версию Python вы используете, вы должны использовать команду pip (а не pip3).

      Затем установим Flask и Gunicorn:

      • pip install gunicorn flask

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

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

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

      • nano ~/myproject/myproject.py

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

      ~/myproject/myproject.py

      from flask import Flask
      app = Flask(__name__)
      
      @app.route("/")
      def hello():
          return "<h1 style='color:blue'>Hello There!</h1>"
      
      if __name__ == "__main__":
          app.run(host='0.0.0.0')
      

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

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

      Теперь вы можете протестировать приложение Flask с помощью следующей команды:

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

      Output

      * Serving Flask app "myproject" (lazy loading) * Environment: production WARNING: Do not use the development server in a production environment. Use a production WSGI server instead. * Debug mode: off * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

      Откройте в браузере IP-адрес вашего сервера с суффиксом :5000:

      http://your_server_ip:5000
      

      Вы увидите примерно следующее:

      Образец приложения Flask

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

      Создание точки входа WSGI

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

      Мы назовем этот файл wsgi.py:

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

      ~/myproject/wsgi.py

      from myproject import app
      
      if __name__ == "__main__":
          app.run()
      

      Сохраните файл и закройте его после завершения.

      Шаг 4 — Настройка Gunicorn

      Ваше приложение написано, и для него создана точка входа. Теперь мы можем перейти к настройке Gunicorn.

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

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

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

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

      Результат будет выглядеть следующим образом:

      Output

      [2018-07-13 19:35:13 +0000] [28217] [INFO] Starting gunicorn 19.9.0 [2018-07-13 19:35:13 +0000] [28217] [INFO] Listening at: http://0.0.0.0:5000 (28217) [2018-07-13 19:35:13 +0000] [28217] [INFO] Using worker: sync [2018-07-13 19:35:13 +0000] [28220] [INFO] Booting worker with pid: 28220

      Откройте в браузере IP-адрес вашего сервера с суффиксом :5000.

      http://your_server_ip:5000
      

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

      Образец приложения Flask

      Убедившись в его нормальной работе, нажмите CTRL+C в окне терминала.

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

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

      Далее мы созадим файл служебных элементов systemd. Создание файла элементов systemd позволит системе инициализации Ubuntu автоматически запускать Gunicorn и обслуживать приложение Flask при загрузке сервера.

      Для начала создайте файл элементов с расширением .service в каталоге /etc/systemd/system:

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

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

      /etc/systemd/system/myproject.service

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

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

      /etc/systemd/system/myproject.service

      [Unit]
      Description=Gunicorn instance to serve myproject
      After=network.target
      
      [Service]
      User=sammy
      Group=www-data
      

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

      • Запуск 3 рабочих процессов (хотя вы можете изменить это при необходимости)
      • Создание и привязвка к файлу сокетов Unix myproject.sock в каталоге нашего проекта. Мы зададим значение umask 007, чтобы при создании файла сокета предоставлялся доступ для владельца и для группы, а любой другой доступ ограничивался
      • Укажите имя файла точки входа WSGI, а также вызываемый элемент Python в этом файле (wsgi:app)

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

      Не забудьте заменить имя пользователя и пути проекта собственными данными:

      /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

      Теперь проверим состояние:

      • sudo systemctl status myproject

      Результат должен выглядеть следующим образом:

      Output

      ● myproject.service - Gunicorn instance to serve myproject Loaded: loaded (/etc/systemd/system/myproject.service; enabled; vendor preset: enabled) Active: active (running) since Fri 2018-07-13 14:28:39 UTC; 46s ago Main PID: 28232 (gunicorn) Tasks: 4 (limit: 1153) CGroup: /system.slice/myproject.service ├─28232 /home/sammy/myproject/myprojectenv/bin/python3.6 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 ├─28250 /home/sammy/myproject/myprojectenv/bin/python3.6 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 ├─28251 /home/sammy/myproject/myprojectenv/bin/python3.6 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007 └─28252 /home/sammy/myproject/myprojectenv/bin/python3.6 /home/sammy/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:myproject.sock -m 007

      Если вы увидите какие-либо ошибки, устраните их, прежде чем продолжить выполнение этого обучающего модуля.

      Шаг 5 — Настройка Nginx для работы с запросами прокси-сервера

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

      Вначале мы создадим новый файл конфигурации серверных блоков в каталоге Nginx sites-available. Назовем его myproject для соответствия остальным именам в этом модуле:

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

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

      /etc/nginx/sites-available/myproject

      server {
          listen 80;
          server_name your_domain www.your_domain;
      }
      

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

      /etc/nginx/sites-available/myproject

      server {
          listen 80;
          server_name your_domain www.your_domain;
      
          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

      Когда файл будет находиться в этом каталоге, можно провести проверку на ошибки синтаксиса:

      Если ошибок обнаружено не будет, перезапустите процесс Nginx для чтения новой конфигурации:

      • sudo systemctl restart nginx

      В заключение снова изменим настройки брандмауэра. Нам больше не потребуется доступ через порт 5000, и мы можем удалить это правило. Затем мы сможем разрешить полный доступ к серверу Nginx:

      • sudo ufw delete allow 5000
      • sudo ufw allow 'Nginx Full'

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

      http://your_domain
      

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

      Образец приложения Flask

      Если будут обнаружены любые ошибки, проверьте следующее:

      • sudo less /var/log/nginx/error.log: проверяет журналы ошибок Nginx.
      • sudo less /var/log/nginx/access.log: проверяет журналы доступа Nginx.
      • sudo journalctl -u nginx: проверяет журналы процессов Nginx.
      • sudo journalctl -u myproject: проверяет журналы Gunicorn вашего приложения Flask.

      Шаг 6 — Защита приложения

      Чтобы обеспечить защиту трафика вашего сервера, необходимо получить сертификат SSL для вашего домена. Этого можно добиться несколькими способами, в том числе получить бесплатный сертификат от Let’s Encrypt, сгенерировать сертификат с собственной подписью или приобрести сертификат у другого поставщика и настроить Nginx для его использования, для чего потребуется выполнить шаги с 2 по 6 обучающего модуля Создание сертификата SSL с собственной подписью для Nginx в Ubuntu 18.04. Для удобства мы выберем первый вариант.

      Вначале добавьте хранилище Certbot Ubuntu:

      • sudo add-apt-repository ppa:certbot/certbot

      Вам нужно будет нажать ENTER для подтверждения.

      Установите пакет Certbot Nginx с apt:

      • sudo apt install python-certbot-nginx

      Certbot предоставляет широкий выбор способов получения сертификатов SSL с помощью плагинов: Плагин Nginx изменит конфигурацию Nginx и перезагрузит ее, когда это потребуется. Для использования этого плагина введите следующую команду:

      • sudo certbot --nginx -d your_domain -d www.your_domain

      Эта команда запускает certbot с плагином --nginx, используя опцию -d to для указания имен, для которых должен действовать сертификат.

      Если это первый запуск certbot, вам будет предложено указать адрес эл. почты и принять условия обслуживания. После этого certbot свяжется с сервером Let’s Encrypt и отправит запрос с целью подтвердить, что вы контролируете домен, для которого запрашиваете сертификат.

      Если это будет подтверждено, certbot запросит у вас предпочитаемый вариант настройки HTTPS:

      Output

      Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access. ------------------------------------------------------------------------------- 1: No redirect - Make no further changes to the webserver configuration. 2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for new sites, or if you're confident your site works on HTTPS. You can undo this change by editing your web server's configuration. ------------------------------------------------------------------------------- Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

      Выберите желаемый вариант, после чего нажмите ENTER. Конфигурация будет обновлена, а Nginx перезагрузится для получения новых настроек. Затем certbot завершит работу и выведет сообщение, подтверждающее завершение процесса и указывающее место хранения ваших сертификатов:

      Output

      IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/your_domain/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/your_domain/privkey.pem Your cert will expire on 2018-07-23. To obtain a new or tweaked version of this certificate in the future, simply run certbot again with the "certonly" option. To non-interactively renew *all* of your certificates, run "certbot renew" - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal. - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le

      Если вы следовали инструкциям по установке Nginx из предварительных требований, вам больше не потребуется разрешать профиль HTTP лишний раз:

      • sudo ufw delete allow 'Nginx HTTP'

      Чтобы подтвердить конфигурацию, снова перейдите в свой домен, используя префикс адреса https://:

      https://your_domain
      

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

      Заключение

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

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



      Source link

      Обслуживание приложений Flask с uWSGI и Nginx в Ubuntu 18.04


      Введение

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

      Предварительные требования

      Перед началом прохождения этого обучающего модуля вам потребуется следующее:

      • Сервер с установленной операционной системой Ubuntu 18.04 и пользователь без привилегий root и с привилегиями sudo. Следуйте указаниям нашего руководства по начальной настройке сервера.
      • Веб-сервер Nginx, установленный в соответствии с шагами 1 и 2 модуля Установка Nginx в Ubuntu 18.04.
      • Доменное имя, настроенное так, чтобы указывать на ваш сервер. Вы можете приобрести его на Namecheap или получить бесплатно на Freenom. Вы можете узнать, как указывать домены на DigitalOcean, из соответствующей документации по доменам и DNS. Обязательно создайте следующие записи DNS:

        • Запись A, где your_domain указывает на публичный IP-адрес вашего сервера.
        • Запись A, где www.your_domain указывает на публичный IP-адрес вашего сервера.
      • Знакомство с нашим сервером приложений uWSGI и спецификацией WSGI. В этом обсуждении определений и концепций о них рассказывается более подробно.

      Шаг 1 — Установка компонентов из хранилищ Ubuntu

      Первым шагом будет установка всех необходимых нам элементов из хранилищ Ubuntu. Для управления нашими компонентами Python мы установим pip, диспетчер пакетов Python. Также мы получим файлы разработки Python, необходимые для создания uWSGI.

      Вначале обновим локальный индекс пакетов и установим пакеты, которые позволят нам создать нашу среду Python. Мы установим пакет python3-pip, а также еще несколько пакетов и средств разработки, необходимых для создания надежной среды программирования:

      • sudo apt update
      • sudo apt install python3-pip python3-dev build-essential libssl-dev libffi-dev python3-setuptools

      С этими пакетами мы перейдем к созданию виртуальной среды для нашего проекта.

      Шаг 2 — Создание виртуальной среды Python

      Теперь мы настроим виртуальную среду, чтобы изолировать наше приложение Flask от других файлов Python в системе.

      Для начала установим пакет python3-venv, который установит модуль venv:

      • sudo apt install python3-venv

      Затем создадим родительский каталог для нашего проекта Flask. Перейдите в каталог после его создания:

      • mkdir ~/myproject
      • cd ~/myproject

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

      • python3.6 -m venv myprojectenv

      Локальные копии Python и pip будут установлены в каталог myprojectenv в каталоге вашего проекта.

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

      • source myprojectenv/bin/activate

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

      Шаг 3 — Настройка приложения Flask

      Находясь в виртуальной среде, вы можете установить Flask и uWSGI и начать работу над созданием вашего приложения.

      Вначале мы установим wheel с локальным экземпляром pip, чтобы убедиться, что наши пакеты будут устанавливаться даже при отсутствии архивов wheel:

      Примечание. Если виртуальная среда активна, то вне зависимости от того, какую версию Python вы используете, вы должны использовать команду pip (а не pip3).

      Затем установим Flask и uWSGI:

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

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

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

      • nano ~/myproject/myproject.py

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

      ~/myproject/myproject.py

      from flask import Flask
      app = Flask(__name__)
      
      @app.route("/")
      def hello():
          return "<h1 style='color:blue'>Hello There!</h1>"
      
      if __name__ == "__main__":
          app.run(host='0.0.0.0')
      

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

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

      Теперь вы можете протестировать приложение Flask с помощью следующей команды:

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

      Output

      * Serving Flask app "myproject" (lazy loading) * Environment: production WARNING: Do not use the development server in a production environment. Use a production WSGI server instead. * Debug mode: off * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

      Откройте в браузере IP-адрес вашего сервера с суффиксом :5000:

      http://your_server_ip:5000
      

      Вы увидите примерно следующее:

      Образец приложения Flask

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

      Создание точки входа WSGI

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

      Мы назовем этот файл wsgi.py:

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

      ~/myproject/wsgi.py

      from myproject import app
      
      if __name__ == "__main__":
          app.run()
      

      Сохраните файл и закройте его после завершения.

      Шаг 4 — Настройка uWSGI

      Ваше приложение написано, и для него создана точка входа. Теперь мы можем перейти к настройке uWSGI.

      Тестирование обслуживания uWSGI

      Проверим способность uWSGI обслуживать наше приложение.

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

      Также укажем сокет, чтобы запуск осуществлялся через общедоступный интерфейс, а также протокол, чтобы использовать протокол HTTP вместо двоичного протокола uwsgi. Мы будем использовать номер порта 5000, который открывали ранее:

      • uwsgi --socket 0.0.0.0:5000 --protocol=http -w wsgi:app

      Откройте в браузере IP-адрес вашего сервера с суффиксом :5000.

      http://your_server_ip:5000
      

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

      Образец приложения Flask

      Убедившись в его нормальной работе, нажмите CTRL+C в окне терминала.

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

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

      Создание файла конфигурации uWSGI

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

      Поместим этот файл в каталоге нашего проекта и назовем его myproject.ini:

      • nano ~/myproject/myproject.ini

      В начало файла мы добавим заголовок [uwsgi], чтобы указать uWSGI на необходимость применения настроек. Мы укажем сам модуль посредством ссылки на файл wsgi.py без расширения, и вызываемый элемент файла, app:

      ~/myproject/myproject.ini

      [uwsgi]
      module = wsgi:app
      

      Затем мы укажем uWSGI начать работу в режиме мастера и создать пять рабочих процессов для обслуживания фактических запросов:

      ~/myproject/myproject.ini

      [uwsgi]
      module = wsgi:app
      
      master = true
      processes = 5
      

      По время тестирования вы разместили uWSGI на сетевом порту. Однако для обработки фактических клиентских подключений вы будете использовать веб-сервер Nginx, который будет передавать запросы uWSGI. Поскольку эти компоненты работают на одном компьютере, предпочтительно будет использовать сокет Unix, так как он быстрее и безопаснее. Назовем этот сокет myproject.sock и разместим его в этом каталоге.

      Также изменим разрешения сокета. Позднее мы сделаем группу Nginx владельцем процесса uWSGI, и поэтому нужно сделать так, чтобы владелец группы сокета мог считывать из нее информацию и записывать в нее информацию. Также мы выполним очистку сокета после остановки процесса, для чего используем опцию vacuum:

      ~/myproject/myproject.ini

      [uwsgi]
      module = wsgi:app
      
      master = true
      processes = 5
      
      socket = myproject.sock
      chmod-socket = 660
      vacuum = true
      

      В заключение мы установим опцию die-on-term. Благодаря этому система инициализации и uWSGI будут одинаково интерпретировать каждый сигнал процесса. Эта настройка обеспечивает соответствие двух системных компонентов и позволяет добиться ожидаемого поведения:

      ~/myproject/myproject.ini

      [uwsgi]
      module = wsgi:app
      
      master = true
      processes = 5
      
      socket = myproject.sock
      chmod-socket = 660
      vacuum = true
      
      die-on-term = true
      

      Возможно вы заметили, что мы не указали протокол, как делали это из командной строки. Это связано с тем, что по умолчанию uWSGI использует для связи протокол uwsgi. Это быстрый двоичный протокол, созданный для коммуникации с другими серверами. В Nginx имеется изначальная поддержка этого протокола, и поэтому лучше использовать его, чем принудительно требовать использования протокола HTTP.

      После завершения редактирования сохраните и закройте файл.

      Шаг 5 — Создание файла элементов systemd

      Далее мы созадим файл служебных элементов systemd. Создание файла элементов systemd позволит системе инициализации Ubuntu автоматически запускать uWSGI и обслуживать приложение Flask при загрузке сервера.

      Для начала создайте файл элементов с расширением .service в каталоге /etc/systemd/system:

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

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

      /etc/systemd/system/myproject.service

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

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

      /etc/systemd/system/myproject.service

      [Unit]
      Description=uWSGI instance to serve myproject
      After=network.target
      
      [Service]
      User=sammy
      Group=www-data
      

      Теперь составим карту рабочего каталога и зададим переменную среды PATH, чтобы система инициализации знала, что исполняемые файлы этого процесса находятся в нашей виртуальной среде. Также укажем команду для запуска службы. Systemd требует, чтобы мы указывали полный путь исполняемого файла uWSGI, установленного в нашей виртуальной среде. Мы передадим имя файла конфигурации .ini, который создали в каталоге нашего проекта.

      Не забудьте заменить имя пользователя и пути проекта собственными данными:

      /etc/systemd/system/myproject.service

      [Unit]
      Description=uWSGI 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/uwsgi --ini myproject.ini
      

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

      /etc/systemd/system/myproject.service

      [Unit]
      Description=uWSGI 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/uwsgi --ini myproject.ini
      
      [Install]
      WantedBy=multi-user.target
      

      Теперь служебный файл systemd готов. Сохраните и закройте его.

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

      • sudo systemctl start myproject
      • sudo systemctl enable myproject

      Теперь проверим состояние:

      • sudo systemctl status myproject

      Результат должен выглядеть следующим образом:

      Output

      ● myproject.service - uWSGI instance to serve myproject Loaded: loaded (/etc/systemd/system/myproject.service; enabled; vendor preset: enabled) Active: active (running) since Fri 2018-07-13 14:28:39 UTC; 46s ago Main PID: 30360 (uwsgi) Tasks: 6 (limit: 1153) CGroup: /system.slice/myproject.service ├─30360 /home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.ini ├─30378 /home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.ini ├─30379 /home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.ini ├─30380 /home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.ini ├─30381 /home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.ini └─30382 /home/sammy/myproject/myprojectenv/bin/uwsgi --ini myproject.ini

      Если вы увидите какие-либо ошибки, устраните их, прежде чем продолжить выполнение этого обучающего модуля.

      Шаг 6 — Настройка Nginx для работы с запросами прокси-сервера

      Сервер приложений uWSGI должен быть запущен и ожидать запросы файла сокета в каталоге проекта. Настроим Nginx для передачи веб-запросов на этот сокет с помощью протокола uwsgi.

      Вначале мы создадим новый файл конфигурации серверных блоков в каталоге Nginx sites-available. Назовем его myproject для соответствия остальным именам в этом модуле:

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

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

      /etc/nginx/sites-available/myproject

      server {
          listen 80;
          server_name your_domain www.your_domain;
      }
      

      Затем добавим блок расположения, соответствующий каждому запросу. В этот блок мы добавим файл uwsgi_params, определяющий некоторые общие параметры uWSGI, которые необходимо настроить. После этого запросы будут переданы на сокет, который мы определили с помощью директивы uwsgi_pass:

      /etc/nginx/sites-available/myproject

      server {
          listen 80;
          server_name your_domain www.your_domain;
      
          location / {
              include uwsgi_params;
              uwsgi_pass unix:/home/sammy/myproject/myproject.sock;
          }
      }
      

      Сохраните файл и закройте его после завершения.

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

      • sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled

      Когда этот файл будет в данном каталоге, мы сможем провести проверку на ошибки синтаксиса с помощью следующей команды:

      Если ошибок обнаружено не будет, перезапустите процесс Nginx для чтения новой конфигурации:

      • sudo systemctl restart nginx

      В заключение снова изменим настройки брандмауэра. Нам больше не потребуется доступ через порт 5000, и мы можем удалить это правило. Затем мы сможем разрешить доступ к серверу Nginx:

      • sudo ufw delete allow 5000
      • sudo ufw allow 'Nginx Full'

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

      http://your_domain
      

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

      Образец приложения Flask

      Если будут обнаружены любые ошибки, проверьте следующее:

      • sudo less /var/log/nginx/error.log: проверяет журналы ошибок Nginx.
      • sudo less /var/log/nginx/access.log: проверяет журналы доступа Nginx.
      • sudo journalctl -u nginx: проверяет журналы процессов Nginx.
      • sudo journalctl -u myproject: проверяет журналы uWSGI вашего приложения Flask.

      Шаг 7 — Защита приложения

      Чтобы обеспечить защиту трафика вашего сервера, необходимо получить сертификат SSL для вашего домена. Этого можно добиться несколькими способами, в том числе получить бесплатный сертификат от Let’s Encrypt, сгенерировать сертификат с собственной подпись ю или приобрести сертификат у другого поставщика и настроить Nginx для его использования, для чего потребуется выполнить шаги с 2 по 6 обучающего модуля Создание сертификата SSL с собственной подписью для Nginx в Ubuntu 18.04. Для удобства мы выберем первый вариант.

      Вначале добавьте хранилище Certbot Ubuntu:

      • sudo add-apt-repository ppa:certbot/certbot

      Вам нужно будет нажать ENTER для подтверждения.

      Затем установите пакет Certbot Nginx с apt:

      • sudo apt install python-certbot-nginx

      Certbot предоставляет широкий выбор способов получения сертификатов SSL с помощью плагинов: Плагин Nginx изменит конфигурацию Nginx и перезагрузит ее, когда это потребуется. Для использования этого плагина введите следующую команду:

      • sudo certbot --nginx -d your_domain -d www.your_domain

      Эта команда запускает certbot с плагином --nginx, используя опцию -d to для указания имен, для которых должен действовать сертификат.

      Если это первый запуск certbot, вам будет предложено указать адрес эл. почты и принять условия обслуживания. После этого certbot свяжется с сервером Let’s Encrypt и отправит запрос с целью подтвердить, что вы контролируете домен, для которого запрашиваете сертификат.

      Если это будет подтверждено, certbot запросит у вас предпочитаемый вариант настройки HTTPS:

      Output

      Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access. ------------------------------------------------------------------------------- 1: No redirect - Make no further changes to the webserver configuration. 2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for new sites, or if you're confident your site works on HTTPS. You can undo this change by editing your web server's configuration. ------------------------------------------------------------------------------- Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

      Выберите желаемый вариант, после чего нажмите ENTER. Конфигурация будет обновлена, а Nginx перезагрузится для получения новых настроек. Затем certbot завершит работу и выведет сообщение, подтверждающее завершение процесса и указывающее место хранения ваших сертификатов:

      Output

      IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/your_domain/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/your_domain/privkey.pem Your cert will expire on 2018-07-23. To obtain a new or tweaked version of this certificate in the future, simply run certbot again with the "certonly" option. To non-interactively renew *all* of your certificates, run "certbot renew" - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal. - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le

      Если вы следовали инструкциям по установке Nginx из предварительных требований, вам больше не потребуется разрешать профиль HTTP лишний раз:

      • sudo ufw delete allow 'Nginx HTTP'

      Чтобы подтвердить конфигурацию, снова перейдите в свой домен, используя префикс адреса https://:

      https://your_domain
      

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

      Заключение

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

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



      Source link