Автор выбрал Tech Education Fund для получения пожертвования в рамках программы Write for DOnations.
Docker — это приложение с открытым исходным кодом, позволяющее администраторам создавать, развертывать и воспроизводить приложения с помощью контейнеров. Контейнеры — это пакеты, в которых содержатся все зависимости, необходимые для запуска приложения на уровне операционной системы. Это означает, что каждое приложение, развернутое с помощью Docker, имеет собственную среду, и его требования обрабатываются отдельно.
Flask — это веб-микроструктура, построенная на базе Python. Она называется микроструктурой, потому что не требует для работы специальных инструментов или плагинов. Микроструктура Flask отличается компактностью, гибкостью и высоким уровнем структурирования, за счет чего она более предпочтительна по сравнению с другими программными структурами.
Развертывание приложения Flask с помощью Docker позволит вам воспроизводить приложение на разных серверах с минимальными изменениями конфигурации.
В этом обучающем модуле вы создадите приложение Flask и выполните его развертывание с помощью Docker. Также в этом обучающем модуле мы расскажем, как обновить приложение после развертывания.
Для выполнения этого руководства вам потребуется следующее:
Вначале вы создадите структуру каталогов, где будет размещено ваше приложение 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, в том числе 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
, которы вы создадите после сохранения этого файла. Добавьте в новый файл следующий код:
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!
строка для пользователей, посещающих вашу веб-страницу:
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:
[uwsgi]
module = main
callable = app
master = true
Этот код определяет модуль, из которого будет обслуживаться приложение Flask. В данном случае это файл main.py
, который здесь указывается как main
. Опция callable
указывает uWSGI использовать экземпляр app
, экспортированный основным приложением. Параметр master
позволяет вашему приложению продолжать работать, и поэтому даже при перезагрузке всего приложения время простоя будет минимальным.
Теперь создайте файл main.py
, который будет главной точкой входа в приложение. Точка входа сообщает uWSGI, как следует взаимодействовать с приложением.
- sudo nano main.py
Далее скопируйте и вставьте в файл следующий код. Этот код импортирует экземпляр Flask под названием app
из пакета приложения, созданного на предыдущих шагах.
from app import app
Наконец, создайте файл requirements.txt
, чтобы указать, какие зависимости диспетчер пакетов pip
установит в вашу среду Docker:
- sudo nano requirements.txt
Добавьте следующую строку для добавления Flask в качестве зависимости:
Flask==1.0.2
В нем указывается устанавливаемая версия Flask. На момент составления настоящего обучающего модуля последней версией Flask была версия 1.0.2
. Вы можете проверить обновления Flask на официальном сайте.
Сохраните и закройте файл. Вы успешно настроили свое приложение Flask и готовы к настройке Docker.
На этом шаге вы создадите два файла для развертывания Docker, Dockerfile
и start.sh
. Dockerfile
— это текстовый документ, содержащий команды, используемые для сборки образа. Файл start.sh
— это скрипт оболочки, который построит образ и создаст контейнер из файла Dockerfile
.
Вначале создайте файл Dockerfile
.
- 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 и образов ОС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
:
- 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}
Первая строка называется 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 и построения контейнера на основе этого образа:
- 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, содержащую заголовок и текст.
<!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 для рендеринга веб-страницы для пользователя.
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. Запустите следующую команду для повторного построения контейнера:
- 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
Добавьте в конец файла выделенную строку:
module = main
callable = app
master = true
touch-reload = /app/uwsgi.ini
Эта строка указывает файл, изменение которого запускает перезагрузку приложения. После внесения изменений сохраните и закройте файл.
Чтобы продемонстрировать это, внесите в ваше приложение небольшое изменение. Для начала откройте файл app/views.py
:
- 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
для активации условия:
- sudo touch uwsgi.ini
Еще раз перезагрузите главную страницу приложения в браузере. Вы увидите, что в приложение включены изменения:
На этом шаге вы выберете условие команды touch-reload
, с которым приложение будет обновляться после внесения изменений.
В этом обучающем модуле вы создали и развернули приложение Flask в контейнере Docker. Также вы настроили команду touch-reload
для обновления приложения без необходимости перезапуска контейнера.
Новое приложение в Docker можно будет легко масштабировать. Чтобы узнать больше об использовании Docker, ознакомьтесь с официальной документацией.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!