Зачем это нужно
Реальный ML-сервис редко живёт один: inference API, Redis для кэша, PostgreSQL для метаданных, MinIO для артефактов, mock Kafka для тестов. Запускать каждый контейнер отдельной командой docker run с сетями и томами — мучительно. Docker Compose описывает несколько сервисов в одном YAML-файле и поднимает их одной командой docker compose up.
Compose — инструмент для локальной разработки и интеграционных тестов. В продакшене вместо него используют Kubernetes и Helm, но логика та же: сервисы, сеть, volumes, переменные окружения.
Основные идеи
Файл compose.yaml. Верхний уровень — services. Каждый сервис — образ, порты, env, зависимости:
` services: api: build: . ports: - "8000:8000" environment: REDIS_URL: redis://redis:6379 depends_on: - redis
redis: image: redis:7-alpine ports: - "6379:6379" `
Имена сервисов (redis) становятся DNS-именами внутри сети Compose — API обращается к redis:6379, не к localhost.
Build vs image. build: . собирает из Dockerfile; image: nginx:1.25 тянет готовый образ. Для своего кода — build, для инфраструктуры — image.
Volumes. Данные в контейнере исчезают при docker compose down. Том сохраняет состояние:
` services: db: image: postgres:16 volumes: - pgdata:/var/lib/postgresql/data
volumes: pgdata: `
Для ML: монтируйте локальную папку с моделью ./models:/app/models:ro (read-only) — не пересобирайте образ при каждой смене весов.
Profiles и override. docker compose --profile full up поднимает только сервисы с нужным profile — удобно, когда тяжёлый Spark нужен не всем. Файл compose.override.yaml (локальные настройки) часто добавляют в .gitignore.
Healthcheck и depends_on. depends_on не ждёт готовности БД — только старт контейнера. Для надёжности добавляйте healthcheck и скрипт ожидания в entrypoint или используйте retry в приложении.
Как это выглядит на практике
Локальный контур «inference + кэш + object storage»:
` services: scorer: build: ./scorer ports: ["8080:8080"] environment: MODEL_PATH: /models/model.onnx S3_ENDPOINT: http://minio:9000 volumes: - ./models:/models:ro depends_on: minio: condition: service_started
minio: image: minio/minio command: server /data ports: ["9000:9000"] environment: MINIO_ROOT_USER: minioadmin MINIO_ROOT_PASSWORD: minioadmin `
Команды:
docker compose up -d docker compose ps docker compose logs scorer docker compose down -v # удалить контейнеры и named volumes
Перед сдачей практикума модуля 3.1: соберите образ, опишите Compose, запушьте образ в registry (как в curriculum). Compose остаётся у разработчика; в CI Jenkins собирает и пушит образ, а Kubernetes разворачивает уже отдельно.
Что сделать после занятия
Поднимите Compose с вашим API и Redis; проверьте, что API видит Redis по имени сервиса, а не
127.0.0.1.Добавьте named volume для PostgreSQL и убедитесь, что данные сохраняются после
docker compose downбез-v.Опишите в Confluence (или README) схему: какие сервисы в Compose соответствуют будущим Deployment в Kubernetes.