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 разворачивает уже отдельно.
Что сделать после занятия
- [ ] Поднимите Compose с вашим API и Redis; проверьте, что API видит Redis по имени сервиса, а не
127.0.0.1. - [ ] Добавьте named volume для PostgreSQL и убедитесь, что данные сохраняются после
docker compose downбез-v. - [ ] Опишите в Confluence (или README) схему: какие сервисы в Compose соответствуют будущим Deployment в Kubernetes.