Compose-паттерны для DE
Compose-паттерны для дата-инженера¶
Docker Compose — стандартный инструмент для локальной разработки и лёгкого продакшена. В DE Compose поднимает целый стек: PostgreSQL, Airflow, dbt, Kafka, Redis — одной командой.
Profiles — условный запуск сервисов¶
Не все сервисы нужны всегда. Profiles позволяют группировать сервисы.
YAML
services:
db:
image: postgres:15-alpine
# Без profile → запускается всегда
backend:
image: myapp:latest
depends_on: [db]
airflow-webserver:
image: apache/airflow:2.8.0
profiles: [airflow] # Только при --profile airflow
airflow-scheduler:
image: apache/airflow:2.8.0
profiles: [airflow]
kafka:
image: confluentinc/cp-kafka:7.5.0
profiles: [kafka]
jupyter:
image: jupyter/pyspark-notebook:latest
profiles: [dev] # Только для разработки
Bash
# Базовый стек
docker compose up -d
# С Airflow
docker compose --profile airflow up -d
# Полный стек
docker compose --profile airflow --profile kafka --profile dev up -d
Типичный DE-стек¶
YAML
# docker-compose.yml
services:
db:
image: postgres:15-alpine
restart: unless-stopped
environment:
POSTGRES_DB: etl_kitchen
POSTGRES_USER: etl_user
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- db_data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U etl_user -d etl_kitchen"]
interval: 10s
timeout: 5s
retries: 5
deploy:
resources:
limits:
memory: 1G
cpus: "1.0"
ports:
- "5432:5432"
redis:
image: redis:7-alpine
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
backend:
build:
context: ./backend
dockerfile: Dockerfile
restart: unless-stopped
depends_on:
db:
condition: service_healthy
environment:
DATABASE_URL: postgresql://etl_user:${DB_PASSWORD}@db:5432/etl_kitchen
REDIS_URL: redis://redis:6379/0
ports:
- "8000:8000"
volumes:
db_data:
depends_on с healthcheck¶
YAML
services:
backend:
depends_on:
db:
condition: service_healthy # Ждать пока pg_isready
redis:
condition: service_healthy
kafka:
condition: service_started # Просто запущен (нет healthcheck)
Без condition: service_healthy контейнер стартует, но PostgreSQL ещё не готов → приложение падает с connection refused.
Override-файлы¶
YAML
# docker-compose.yml — базовый (продакшн)
services:
backend:
image: myregistry/backend:latest
# docker-compose.override.yml — автоматически подхватывается!
services:
backend:
build: ./backend # Локальная сборка вместо pull
volumes:
- ./backend:/app # Live-reload
environment:
DEBUG: "true"
Bash
# Разработка (подхватит override автоматически)
docker compose up
# Продакшн (только базовый)
docker compose -f docker-compose.yml up -d
# Явный набор файлов
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
watch — автоперезагрузка (Compose 2.22+)¶
YAML
services:
backend:
build: ./backend
develop:
watch:
- action: sync # Синхронизировать файлы
path: ./backend/app
target: /app/app
- action: rebuild # Пересобрать образ
path: ./backend/requirements.txt
- action: sync+restart # Синхронизировать + рестарт
path: ./backend/config.yml
target: /app/config.yml
Bash
docker compose watch
# Изменил app/main.py → автоматически синхронизируется в контейнер
# Изменил requirements.txt → автоматически rebuild
Resource limits¶
YAML
services:
db:
deploy:
resources:
limits:
memory: 2G
cpus: "2.0"
reservations:
memory: 512M
cpus: "0.5"
backend:
deploy:
resources:
limits:
memory: 512M
Без limits контейнер съест весь RAM
PostgreSQL без ограничений может потребить всю память хоста, вызвав OOM-killer. Всегда ставь limits.memory.
Networking¶
YAML
services:
backend:
networks:
- frontend
- backend
db:
networks:
- backend # НЕ доступна из frontend
nginx:
networks:
- frontend
networks:
frontend:
backend:
internal: true # Нет доступа в интернет
Правила:
- БД — только в
backendсети (не видна снаружи) - Приложение — в обеих сетях (принимает запросы, обращается к БД)
- Nginx/proxy — только в
frontend
Секреты (Docker Secrets)¶
YAML
services:
db:
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_password
secrets:
db_password:
file: ./secrets/db_password.txt # Локально
# Или в Docker Swarm:
# external: true
Для Compose без Swarm — проще через .env:
Полезные команды¶
Bash
# Запустить в фоне
docker compose up -d
# Пересобрать образы
docker compose up -d --build
# Логи конкретного сервиса
docker compose logs -f backend
# Выполнить команду в работающем контейнере
docker compose exec db psql -U etl_user -d etl_kitchen
# Остановить и удалить (с volumes)
docker compose down -v
# Показать ресурсы
docker compose top
docker stats
Проверь себя¶
Источники¶
- Docker Compose: Specification — полная спецификация
- Docker Compose: Profiles — условный запуск сервисов
- Docker Compose: Watch — автоперезагрузка для разработки
- Docker Compose: Networking — сети между сервисами