Этот файл описывает, как собрать Docker-образ для продакшн-версии приложения.
Ключевые моменты:
- Базовый образ:
python:3.11.4-slim-buster
(облегченная версия Python 3.11.4) - Рабочая директория:
/app
- Установка переменных окружения:
PYTHONPATH=/app
FLASK_APP=src/app.py
- Копирование и установка зависимостей из
requirements.txt
- Копирование всех файлов проекта в контейнер
- Открытие порта 5000
- Использование
entrypoint.sh
в качестве точки входа
Этот bash-скрипт служит точкой входа для Docker-контейнера.
Последовательность действий:
-
Запуск пайплайна:
echo "Starting pipeline" python3 src/pipeline.py
Это запускает процесс обучения модели.
-
Запуск Flask-сервера:
echo "Starting Flask server" flask run --host=0.0.0.0 --port=5000
Запускает Flask-приложение, делая его доступным на всех интерфейсах контейнера на порту 5000.
- Docker-образ собирается с использованием
Dockerfile.prod
. - При запуске контейнера выполняется
entrypoint.sh
. - Скрипт сначала запускает пайплайн - для обучения модели.
- Затем запускается Flask-сервер, который обслуживает API предсказаний.
Этот подход обеспечивает автоматизированное развертывание приложения в контейнере, включая подготовку модели и запуск веб-сервиса.
Папка src
содержит основной исходный код проекта для создания и обслуживания модели машинного обучения для классификации ирисов. Проект использует Flask для создания веб-сервиса, который предоставляет предсказания на основе обученной модели.
src/
│
├── app.py
├── inference.py
├── pipeline.py
├── preprocessing.py
└── train.py
Этот файл содержит основной сервис приложения, реализованный с использованием Flask.
Ключевые компоненты:
- Инициализация Flask-приложения
- Загрузка обученной модели
- Определение маршрутов:
/
: Проверка работоспособности сервиса/predict
: Эндпоинт для получения предсказаний
Маршрут /predict
принимает POST-запросы с данными об ирисе в формате JSON и возвращает предсказанный вид ириса.
Модуль для загрузки модели и выполнения предсказаний.
Основные функции:
load_model(model_path: str) -> BaseEstimator
: Загружает модель из файлаpredict(model: BaseEstimator, df: pd.DataFrame) -> List[int]
: Выполняет предсказания на новых данных
Этот файл содержит основной пайплайн проекта.
Основные этапы:
- Загрузка данных
- Разделение данных на обучающую и тестовую выборки
- Обучение модели
- Сохранение модели
- Оценка модели
Модуль для загрузки и предобработки данных.
Основные функции:
load_data() -> pd.DataFrame
: Загружает набор данных ирисов из sklearn и преобразует его в pandas DataFramesplit_data(df: pd.DataFrame, ...) -> Tuple[pd.DataFrame, pd.DataFrame]
: Разделяет данные на обучающую и тестовую выборки
Модуль для обучения и оценки модели.
Основные функции:
train_model(train: pd.DataFrame, ...) -> RandomForestClassifier
: Обучает модель случайного леса на тренировочных данныхevaluate_model(model: RandomForestClassifier, test: pd.DataFrame) -> float
: Оценивает точность модели на тестовых данных
- Скрипт
pipeline.py
запускает полный процесс от загрузки данных до оценки модели. - Обученная модель сохраняется в папке
models
. - Сервис в
app.py
загружает сохраненную модель и использует ее для предсказаний.
Этот проект демонстрирует полный цикл разработки модели машинного обучения: от подготовки данных и обучения модели до развертывания модели в виде веб-сервиса.
.github/workflows/main.yml
Этот CI/CD (Continuous Integration/Continuous Deployment) пайплайн настроен для автоматизации процессов проверки кода, сборки и развертывания приложения при push-событиях в ветку main
и при создании pull request'ов в эту ветку.
В пайплайне используются следующие переменные окружения, хранящиеся в секретах GitHub:
DOCKER_HUB_USER
: имя пользователя Docker HubDOCKER_HUB_REPOSITORY
: название репозитория в Docker HubDOCKER_HUB_ACCESS_TOKEN
: токен доступа к Docker HubIMAGE_NAME
: полное имя Docker-образаCONTAINER_NAME
: имя контейнера для запуска на сервереSERVER_HOST
: адрес сервера для развертыванияSERVER_USER
: имя пользователя на сервереSERVER_SSH_PRIVATE_KEY
: приватный SSH-ключ для доступа к серверу
Также определены некоторые константы:
PYTHON_VERSION
: версия Python ('3.x')LINTERS
: используемый линтер ('ruff')LINTER_CMD
: команда для запуска линтера
Как пользоваться GitHub Secrets: https://docs.github.com/ru/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions
Перед запуском CI/CD пайплайна необходимо заполнить свои GitHub Secrets согласно списка переменных.
Для использования Docker Hub нужно зарегистрироваться на hub.docker.com и создать токен доступа.
Чтобы развернуть ВМ в Yandex.Cloud для проекта необходимо перейти в директорию infrastructure, заполнить свои переменные в файле terraform.tfvars и запустить terraform:
cd infrastructure
terraform init
terraform plan
terraform apply
Этот этап выполняет проверку качества кода с помощью линтера.
Шаги:
- Checkout кода из репозитория
- Настройка окружения Python
- Установка зависимостей (линтера)
- Запуск линтера
Этот этап отвечает за сборку Docker-образа и его публикацию в Docker Hub.
Шаги:
- Checkout кода из репозитория
- Сборка Docker-образа с использованием
Dockerfile.prod
- Аутентификация в Docker Hub
- Публикация образа в Docker Hub
Этот этап выполняет развертывание приложения на удаленном сервере.
Шаги:
- Подключение к удаленному серверу по SSH
- Загрузка нового Docker-образа
- Остановка и удаление старого контейнера (если существует)
- Запуск нового контейнера
- При push в ветку
main
или создании pull request'а в эту ветку запускается joblint
. - Если
lint
прошел успешно, запускается jobbuild
. - После успешного выполнения
build
, запускается jobdeploy
.
Такая последовательность обеспечивает, что код проходит проверку качества перед сборкой, а развертывание происходит только после успешной сборки и публикации образа.
- Автоматизация: Весь процесс от проверки кода до развертывания автоматизирован, что уменьшает вероятность человеческой ошибки.
- Безопасность: Использование секретов GitHub для хранения чувствительных данных.
- Изоляция: Использование Docker обеспечивает изоляцию приложения и его зависимостей.
- Версионирование: Каждый образ тегируется с использованием SHA коммита, что обеспечивает четкое версионирование.
- Быстрый откат: В случае проблем можно быстро откатиться к предыдущей версии, просто запустив контейнер с предыдущим тегом.
Этот пайплайн обеспечивает надежный процесс непрерывной интеграции и развертывания, который можно легко адаптировать под конкретные нужды проекта.
Добавляем в Postman/Insomnia путь:
http://<внешний IP вашей ВМ>:5000/predict
Выбирает метод POST
В body передаем JSON:
{
"sepal_length": 5.1,
"sepal_width": 3.3,
"petal_length": 1.7,
"petal_width": 0.5,
}
В результате мы должны получить ответ в виде JSON:
{"prediction": "<класс ириса>"}
Quickstart for GitHub Actions
Документация GitHub Actions
Github Actions. Простой пример для уверенного знакомства
Строим домашний CI/CD при помощи GitHub Actions и Python