Поиск по сайту:

Как создать и развернуть приложение Flask с помощью Docker в Ubuntu 18.04


Автор выбрал программу Write for DOnations.

Введение

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

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

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

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

Предпосылки

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

  • Пользователь без полномочий root с привилегиями sudo, настроенными в соответствии с руководством Initial Server Setup with Ubuntu 18.04.
  • Один сервер Ubuntu 18.04 с установленным Docker, настроенный с помощью образа Docker, доступного в один клик.
  • Руководство по установке Nginx в Ubuntu 18.04.

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

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

  1. sudo mkdir /var/www/TestApp

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

  1. cd /var/www/TestApp

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

  1. sudo mkdir -p app/static app/templates

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

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

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

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

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

  1. sudo nano app/__init__.py

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

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

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

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

Создав файл __init__.py, вы готовы создать файл views.py в каталоге app. Этот файл будет содержать большую часть логики вашего приложения.

  1. sudo nano app/views.py

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

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.

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

  1. sudo nano uwsgi.ini

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

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

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

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

  1. sudo nano main.py

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

from app import app

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

  1. sudo nano requirements.txt

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

Flask==1.0.2

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

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

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

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

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

  1. sudo nano Dockerfile

Затем добавьте нужную конфигурацию в 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 и образов ОС.

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

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

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

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

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

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

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

sudo nano start.sh

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

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

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

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

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

Выполните скрипт start.sh, чтобы создать образ Docker и создать контейнер из полученного образа:

  1. sudo bash start.sh

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

  1. sudo docker ps

Вы получите вывод, показывающий контейнеры:

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:

  1. sudo nano app/templates/home.html

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


<!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, чтобы он обслуживал только что созданный файл:

  1. sudo nano app/views.py

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

from flask import render_template
...

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

...

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

Обновленный файл 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. Выполните следующую команду, чтобы перестроить контейнер:

  1. sudo docker stop docker.test && sudo docker start docker.test

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

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

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

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

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

Чтобы реализовать это, начните с открытия файла uwsgi.ini:

  1. sudo nano uwsgi.ini

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

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

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

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

  1. sudo nano app/views.py

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

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, чтобы активировать условие:

  1. sudo touch uwsgi.ini

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

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

Заключение

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

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