MLOps Path

3.1.3 · блок 3

Docker Compose: несколько сервисов локально

Docker Compose: несколько сервисов локально

Зачем это нужно

Реальный 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 разворачивает уже отдельно.

Что сделать после занятия

Официальные материалы

Открыть интерактивную версию