One place for hosting & domains

      Обслуживание приложений 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

      How To Serve Flask Applications with uWSGI and Nginx on Ubuntu 18.04


      Introdução

      Neste guia, você construirá um aplicativo Python usando o microframework do Flask no Ubuntu 18.04. A maior parte deste artigo será sobre como configurar o servidor do aplicativo uWSGI e como iniciar o aplicativo e configurar o Nginx para atuar como um proxy reverso no front-end.

      Pré-requisitos

      Antes de iniciar este guia, você deve ter:

      • Um servidor com o Ubuntu 18.04 instalado e um usuário não raiz com privilégios sudo. Siga nosso guia de configuração inicial do servidor para orientação.
      • O Nginx instalado, seguindo os Passos 1 e 2 de Como Instalar o Nginx no Ubuntu 18.04.
      • Um nome de domínio configurado para apontar para o seu servidor. Você pode comprar um no Namecheap ou obter um de graça no Freenom. Você pode aprender como apontar domínios para o DigitalOcean seguindo a relevante documentação para domínios e DNS. Certifique-se de criar os seguintes registros DNS:

        • Um registro com o your_domain <^>apontando para o endereço IP público do seu servidor.
        • Um registro A com www.your_domain apontando para o endereço IP público do seu servidor.
      • Familiaridade com a uWSGI, nosso servidor do aplicativo, e as especficiações da WSGI. Este debate sobre definições e conceitos examinará ambos em detalhes.

      Passo 1 — Instalando os componentes dos repositórios do Ubuntu

      Nosso primeiro passo será instalar todas as partes dos repositórios do Ubuntu que vamos precisar. Vamos instalar o pip e o gerenciador de pacotes Python para gerenciar nossos componentes Python. Também vamos obter os arquivos de desenvolvimento do Python necessários para construir a uWSGI.

      Primeiramente, vamos atualizar o índice local de pacotes e instalar os pacotes que irão nos permitir construir nosso ambiente Python. Estes incluem o python3-pip, junto com alguns outros pacotes e ferramentas de desenvolvimento necessários para um ambiente de programação robusto:

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

      Com esses pacotes instalados, vamos seguir em frente para criar um ambiente virtual para nosso projeto.

      Passo 2 — Criando um Ambiente Virtual em Python

      Em seguida, vamos configurar um ambiente virtual para isolar nosso aplicativo Flask dos outros arquivos Python no sistema.

      Inicie instalando o pacote python3-venv, que instalará o módulo venv:

      • sudo apt install python3-venv

      Em seguida, vamos fazer um diretório pai para nosso projeto Flask. Acesse o diretório após criá-lo:

      • mkdir ~/myproject
      • cd ~/myproject

      Crie um ambiente virtual para armazenar os requisitos Python do projeto Flask digitando:

      • python3.6 -m venv myprojectenv

      Isso instalará uma cópia local do Python e do pip para um diretório chamado myprojectenv dentro do diretório do seu projeto.

      Antes de instalar aplicativos no ambiente virtual, você precisa ativá-lo. Faça isso digitando:

      • source myprojectenv/bin/activate

      Seu prompt mudará para indicar que você agora está operando no ambiente virtual. Ele se parecerá com isso (myprojectenv)user@host:~/myproject$.

      Passo 3 — Configurando um aplicativo Flask

      Agora que você está no seu ambiente virtual, instale o Flask e a uWSGI e comece a projetar o seu aplicativo.

      Primeiramente, vamos instalar o wheel com a instância local do pip para garantir que nossos pacotes serão instalados mesmo se estiverem faltando arquivos wheel:

      Nota: Independentemente da versão de Python que você estiver usando, quando o ambiente virtual for ativado, você deverá usar o comando pip (não pip3).

      Em seguida, vamos instalar o Flask e a uWSGI:

      Criando um App de exemplo

      Agora que você tem o Flask disponível, você pode criar um aplicativo simples. O Flask é um microframework. Ele não inclui muitas das ferramentas que os frameworks mais completos talvez tenham. Ele existe, principalmente, como um módulo que você pode importar para seus projetos para ajudá-lo na inicialização de um aplicativo Web.

      Embora seu aplicativo possa ser mais complexo, vamos criar nosso app Flask em um único arquivo, chamado “myproject.py:

      • nano ~/myproject/myproject.py

      O código do aplicativo ficará neste arquivo. Ele importará o Flask e instanciará um objeto Flask. Você pode usar isto para definir as funções que devem ser executadas quando uma rota específica for solicitada:

      ~/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')
      

      Isso define basicamente qual conteúdo apresentar quando o domínio raiz for acessado. Salve e feche o arquivo quando você terminar.

      Se você seguiu o guia de configuração inicial do servidor, você deverá ter um firewall UFW ativado. Para testar o aplicativo, você precisa permitir o acesso à porta 5000:

      Agora, você pode testar seu app Flask digitando:

      Você verá um resultado como o seguinte, incluindo um aviso útil lembrando você para não usar essa configuração do servidor na produção:

      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)

      Visite o endereço IP do seu servidor seguido de :5000 no seu navegador Web:

      http://your_server_ip:5000
      

      Você deve ver algo como isto:

      Flask sample app

      Quando terminar, tecle CTRL-C na janela do seu terminal para parar o servidor de desenvolvimento Flask.

      Criando o ponto de entrada da WSGI

      Em seguida, vamos criar um arquivo que servirá como o ponto de entrada para nosso aplicativo. Isso dirá ao nosso servidor uWSGI como interagir com ele.

      Vamos chamar o arquivo de wsgi.py:

      Neste arquivo, vamos importar a instância Flask do nosso aplicativo e então executá-lo:

      ~/myproject/wsgi.py

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

      Salve e feche o arquivo quando você terminar.

      Passo 4 — Configurando a uWSGI

      Seu aplicativo agora está gravado com um ponto de entrada estabelecido. Podemos agora seguir em frente para configurar a uWSGI.

      Testando o atendimento à uWSGI

      Vamos testar para ter certeza de que a uWSGI pode atender nosso aplicativo.

      Podemos fazer isso simplesmente passando-lhe o nome do nosso ponto de entrada. Criamos esse ponto de entrada através do nome do módulo (menos a extensão .py) mais o nome do objeto callable dentro do aplicativo. No nosso caso, trata-se do wsgi:app.

      Vamos também especificar o soquete, de modo que ele seja iniciado em uma interface disponível publicamente, bem como o protocolo, para que ele use o HTTP em vez do protocolo binário uwsgi. Vamos usar o mesmo número de porta, 5000, que abrimos mais cedo:

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

      Visite o endereço IP do seu servidor com :5000 anexo ao final no seu navegador Web novamente:

      http://your_server_ip:5000
      

      Você deve ver o resultado do seu aplicativo novamente:

      Flask sample app

      Quando você tiver confirmado que ele está funcionando corretamente, pressione CTRL-C na janela do seu terminal.

      Acabamos agora o nosso ambiente virtual, para que possamos desativá-lo:

      Agora, qualquer comando Python voltará a usar o ambiente do sistema Python.

      Criando um arquivo de configuração da uWSGI

      Você testou e viu que a uWSGI pode atender o seu aplicativo. Porém, em última instância, você irá querer algo mais robusto para o uso a longo prazo. Você pode criar um arquivo de configuração da uWSGI com as opções relevantes para isso.

      Vamos colocar aquele arquivo no diretório do nosso projeto e chamá-lo de myproject.ini:

      • nano ~/myproject/myproject.ini

      Dentro, vamos começar com o cabeçalho [uwsgi], para que a uWSGI saiba aplicar as configurações. Vamos especificar duas coisas: o módulo propriamente dito, recorrendo ao arquivo wsgi.py (menos a extensão) e ao objeto callable dentro do arquivo, app:

      ~/myproject/myproject.ini

      [uwsgi]
      module = wsgi:app
      

      Em seguida, vamos dizer à uWSGI para iniciar em modo mestre e gerar cinco processos de trabalho para atender a pedidos reais:

      ~/myproject/myproject.ini

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

      Quando você estava testando, você expôs a uWSGI em uma porta da rede. No entanto, você usará o Nginx para lidar com conexões reais do cliente, as quais então passarão as solicitações para a uWSGI. Uma vez que esses componentes estão operando no mesmo computador,é preferífel usar um soquete Unix porque ele é mais rápido e mais seguro. Vamos chamar o soquete de myproject<^>.sock e colocá-lo neste diretório.

      Vamos alterar também as permissões no soquete. Mais tarde, iremos atribuir a propriedade do grupo Nginx sobre o processo da uWSGI. Dessa forma, precisamos assegurar que o proprietário do grupo do soquete consiga ler as informações que estão nele e gravar nele. Quando o processo parar, também limparemos o soquete, adicionando a opção vacuum:

      ~/myproject/myproject.ini

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

      A última coisa que vamos fazer é definir a opção die-on-term. Isso pode ajudar a garantir que o sistema init e a uWSGI tenham as mesmas suposições sobre o que cada sinal de processo significa. Configurar isso alinha os dois componentes do sistema, implementando o comportamento esperado:

      ~/myproject/myproject.ini

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

      Você pode ter notado que não especificamos um protocolo como fizemos a partir da linha de comando. Isso acontece porque, por padrão, a uWSGI fala usando o protocolo uwsgi, um protocolo binário rápido projetado para se comunicar com outros servidores. O Nginx pode falar este protocolo de maneira nativa, então é melhor usar isso do que forçar a comunicação pelo HTTP.

      Quando você terminar, salve e feche o arquivo.

      Passo 5 — Criando um arquivo de unidade systemd

      Em seguida, vamos criar o arquivo de unidade systemd. Criar um arquivo de unidade systemd permitirá que o sistema init do Ubuntu inicie automaticamente a uWSGI e atenda o aplicativo Flask sempre que o servidor for reinicializado.

      Para começar, crie um arquivo de unidade que termine com .service dentro do diretório /etc/systemd/system:

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

      Ali, vamos começar com a seção [Unit], que é usada para especificar os metadados e dependências. Vamos colocar uma descrição do nosso serviço aqui e dizer ao sistema init para iniciar isso somente após o objetivo da rede ter sido alcançado:

      /etc/systemd/system/myproject.service

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

      Em seguida, vamos abrir a seção [Service]. Isso especificará o usuário e o grupo sob o qual que queremos que o processo seja executado. Vamos dar à nossa conta de usuário regular a propriedade sobre o processo, uma vez que ela possui todos os arquivos relevantes. Vamos também dar propriedade sobre o grupo ao grupo www-data para que o Nginx possa se comunicar facilmente com os processos da uWSGI. Lembre-se de substituir esse nome de usuário pelo seu nome de usuário:

      /etc/systemd/system/myproject.service

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

      Em seguida, vamos mapear o diretório de trabalho e definir a variável de ambiente PATH para que o sistema init saiba que os executáveis do processo estão localizados dentro do nosso ambiente virtual. Vamos também especificar o comando para iniciar o serviço. O systemd exige que seja dado o caminho completo para o executável uWSGI, que está instalado dentro do nosso ambiente virtual. Vamos passar o nome do arquivo de configuração .ini que criamos no nosso diretório de projeto.

      Lembre-se de substituir o nome de usuário e os caminhos do projeto por seus próprios dados:

      /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
      

      Finalmente, vamos adicionar uma seção [Install]. Isso dirá ao systemd ao que vincular este serviço se nós o habilitarmos para iniciar na inicialização. Queremos que este serviço comece quando o sistema regular de vários usuários estiver funcionando:

      /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
      

      Com isso, nosso arquivo de serviço systemd está completo. Salve e feche-o agora.

      Podemos agora iniciar o serviço uWSGI que criamos e habilitá-lo para que ele seja iniciado na inicialização:

      • sudo systemctl start myproject
      • sudo systemctl enable myproject

      Vamos verificar o status:

      • sudo systemctl status myproject

      Você deve ver um resultado como este:

      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

      Se encontrar erros, certifique-se de resolvê-los antes de continuar com o tutorial.

      Passo 5 — Configurando o Nginx para solicitações de proxy

      Nosso servidor do aplicativo uWSGI agora deverá estar funcionando, esperando pedidos no arquivo do soquete, no diretório do projeto. Vamos configurar o Nginx para passar pedidos da Web àquele soquete, usando o protocolo uwsgi.

      Comece criando um novo arquivo de configuração do bloco do servidor no diretório sites-available do Nginx. Vamos chamá-lo de myproject para mantê-lo alinhado com o resto do guia:

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

      Abra um bloco de servidor e diga ao Nginx para escutar na porta padrão 80. Vamos também dizer a ele para usar este bloco para pedidos para o nome de domínio do nosso servidor:

      /etc/nginx/sites-available/myproject

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

      Em seguida, vamos adicionar um bloco de localização que corresponda a cada pedido. Dentro deste bloco, vamos incluir o arquivo uwsgi_params, que especifica alguns parâmetros gerais da uWSGI que precisam ser configurados. Vamos então passar os pedidos para o soquete que definimos usando a diretiva 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;
          }
      }
      

      Salve e feche o arquivo quando você terminar.

      Para habilitar a configuração do bloco do servidor Nginx que você acabou de criar, vincule o arquivo ao diretório sites-enabled:

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

      Com o arquivo naquele diretório, podemos realizar testes à procura de erros de sintaxe, digitando:

      Se esse procedimento retornar sem indicar problemas, reinicie o processo do Nginx para ler a nova configuração:

      • sudo systemctl restart nginx

      Finalmente, vamos ajustar o firewall novamente. Já não precisamos de acesso através da porta 5000, então podemos remover essa regra. Podemos então conceder acesso total ao servidor Nginx:

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

      Agora, você consegue navegar até o nome de domínio do seu servidor no seu navegador Web:

      http://your_domain
      

      Você deve ver o resultado do seu aplicativo:

      Flask sample app

      Caso encontre quaisquer erros, tente verificar o seguinte:

      • sudo less /var/log/nginx/error.log: verifica os registros de erros do Nginx.
      • sudo less /var/log/nginx/access.log: verifica os registros de acesso do Nginx.
      • sudo journalctl -u nginx: verifica os registros de processo do Nginx.
      • sudo journalctl -u myproject: verifica os registros de uWSGI do seu app Flask.

      Passo 7 — Protegendo o aplicativo

      Para garantir que o tráfego para seu servidor permaneça protegido, vamos obter um certificado SSL para seu domínio. Há várias maneiras de fazer isso, incluindo a obtenção de um certificado gratuito do Let’s Encrypt, gerando um certificado autoassinado ou comprando algum de outro provedor e configurando o Nginx para usá-lo, seguindo os Passos 2 a 6 de Como criar um certificado SSL autoassinado para o Nginx no Ubuntu 18.04. Vamos escolher a opção um por questão de conveniência.

      Primeiramente, adicione o repositório de software Ubuntu do Certbot:

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

      Aperte ENTER para aceitar.

      Em seguida, instale o pacote Nginx do Certbot com o apt:

      • sudo apt install python-certbot-nginx

      O Certbot oferecer várias maneiras de obter certificados SSL através de plug-ins. O plug-in Nginx cuidará da reconfiguração do Nginx e recarregará a configuração sempre que necessário. Para usar este plug-in, digite o seguinte:

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

      Esse comando executa o certbot com o plug-in --nginx, usando -d para especificar os nomes para os quais desejamos um certificado válido.

      Se essa é a primeira vez que você executa o certbot, você será solicitado a informar um endereço de e-mail e concordar com os termos de serviço. Após fazer isso, o certbot se comunicará com o servidor da Let’s Encrypt, executando posteriormente um desafio para verificar se você controla o domínio para o qual está solicitando um certificado.

      Se tudo correr bem, o certbot perguntará como você quer definir suas configurações de 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):

      Select your choice then hit ​​​ENTER​​​​​. A configuração será atualizada e o Nginx recarregará para aplicar as novas configurações. O certbot será encerrado com uma mensagem informando que o processo foi concluído e onde os certificados estão armazenados:

      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

      Se seguiu as instruções de instalação do Nginx nos pré-requisitos, a permissão do perfil HTTP redundante não será mais necessária:

      • sudo ufw delete allow 'Nginx HTTP'

      Para verificar a configuração, vamos navegar novamente até o seu domínio, usando https://:

      https://your_domain
      

      Você deve ver novamente o resultado do seu aplicativo, junto com o indicador de segurança do seu navegador, que deve indicar que o site está protegido.

      Conclusão

      Neste guia, você criou e protegeu um aplicativo Flask simples em um ambiente virtual Python. Você criou um ponto de entrada da WSGI para que qualquer servidor de aplicativo compatível com a WSGI possa interagir com ela; depois, configurou o servidor de app uWSGI para fornecer essa função. Depois, criou um arquivo de serviço systemd para iniciar automaticamente o servidor do aplicativo na inicialização. Você também criou um bloco de servidor Nginx que passa o tráfego Web do cliente para o servidor do aplicativo - retransmitindo pedidos externos - e protegeu o tráfego para seu servidor com o Let’s Encrypt.

      O Flask é um framework muito simples - mas extremamente flexível, destinado a fornecer funcionalidade a seus aplicativos sem ser restritivo demais em termos de estrutura e design. Você pode usar a pilha geral descrita neste guia para atender os aplicativos flask que projetar.



      Source link

      Cómo hacer funcionar aplicaciones de Flask con uWSGI y Nginx en Ubuntu 18.04


      Introducción

      A través de esta guía, creará una aplicación de Python utilizando el microframework de Flask en Ubuntu 18.04. En la mayor parte de este artículo se abordarán la configuración del servidor de la aplicación uWSGI y la forma de iniciar la aplicación y configurar Nginx para que funcione como un proxy inverso de cliente.

      Requisitos previos

      Antes de comenzar con esta guía, deberá contar con lo siguiente:

      • Un servidor con Ubuntu 18.04 instalado y un usuario no root con privilegios sudo. Siga nuestra guía de configuración inicial para servidores a modo de orientación.
      • Nginx instalado conforme a los pasos 1 y 2 de Cómo instalar Nginx en Ubuntu 18.04.
      • Un nombre de dominio configurado para que apunte a su servidor. Puede adquirir uno en Namecheap obtener uno de forma gratuita en Freenom. Puede aprender a apuntar dominios a DigitalOcean siguiendo la documentación sobre dominios y DNS pertinente. Asegúrese de crear los siguientes registros DNS:

        • Un registro A con your_domain orientado a la dirección IP pública de su servidor.
        • Un registro A con www.your_domain orientado a la dirección IP pública de su servidor.
      • Conocimientos sobre uWSGI, nuestro servidor de aplicaciones y la especificación WSGI. En esta discusión de definiciones y conceptos se abordan ambos en profundidad.

      Paso 1: Instalar los componentes desde los repositorios de Ubuntu

      Nuestro primer paso será instalar todo lo que necesitamos desde los repositorios de Ubuntu. Instalaremos pip, el administrador de paquetes de Python, para administrar nuestros componentes de Python. También obtendremos los archivos de desarrollo de Python necesarios para crear uWSGI.

      Primero, actualizaremos el índice de paquetes locales e instalaremos los paquetes que nos permitirán crear nuestro entorno de Python. Entre ellos está phyton3-pip, junto con paquetes y herramientas de desarrollo adicionales que se necesitan para un entorno de programación sólido:

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

      Una vez implementados estos paquetes, crearemos un entorno virtual para nuestro proyecto.

      Paso 2: Crear un entorno virtual de Python

      A continuación, configuraremos un entorno virtual para aislar nuestra aplicación de Flask de los otros archivos de Python del sistema.

      Comience instalando el paquete phyton3-venv, que instalará el módulo venv:

      • sudo apt install python3-venv

      Luego, crearemos un directorio principal para nuestro proyecto de Flask. Después de crearlo, posiciónese en él:

      • mkdir ~/myproject
      • cd ~/myproject

      Cree un entorno virtual para almacenar los requisitos de Python de su proyecto de Flask escribiendo lo siguiente:

      • python3.6 -m venv myprojectenv

      Con esto se instalará una copia local de Python y pip en un directorio llamado myprojectenv dentro del directorio de su proyecto.

      Antes de instalar aplicaciones dentro del entorno virtual, deberá activarlo. Hágalo escribiendo lo siguiente:

      • source myprojectenv/bin/activate

      Su mensaje cambiará para indicar que ahora realiza operaciones dentro del entorno virtual. Se parecerá a esto: (myprojectenv)user@host:~/myproject$.

      Paso 3: Configurar una aplicación de Flask

      Ahora que se encuentra en su entorno virtual, podrá instalar Flask y uWSGI y comenzar a diseñar su aplicación.

      Primero, instalaremos wheel con la instancia local de pip para asegurarnos de que nuestros paquetes se instalen aunque falten archivos de wheel:

      Nota: Independientemente de la versión de Phyton que use, cuando se active el entorno virtual deberá utilizar el comando pip (no pip3).

      A continuación, instalaremos Flask y uWSGI:

      Creación de una aplicación de ejemplo

      Ahora que dispone de Flask, puede crear una aplicación sencilla. Flask es un microframework. No cuenta con muchas de las herramientas que podrían incluirse en frameworks con más características y existe sobre todo como un módulo que puede importar a sus proyectos para que pueda inicializar una aplicación web.

      Aunque la complejidad podría ser mayor, crearemos nuestra aplicación de Flask en un único archivo, llamado “myproject.py:

      • nano ~/myproject/myproject.py

      El código de aplicación residirá en este archivo. Importará Flask y creará una instancia de un objeto de Flask. Puede utilizarlo para definir las funciones que deberían ejecutarse cuando se solicita una ruta específica:

      ~/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')
      

      Esto define básicamente el contenido que se presentará al acceder al dominio root. Guarde y cierre el archivo cuando termine.

      Si siguió la guía de configuración inicial para servidores, debería tener activado un firewall UFW. Para probar la aplicación, debe permitir el acceso al puerto 5000:

      Ahora podrá probar su aplicación de Flask escribiendo lo siguiente:

      Verá un resultado como el siguiente, en el cual se incluirá una advertencia útil que le recordará no utilizar esta configuración de servidor en la producción:

      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)

      Agregue :5000 al final de la dirección IP de su servidor en su navegador web y visítela:

      http://your_server_ip:5000
      

      Debería ver algo como esto:

      Aplicación de ejemplo de Flask

      Cuanto termine, pulse CTRL-C en la ventana de su terminal para detener el servidor de desarrollo Flask.

      Creación de un punto de entrada de WSGI

      A continuación, crearemos un archivo que servirá como punto de entrada para nuestra aplicación. Esto le indicará a nuestro servidor de uWSGI cómo interactuar con él.

      Llamaremos al archivo wsgi.py:

      En él, importaremos la instancia de Flask desde nuestra aplicación y luego la ejecutaremos:

      ~/myproject/wsgi.py

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

      Guarde y cierre el archivo cuando termine.

      Paso 4: Configurar uWSGI

      Su aplicación quedará, así, escrita con un punto de entrada establecido. Ahora, podemos continuar con la configuración de uWSGI.

      Prueba del servicio de uWSGI

      Haremos una prueba para comprobar que uWSGI pueda hacer funcionar nuestra aplicación.

      Lo haremos con solo pasarle el nombre de nuestro punto de entrada. Se construye como el nombre del módulo (menos la extensión .py) más el nombre del elemento invocable dentro de la aplicación. En nuestro caso, es wsgi:app.

      También especificaremos el socket, de modo que se inicie en una interfaz disponible de forma pública, además del protocolo, para que utilice HTTP en lugar del protocolo binario uwsgi. Utilizaremos el mismo número de puerto, 5000, que abrimos antes:

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

      Visite de nuevo la dirección IP de su servidor con :5000 agregado al final en su navegador web:

      http://your_server_ip:5000
      

      Debería volver a ver el resultado de su aplicación:

      Aplicación de ejemplo de Flask

      Cuando confirme que funciona correctamente, pulse CTRL-C en la ventana de su terminal.

      Ya completamos las tareas de nuestro entorno virtual, por lo que podemos desactivarlo:

      Ahora todos los comandos de Python usarán de nuevo el entorno de Phyton del sistema.

      Creación de un archivo de configuración de uWSGI

      Ya comprobó que uWSGI puede hacer funcionar su aplicación. Sin embargo, en última instancia le convendrá algo más sólido para el uso a largo plazo. Puede crear un archivo de configuración de uWSGI con las opciones pertinentes para esto.

      Dispondremos ese archivo en nuestro directorio de proyectos y lo llamaremos myproject.ini:

      • nano ~/myproject/myproject.ini

      En su interior, empezaremos con el encabezado de [uwsgi] a fin de que uWSGI esté al tanto para aplicar la configuración. Especificaremos dos cosas: el propio módulo, haciendo referencia al archivo wsgi.py menos la extensión, y el elemento invocable dentro del archivo, app:

      ~/myproject/myproject.ini

      [uwsgi]
      module = wsgi:app
      

      A continuación, le diremos a uWSGI que se inicie en el modo maestro y cree cinco procesos de trabajador para proporcionar solicitudes reales:

      ~/myproject/myproject.ini

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

      Cuando hizo pruebas, expuso uWSGI en un puerto de red. Sin embargo, utilizará Nginx para gestionar las conexiones de clientes reales, que luego transmitirán solicitudes a uWSGI. Debido a que estos componentes funcionan en la misma computadora, es preferible un socket de Unix porque es más rápido y seguro. Llamaremos al socket myproject.sock y lo dispondremos en este directorio.

      También cambiaremos los permisos del socket. Más adelante, daremos al grupo de Nginx la propiedad del proceso de uWSGI, por lo que debemos verificar que el propietario de grupo del socket pueda leer información de él y enviarle texto. También eliminaremos el socket cuando se detenga el proceso agregando la opción vacuum:

      ~/myproject/myproject.ini

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

      Lo último que haremos será establecer la opción die-on-term. Esto puede ayudar a garantizar que el sistema init y uWSGI tengan los mismos supuestos sobre lo que significa cada señal de proceso. Al configurar esto se alinean los dos componentes del sistema y se implementa el comportamiento esperado:

      ~/myproject/myproject.ini

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

      Posibleemente haya observado que no especificamos un protocolo como hicimos desde la línea de comandos. Esto se debe a que, de forma predeterminada, uWSGI se comunica usando el protocolo de uwsgi, un protocolo binario rápido diseñado para la comunicación con otros servidores. Nginx puede comunicarse a través de este protocolo de forma nativa, por lo que es mejor usarlo que forzar la comunicación por HTTP.

      Cuando termine, guarde y cierre el archivo.

      Paso 5: Crear un archivo de unidad systemd

      A continuación, crearemos el archivo de unidad de servicio systemd. Crear un archivo de unidad systemd permitirá que el sistema init de Ubuntu inicie automáticamente uWSGI y haga funcionar la aplicación de Flask cuando el servidor se cargue.

      Cree un archivo de unidad terminado en .service dentro del directorio /etc/systemd/system para empezar:

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

      En su interior, empezaremos con la sección [Unit] que se usa para especificar metadatos y dependencias. Aquí agregaremos una descripción de nuestro servicio e indicaremos al sistema init que lo inicie solo tras haber alcanzado el objetivo de red:

      /etc/systemd/system/myproject.service

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

      A continuación, abriremos la sección [Service]. Esto especificará el usuario y el grupo con los cuales deseamos que se ejecute el proceso. Otorgaremos la propiedad del proceso a nuestra cuenta de usuario normal, ya que tiene la propiedad de todos los archivos pertinentes. También otorgaremos la propiedad del grupo al grupo www-data para que Nginx pueda comunicarse fácilmente con los procesos de Gunicorn. No se olvide de sustituir el nombre de usuario por el suyo:

      /etc/systemd/system/myproject.service

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

      A continuación, planearemos los detalles del directorio de trabajo y estableceremos el entorno variable PATH para que el sistema init sepa que los ejecutables para el proceso están ubicados dentro de nuestro entorno virtual. También especificaremos el comando para iniciar el servicio. Systemd necesita que le proporcionemos la ruta completa al ejecutable de uWSGI, que se instala dentro de nuestro entorno virtual. Pasaremos el nombre del archivo de configuración .ini que creamos en el directorio de nuestro proyecto.

      No se olvide de sustituir el nombre del usuario y las rutas del proyecto por su propia información:

      /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
      

      Por último, vamos a añadiremos una sección [Install]. Esto indicará a systemd a qué deberá vincular este servicio si lo habilitamos para que se cargue en el inicio. Queremos que este servicio se inicie cuando el sistema multiusuario normal esté en funcionamiento:

      /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
      

      Con eso, nuestro archivo de servicio de systemd quedará completo. Guárdelo y ciérrelo ahora.

      Ya podemos iniciar el servicio uWSGI que creamos y activarlo para que se cargue en el inicio:

      • sudo systemctl start myproject
      • sudo systemctl enable myproject

      Comprobaremos el estado:

      • sudo systemctl status myproject

      Debería ver el siguiente resultado:

      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

      Si detecta errores, asegúrese de resolverlos antes de continuar con el tutorial.

      Paso 6: Configurar Nginx para solicitudes de proxy

      Ahora, nuestro servidor de aplicación uWSGI debería estar funcionando, esperando solicitudes en el archivo de socket del directorio del proyecto. Configuraremos Nginx para que transmita las solicitudes web a ese socket usando el protocolo uwsgi.

      Comencemos creando un nuevo archivo de configuración de bloque de servidor en el directorio sites-available de Nginx. Lo llamaremos myproject para que se adecue al resto de esta guía:

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

      Abra un bloque de servidor e indique a Nginx que escuche en el puerto predeterminado 80. También le indicaremos que utilice este bloque para solicitudes para el nombre de dominio de nuestro servidor:

      /etc/nginx/sites-available/myproject

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

      A continuación, agregaremos un bloque de ubicación que coincida con cada solicitud. Dentro de este bloque, incluiremos el archivo proxy_params que especifica algunos parámetros de proxy generales de uWSGI que deben configurarse. Luego, pasaremos las solicitudes al socket que definimos usando la directiva proxy_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;
          }
      }
      

      Guarde y cierre el archivo cuando termine.

      Para habilitar la configuración del bloque de servidor de Nginx que acaba de crear, vincule el archivo al directorio sites-enabled​​​:

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

      Con el archivo en ese directorio, podemos probar si hay errores de sintaxis escribiendo lo siguiente:

      Si no se indican problemas, reinicie el proceso de Nginx para que lea la nueva configuración:

      • sudo systemctl restart nginx

      Por último, ajustaremos el firewall de nuevo. Ya no necesitamos acceso a través del puerto 5000, por lo que podemos eliminar esta regla. Luego podemos permitir el acceso al servidor de Nginx:

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

      Ahora debería poder visitar el nombre de dominio de su servidor en su navegador web:

      http://your_domain
      

      Debería ver el resultado de su aplicación:

      Aplicación de ejemplo de Flask

      Si encuentra algún error, intente verificar lo siguiente:

      • sudo less /var/log/nginx/error.log: verifica los registros de error de Nginx.
      • sudo less /var/log/nginx/access.log: verifica los registros de acceso de Nginx.
      • sudo journalctl -u nginx: verifica los registros de proceso de Nginx.
      • sudo journalctl -u myproject: verifica los registros de uWSGI de su aplicación de Flask.

      Paso 7: Proteger la aplicación

      Para asegurarse de que el tráfico hacia su servidor siga siendo seguro, obtendremos un certificado SSL para su dominio. Existen varias formas de hacerlo. Entre otras, obtener un certificado gratuito de Let’s Encrypt, generar un certificado autofirmado o adquirir uno de otro proveedor y configurar Nginx para que lo utilice siguiendo los pasos 2 a 6 de Cómo crear un certificado SSL autofirmado para Nginx en Ubuntu 18.04. Por motivos de conveniencia, elegiremos la primera opción.

      Primero, agregue el repositorio de Certbot de Ubuntu:

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

      Deberá seleccionar ENTER para aceptar.

      Instale el paquete de Nginx de Certbot con apt:

      • sudo apt install python-certbot-nginx

      Certbot ofrece varias alternativas para obtener certificados SSL a través de complementos. El complemento de Nginx se encargará de reconfigurar Nginx y volver a cargar la configuración cuando sea necesario. Para utilizar este complemento, escriba lo siguiente:

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

      Con esto, se ejecuta certbot con el complemento --nginx usando -d para especificar los nombres para los cuales deseamos que el certificado tenga validez.

      Si es la primera vez que ejecuta certbot, se le solicitará introducir una dirección de correo electrónico y aceptar las condiciones de servicio. Después de esto, certbot se comunicará con el servidor de Let’s Encrypt y realizará una comprobación a fin de verificar que usted controle el dominio para el cual solicite un certificado.

      Si la comprobación se realiza correctamente, certbot le preguntará cómo desea configurar sus ajustes de 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):

      Seleccione su elección y luego ENTER. La configuración se actualizará y Nginx se volverá a cargar para aplicar los ajustes nuevos. certbot concluirá con un mensaje que le indicará que el proceso tuvo éxito e indicará la ubicación de almacenamiento de sus certificados:

      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

      Si siguió las instrucciones de instalación de Nginx en los requisitos previos, ya no necesitará la asignación de perfil HTTP redundante:

      • sudo ufw delete allow 'Nginx HTTP'

      Para verificar la configuración, acceda una vez más a su dominio utilizando https://:

      https://your_domain
      

      Una vez más, debería ver el resultado de su aplicación junto con el indicador de seguridad de su navegador, que debería indicar que el sitio está protegido.

      Conclusión

      A través de esta guía, creó y aseguró una aplicación de Flask simple dentro de un entorno virtual de Python. Creó un punto de entrada de WSGI para que cualquier servidor de aplicación con capacidad para WSGI pueda interactuar con él y configuró el servidor de aplicación de uWSGI para proporcionar esta función. Luego, creó un archivo de servicio systemd para iniciar automáticamente el servidor de aplicación en el inicio. También creó un bloque de servidor de Nginx que transmite el tráfico de clientes web al servidor de la aplicación, y reenvía solicitudes externas, y protegió el tráfico hacia su servidor con Let’s Encrypt.

      Flask es un framework muy sencillo, pero extremadamente flexible, diseñado para proporcionar funcionalidad a sus aplicaciones sin ser demasiado restrictivo respecto de la estructura y del diseño. Puede utilizar la pila general descrita en esta guía para hacer funcionar las aplicaciones de Flask que diseñe.



      Source link