One place for hosting & domains

      Создание и развертывание приложения Flask с использованием Docker в Ubuntu 18.04


      Автор выбрал Tech Education Fund для получения пожертвования в рамках программы Write for DOnations.

      Введение

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

      Flask — это веб-микроструктура, построенная на базе Python. Она называется микроструктурой, потому что не требует для работы специальных инструментов или плагинов. Микроструктура Flask отличается компактностью, гибкостью и высоким уровнем структурирования, за счет чего она более предпочтительна по сравнению с другими программными структурами.

      Развертывание приложения Flask с помощью Docker позволит вам воспроизводить приложение на разных серверах с минимальными изменениями конфигурации.

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

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

      Для выполнения этого руководства вам потребуется следующее:

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

      Вначале вы создадите структуру каталогов, где будет размещено ваше приложение Flask. В этом обучающем модуле мы создадим каталог TestApp в каталоге /var/www, но вы можете изменить команду и использовать любое другое название.

      • sudo mkdir /var/www/TestApp

      Перейдите в созданный каталог TestApp:

      Создайте базовую структуру папок для приложения Flask:

      • sudo mkdir -p app/static app/templates

      Флаг -p означает, что команда mkdir создаст каталог и все его родительские каталоги, которых еще не существует. В данном случае команда mkdir создаст родительский каталог app в процессе создания каталогов static и templates.

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

      В каталоге static хранятся различные ресурсы, в том числе файлы изображений, CSS и JavaScript. В каталоге templates хранятся шаблоны HTML для вашего проекта.

      Теперь базовая структура папок готова, и вы можете создать все файлы, необходимые для запуска приложения Flask. Вначале создайте файл __init__.py в каталоге app. Этот файл сообщает интерпретатору Python, что каталог app является пакетом, и его следует рассматривать именно как пакет.

      Запустите следующую команду для создания файла:

      • sudo nano app/__init__.py

      Пакеты в Python позволяют группировать модули в логические пространства имен или иерархии. Этот подход позволяет разбивать код на отдельные управляемые блоки, которые выполняют конкретные функции.

      Затем вы добавитье в файл __init__.py код, который создаст экземпляр Flask и импортирует логику из файла views.py, которы вы создадите после сохранения этого файла. Добавьте в новый файл следующий код:

      /var/www/TestApp/__init__.py

      from flask import Flask
      app = Flask(__name__)
      from app import views
      

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

      После создания файла __init__.py вы будете готовы создать файл views.py в каталоге app. В этом файле будет содержаться большая часть логики вашего приложения.

      Затем добавьте код в файл views.py. Этот код будет возвращать фразу hello world! строка для пользователей, посещающих вашу веб-страницу:

      /var/www/TestApp/app/views.py

      from app import app
      
      @app.route('/')
      def home():
         return "hello world!"
      

      Строка @app.route над функцией называется декоратором. Декораторы изменяют функцию, которая следует за ними. В данном случае декторатор указывает Flask, какой URL активирует функцию home(). Текст hello world, возвращаемый функцией home, будет отображаться пользователю в браузере.

      Создав файл views.py, вы готовы к созданию файла uwsgi.ini. Этот файл будет содержать конфигурации uWSGI для нашего приложения. uWSGI — это опция развертывания Nginx, представляющая собой как протокол, так и сервер приложений, который может обслуживать протоколы uWSGI, FastCGI и HTTP.

      Для создания этого файла запустите следующую команду:

      Затем добавьте в файл следующее содержание для настройки сервера uWSGI:

      /var/www/TestApp/uwsgi.ini

      [uwsgi]
      module = main
      callable = app
      master = true
      

      Этот код определяет модуль, из которого будет обслуживаться приложение Flask. В данном случае это файл main.py, который здесь указывается как main. Опция callable указывает uWSGI использовать экземпляр app, экспортированный основным приложением. Параметр master позволяет вашему приложению продолжать работать, и поэтому даже при перезагрузке всего приложения время простоя будет минимальным.

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

      Далее скопируйте и вставьте в файл следующий код. Этот код импортирует экземпляр Flask под названием app из пакета приложения, созданного на предыдущих шагах.

      /var/www/TestApp/main.py

      from app import app
      

      Наконец, создайте файл requirements.txt, чтобы указать, какие зависимости диспетчер пакетов pip установит в вашу среду Docker:

      • sudo nano requirements.txt

      Добавьте следующую строку для добавления Flask в качестве зависимости:

      /var/www/TestApp/app/requirements.txt

      Flask==1.0.2
      

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

      Сохраните и закройте файл. Вы успешно настроили свое приложение Flask и готовы к настройке Docker.

      Шаг 2 — Настройка Docker

      На этом шаге вы создадите два файла для развертывания Docker, Dockerfile и start.sh. Dockerfile — это текстовый документ, содержащий команды, используемые для сборки образа. Файл start.sh — это скрипт оболочки, который построит образ и создаст контейнер из файла Dockerfile.

      Вначале создайте файл Dockerfile.

      Далее добавьте в файл Dockerfile желаемую конфигурацию. Эти команды указывают, как будет построен образ, и какие дополнительные требования будут в него включены.

      /var/www/TestApp/Dockerfile

      FROM tiangolo/uwsgi-nginx-flask:python3.6-alpine3.7
      RUN apk --update add bash nano
      ENV STATIC_URL /static
      ENV STATIC_PATH /var/www/app/static
      COPY ./requirements.txt /var/www/requirements.txt
      RUN pip install -r /var/www/requirements.txt
      

      В этом примере образ Docker будет построен на основе существующего образа tiangolo/uwsgi-nginx-flask, который можно найти на ресурсе DockerHub. Этот конкретный образ Docker лучше многих других, потому что он поддерживает широкий спектр версий Python и образов ОСs.

      В первых двух строках указывается родительский образ, который вы будете использовать для запуска приложений и установки процессора команд bash и текстового редактора nano. Также он устанавливает клиент git для связи со службами хостинга контроля версий, такими как GitHub, GitLab и Bitbucket. ENV STATIC_URL /static — переменная среды, используемая для конкретного образа Docker. Она определяет статичную папку, где хранятся все ресурсы, включая образы, файлы CSS и файлы JavaScript.

      Последние две строки копируют в контейнер файл requirements.txt, чтобы его можно было выполнить, а затем выполняют синтаксический анализ файла requirements.txt для установки указанных зависимостей.

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

      Теперь вы установили файл Dockerfile и уже почти готовы написать скрипт start.sh, который построит для вас контейнер Docker. Прежде чем создавать скрипт start.sh, убедитесь, что у вас имеется открытый порт для использования в конфигурации. Чтобы проверить, свободен ли порт, запустите следующую команду:

      • sudo nc localhost 56733 < /dev/null; echo $?

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

      Когда вы найдете открытый порт для использования, создайте скрипт start.sh:

      Скрипт start.sh — это скрипт оболочки, создающий образ из файла Dockerfile и создающий контейнер на основе полученного образа Docker. Добавьте свою конфигурацию в новый файл:

      /var/www/TestApp/start.sh

      #!/bin/bash
      app="docker.test"
      docker build -t ${app} .
      docker run -d -p 56733:80 
        --name=${app} 
        -v $PWD:/app ${app}
      

      Первая строка называется shebang. Она указывает, что это файл bash, и что его нужно выполнять как команды. В следующей строке указывается, какое имя вы хотите присвоить образу и контейнеру, а также выполняется сохранение этого имени в переменной app. Следующая строка указывает Docker построить образ из файла Dockerfile, находящегося в текущем каталоге. В этом примере будет создан образ с именем docker.test.

      Последние три строки создают новый контейнер с именем docker.test с открытым портом 56733. Наконец, текущий каталог связывается с каталогом /var/www directory в контейнере.

      Флаг -d используется для запуска контейнера в режиме демона или в качестве фонового процесса. Флаг -p используется для привязки порта на сервере к конкретному порту контейнера Docker. В данном случае вы привязываете порт 56733 к порту 80 контейнера Docker. Флаг -v указывает, какой том Docker следует монтировать на контейнер. В данном случае вы монтируете весь каталог проекта в папку /var/www в контейнере Docker.

      Запустите скрипт start.sh для создания образа Docker и построения контейнера на основе этого образа:

      После завершения выполнения скрипта используйте следующую команду для вывода списка всех запущенных контейнеров:

      В результате будет выведен список контейнеров:

      Output

      CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 58b05508f4dd docker.test "/entrypoint.sh /sta…" 12 seconds ago Up 3 seconds 443/tcp, 0.0.0.0:56733->80/tcp docker.test

      Вы увидите, что контейнер docker.test запущен и работает. Теперь, когда контейнер работает, откройте в браузере IP-адрес на указанном порту: http://ip-address:56733

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

      Главная страница

      На этом шаге вы успешно развернули свое приложение Flask в контейнере Docker. Теперь вы используете шаблоны, чтобы показать пользователям контент.

      Шаг 3 — Работа с файлами шаблонов

      Шаблоны — это файлы, показывающие статичный и динамический контент пользователям вашего приложения. На этом шаге вы создадите шаблон HTML для создания главной страницы приложения.

      Вначале создайте файл home.html в каталоге app/templates:

      • sudo nano app/templates/home.html

      Добавьте код для вашего шаблона. Этот код создаст страницу HTML5, содержащую заголовок и текст.

      /var/www/TestApp/app/templates/home.html

      
      <!doctype html>
      
      <html lang="en-us">   
        <head>
          <meta charset="utf-8">
          <meta http-equiv="x-ua-compatible" content="ie=edge">
          <title>Welcome home</title>
        </head>
      
        <body>
          <h1>Home Page</h1>
          <p>This is the home page of our application.</p>
        </body>
      </html>
      

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

      Теперь измените файл app/views.py, чтобы обслуживать созданный файл:

      Вначале добавьте в начале файла следующую строку для импорта метода render_template из Flask. Этот метод проводит синтаксический анализ файла HTML для рендеринга веб-страницы для пользователя.

      /var/www/TestApp/app/views.py

      from flask import render_template
      ...
      

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

      /var/www/TestApp/app/views.py

      ...
      
      @app.route('/template')
      def template():
          return render_template('home.html')
      

      Обновленный файл app/views.py будет выглядеть примерно следующим образом:

      /var/www/TestApp/app/views.py

      from flask import render_template
      from app import app
      
      @app.route('/')
      def home():
          return "Hello world!"
      
      @app.route('/template')
      def template():
          return render_template('home.html')
      

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

      Чтобы эти изменения вступили в силу, вам нужно будет остановить и перезапустить контейнеры Docker. Запустите следующую команду для повторного построения контейнера:

      • sudo docker stop docker.test && sudo docker start docker.test

      Откройте свое приложение по адресу http://your-ip-address:56733/template, чтобы увидеть, как выводится новый шаблон.

      главная страница

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

      Шаг 4 — Обновление приложения

      Иногда в приложение бывает нужно внести изменения. Это может быть установка новых требований, обновление контейнера Docker или внесение изменений в код HTML и логику. В этом разделе вы настроите команду touch-reload для внесения этих зменений без перезапуска контейнера Docker.

      Функция автоматической перезагрузки Python отслеживает изменения во всей файловой системе и обновляет приложение при обнаружении изменений. Автоматическая перезагрузка не рекомендуется в производственной среди, поскольку она может очень быстро увеличить нагрузку на ресурсы системы. На этом шаге вы используете команду touch-reload для отслеживания изменений определенного файла и перезагрузке контейнера в случае обновления или замены файла.

      Для реализации этой функции откройте файл uwsgi.ini:

      Добавьте в конец файла выделенную строку:

      /var/www/TestApp/uwsgi.ini

      module = main
      callable = app
      master = true
      touch-reload = /app/uwsgi.ini
      

      Эта строка указывает файл, изменение которого запускает перезагрузку приложения. После внесения изменений сохраните и закройте файл.

      Чтобы продемонстрировать это, внесите в ваше приложение небольшое изменение. Для начала откройте файл app/views.py:

      Замените строку, возвращаемую функцией home:

      /var/www/TestApp/app/views.py

      from flask import render_template
      from app import app
      
      @app.route('/')
      def home():
          return "<b>There has been a change</b>"
      
      @app.route('/template')
      def template():
          return render_template('home.html')
      

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

      Если вы откроете главную страницу приложения по адресу http://ip-address:56733, вы увидите, что изменения не отражаются. Это связано с тем, что условием перезагрузки будет изменение в файле uwsgi.ini. Чтобы перезагрузить приложение, используйте команду touch для активации условия:

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

      Главная страница обновлена

      На этом шаге вы выберете условие команды touch-reload, с которым приложение будет обновляться после внесения изменений.

      Заключение

      В этом обучающем модуле вы создали и развернули приложение Flask в контейнере Docker. Также вы настроили команду touch-reload для обновления приложения без необходимости перезапуска контейнера.

      Новое приложение в Docker можно будет легко масштабировать. Чтобы узнать больше об использовании Docker, ознакомьтесь с официальной документацией.



      Source link