Главная/Development workflow/Обзор

Раздел 10. Development workflow

Контейнеризация окупается, когда новый разработчик поднимает проект одной командой и получает то же окружение, что и все остальные. Она же становится обузой, когда каждое изменение строки кода требует пересборки образа на две минуты.

Раздел строит рабочий процесс, в котором обе цели совместимы: production-образ остаётся минимальным и воспроизводимым, а разработка идёт с hot reload, отладчиком и мгновенной обратной связью. Ключ — разделение конфигураций, а не компромисс между ними.

Раздел также закрывает вопросы, которые возникают у каждой команды: где хранить .env, как выполнять миграции, как не набирать одни и те же длинные команды и как встроить линтеры и type checking в тот же процесс.

Цели обучения

После раздела учащийся сможет:

  • разделить development и production образы, не дублируя Dockerfile;
  • настроить hot reload через bind mount и объяснить, что при этом теряется;
  • объяснить, почему установленные в образе пакеты «пропадают» при монтировании кода, и обойти это;
  • настроить удалённую отладку Python-приложения в container из IDE;
  • организовать работу с .env так, чтобы секреты не попадали в репозиторий;
  • выполнять database migrations в контейнеризованной среде воспроизводимым способом;
  • создать disposable-окружение, которое поднимается и удаляется одной командой;
  • автоматизировать рутину через Makefile и вспомогательные скрипты;
  • запускать linting, formatting и type checking согласованно локально и в CI.

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

Материалы

  1. Development и production образы
    Разные требования к двум образам. Один Dockerfile с несколькими стадиями против двух файлов. Стадия dev поверх общей базы. Дополнительные инструменты только в dev. Организация через compose.override.yaml и --target. Как не допустить попадания dev-зависимостей в production.

  2. Hot reload
    Монтирование исходного кода. uvicorn --reload и flask --debug: как работают и почему только для разработки. Проблема перекрытия каталогов из образа. Права на файлы, создаваемые приложением. Compose develop.watch как альтернатива bind mount. Ограничения на больших проектах.

  3. Отладка в container
    docker compose exec и запуск отладочной сессии. debugpy и подключение из IDE, проброс порта отладчика. Отладка при нескольких worker-процессах. Логирование как основной инструмент отладки в контейнеризованной среде. Что делать, когда в образе нет shell.

  4. Database migrations
    Три подхода: миграции при старте приложения, отдельный сервис в Compose, ручной запуск. Trade-offs каждого. Ожидание готовности базы. Идемпотентность и повторный запуск. Откат миграций. Тестовая база и её пересоздание.

  5. Автоматизация
    Makefile для типовых операций и почему он удобнее набора скриптов. Bash helper scripts и их границы. pre-commit в контейнеризованном проекте. Запуск ruff, mypy, pytest одинаково локально и в CI. Единый источник правды для конфигурации инструментов.

  6. Практические задания
    Лабораторные задания раздела с проверкой результата.

Рекомендуемый порядок чтения

Последовательный: 01 → 02 → 03 → 04 → 05 → exercises.

Урок 03 можно пропустить, если вы отлаживаете логами, — но вернитесь к нему, когда столкнётесь с ошибкой, воспроизводящейся только в container.

Практические задания

ЗаданиеТип
1Собрать один Dockerfile с двумя стадиями и проверить, что dev-зависимостей нет в production-образеобяз.
2Настроить hot reload для FastAPI и убедиться, что изменение кода применяется без пересборкиобяз.
3Воспроизвести исчезновение установленных пакетов при монтировании кода и решить проблемуобяз.
4Вынести миграции в отдельный сервис и проверить порядок запускаобяз.
5Написать Makefile с целями up, down, test, lint, migrate, shellобяз.
6Подключить отладчик IDE к процессу внутри container и остановиться на breakpointдоп.
7Настроить pre-commit так, чтобы он использовал те же версии инструментов, что и CIдоп.
8Создать команду, которая полностью пересоздаёт тестовую базу с нулядоп.
9Разработчик изменил requirements.txt, но новый пакет не появился в контейнере. Объяснитьдиаг.
10Организовать окружение так, чтобы файлы, созданные приложением в bind mount, принадлежали текущему пользователю host

Полные формулировки — в exercises.md.

Критерии завершения раздела

Раздел пройден, когда учащийся может без подсказок:

  1. Объяснить, чем dev-образ должен отличаться от production-образа, и назвать три конкретных отличия.
  2. Настроить проект так, чтобы docker compose up давал рабочее окружение с hot reload.
  3. Объяснить, почему bind mount кода может «сломать» установленные зависимости.
  4. Выбрать подход к миграциям для конкретного проекта и обосновать выбор.
  5. Свести типовые операции проекта к пяти-семи командам make.
  6. Гарантировать, что линтер локально и в CI даёт одинаковый результат.

Проверьте себя: Quiz 10. Затем выполните Проект 3. Multi-service stack.

Что дальше

Разработка налажена. Следующий раздел меняет требования: то, что удобно в разработке, в production обычно недопустимо.

Навигация

← Предыдущий раздел: Docker Compose
Вернуться к главному оглавлению
Следующий раздел: Production-ready containers →

Markdown на GitHub ↗