Перейти к содержимому
Главная страница » Flask приложение в Docker

Flask приложение в Docker

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

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

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

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

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

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

  • Пользователь без права root с правами sudo настраивается, следуя руководству по начальной настройке сервера с Ubuntu 23.04.
  • Один сервер Ubuntu 23.04 с установленным Docker;
  • Установленный Nginx.

Структура простого Flask приложения

Структура моего Flask-приложения будет иметь следующий вид:

TestApp
├── uwsgi.ini
├── main.py
├── requirements.txt
├── Dockerfile
├── start.sh
└── app
    ├── __init__.py   
    ├── static         
    ├── views.py  
    └── templates
        └── home.html

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

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

sudo mkdir /var/www/TestApp

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

cd /var/www/TestApp

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

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 каталог является пакетом и должен рассматриваться как таковой.

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

sudo nano app/__init__.py

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

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

/var/www/TestApp/app/__init__.py

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

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

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

sudo nano app/views.py

Затем добавьте код в свой 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.

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

sudo nano uwsgi.ini

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

/var/www/TestApp/uwsgi.ini

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

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

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

sudo nano main.py

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

/var/www/TestApp/main.py

from app import app

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

sudo nano requirements.txt

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

/var/www/TestApp/requirements.txt

Flask==1.0.2

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

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

Настройка Docker

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

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

sudo nano 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 и образов ОС.

В первых двух строках указывается родительский образ, который вы будете использовать для запуска приложения и установки командного процессора 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 скрипт:

sudo nano 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 каталогом контейнера.

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

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

sudo bash start.sh

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

sudo docker ps

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

OutputCONTAINER 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. Далее вы будете использовать шаблоны для отображения контента пользователям.

Отправка файлов шаблонов

Шаблоны — это файлы, которые отображают статическое и динамическое содержимое пользователям, посещающим ваше приложение. На этом шаге вы создадите 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 файл для обслуживания вновь созданного файла:

sudo nano 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.

Обновление приложения

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

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

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

sudo nano uwsgi.ini

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

/var/www/TestApp/uwsgi.ini

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

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

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

sudo nano 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 для активации условия:

sudo touch uwsgi.ini

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

Обновлена домашняя страница

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

Заключение

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

Источник

Ссылки:

How to Dockerize a Flask Application

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *