Logo Craft Homelab Docs Контакты Telegram
Трендовые github проекты в нашем телеграм канале. Подпишись →
2 марта 2026 г.

Docker Compose: продвинутый

Docker Compose покрывает весь жизненный цикл разработки — от локальной среды до CI — если использовать profiles, override-файлы и healthchecks вместо одного монолитного docker-compose.yml. Один файл с правильной структурой заменяет набор скриптов и ручных инструкций в README.

Базовый docker-compose.yml для запуска приложения с базой — это просто. Сложнее покрыть одной конфигурацией локальную разработку, CI и продакшен-подобное окружение без дублирования. Compose предоставляет несколько механизмов именно для этого.

Key Takeaways

  • Profiles позволяют подключать сервисы по требованию (--profile debug) без дублирования файлов
  • docker-compose.override.yml автоматически применяется при локальном запуске и перекрывает базовую конфигурацию
  • depends_on без condition: service_healthy не гарантирует готовность сервиса — нужен явный healthcheck
  • Compose Watch (v2.22+) заменяет bind mount умной синхронизацией: sync, rebuild, sync+restart в зависимости от типа файла
  • .env файл автоматически подгружается; для разных окружений используют --env-file .env.staging

Profiles

Profiles позволяют включать сервисы по требованию. Типичный случай — инструменты для отладки, которые не нужны в CI:

services:
  app:
    build: .
    ports:
      - "8000:8000"
    depends_on:
      db:
        condition: service_healthy

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: mydb
      POSTGRES_PASSWORD: secret
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "postgres"]
      interval: 5s
      timeout: 3s
      retries: 5

  redis:
    image: redis:7-alpine

  # Запускается только с --profile debug
  pgadmin:
    image: dpage/pgadmin4
    profiles: [debug]
    ports:
      - "5050:80"
    environment:
      PGADMIN_DEFAULT_EMAIL: admin@local.dev
      PGADMIN_DEFAULT_PASSWORD: admin

  # Запускается только с --profile tools
  redis-commander:
    image: rediscommander/redis-commander
    profiles: [tools]
    ports:
      - "8081:8081"
    environment:
      REDIS_HOSTS: "local:redis:6379"
# Базовый запуск (без отладочных инструментов)
docker compose up -d

# С pgAdmin для работы с базой
docker compose --profile debug up -d

# С несколькими profiles
docker compose --profile debug --profile tools up -d

Profiles можно задавать через переменную окружения:

COMPOSE_PROFILES=debug,tools docker compose up -d

Override файлы

docker-compose.override.yml автоматически сливается с docker-compose.yml при запуске без указания файлов. Это стандартный паттерн для разделения конфигурации по окружениям:

# docker-compose.yml -- база для всех окружений
services:
  app:
    build: .
    environment:
      DATABASE_URL: postgresql://app:secret@db:5432/mydb
      REDIS_URL: redis://redis:6379/0

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_PASSWORD: secret

  redis:
    image: redis:7-alpine
# docker-compose.override.yml -- локальная разработка (автозагрузка)
services:
  app:
    build:
      target: development    # multi-stage: dev стейдж с hot-reload
    volumes:
      - .:/app               # маунт исходников для live-reload
    environment:
      DEBUG: "true"
      LOG_LEVEL: DEBUG
    ports:
      - "8000:8000"
      - "5678:5678"          # debugpy для VS Code remote debug

  db:
    ports:
      - "5432:5432"          # открываем порт локально для psql/DBeaver
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:
# docker-compose.prod.yml -- продакшен-подобная конфигурация
services:
  app:
    restart: always
    deploy:
      resources:
        limits:
          cpus: "1.0"
          memory: 512M
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
    environment:
      DEBUG: "false"
# Локально (автоматически применяется override)
docker compose up -d

# CI (только базовый файл, без маунтов и отладчика)
docker compose -f docker-compose.yml up -d

# Prod-подобное окружение
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

Слияние конфигурации

При слиянии файлов Compose объединяет словари и переопределяет скалярные значения. Список environment объединяется, а не заменяется — это удобно для добавления переменных в override без полного дублирования.

Переменные окружения и .env

Compose автоматически подгружает .env из текущей директории:

# .env
POSTGRES_VERSION=16-alpine
APP_PORT=8000
SECRET_KEY=dev-only-key-change-in-prod
services:
  app:
    ports:
      - "${APP_PORT}:8000"
  db:
    image: postgres:${POSTGRES_VERSION}
    environment:
      POSTGRES_PASSWORD: ${SECRET_KEY}

Для разных окружений используют несколько .env файлов:

# Staging
docker compose --env-file .env.staging up -d

# Production
docker compose --env-file .env.prod up -d

Файл .env не должен попасть в git с реальными секретами. Храните .env.example с placeholder-значениями, а реальные секреты передавайте через CI/CD или Secrets Manager.

Healthchecks и depends_on

depends_on без condition проверяет только запуск контейнера, не готовность сервиса. PostgreSQL стартует секунды, а не мгновенно — без healthcheck приложение падает при попытке подключиться к ещё не готовой базе:

services:
  app:
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy

  db:
    image: postgres:16-alpine
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5
      start_period: 10s      # не считать failures первые 10 секунд

  redis:
    image: redis:7-alpine
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 3

  elasticsearch:
    image: elasticsearch:8.12.0
    healthcheck:
      test: ["CMD-SHELL", "curl -sf http://localhost:9200/_cluster/health || exit 1"]
      interval: 10s
      timeout: 10s
      retries: 5
      start_period: 60s      # ES запускается долго

start_period даёт сервису время на первоначальный запуск. В этот период failures не считаются — это важно для тяжёлых сервисов вроде Elasticsearch или Kafka.

Watch mode

Compose Watch (добавлен в v2.22) отслеживает изменения файлов и выполняет умную реакцию без полного перезапуска:

services:
  app:
    build: .
    develop:
      watch:
        - action: sync          # скопировать файл без пересборки
          path: ./src
          target: /app/src
          ignore:
            - __pycache__
            - "*.pyc"
        - action: rebuild       # пересобирать образ при изменении зависимостей
          path: requirements.txt
        - action: rebuild
          path: pyproject.toml
        - action: sync+restart  # синхронизировать и перезапустить контейнер
          path: ./config
          target: /app/config
docker compose watch

Это гибче, чем простой bind mount: изменение requirements.txt вызывает docker build, изменение исходного файла Python — только копирование без пересборки.

Сети и volume

По умолчанию Compose создаёт одну сеть для всех сервисов. Для изоляции групп сервисов — явные сети:

networks:
  frontend:
  backend:
  monitoring:

services:
  nginx:
    networks: [frontend]

  app:
    networks: [frontend, backend]   # app виден с обеих сторон

  db:
    networks: [backend]             # db недоступен из frontend-сети

  prometheus:
    networks: [monitoring, backend] # мониторинг видит backend

Named volumes для персистентных данных:

volumes:
  postgres_data:
    driver: local
  redis_data:
    driver: local
  # External volume, созданный вне Compose (например, в продакшене)
  uploads:
    external: true
    name: production-uploads

Полезные команды

# Логи конкретного сервиса в реальном времени
docker compose logs -f app

# Перезапустить только один сервис
docker compose restart app

# Пересобрать образ без кэша и перезапустить
docker compose up -d --build --no-cache app

# Запустить одноразовую команду (миграции, seed)
docker compose run --rm app python manage.py migrate

# Статус и порты
docker compose ps

# Удалить всё включая volumes
docker compose down -v

Итог

Profiles, override-файлы и healthchecks превращают Compose из инструмента для запуска контейнеров в полноценный инструмент управления окружениями. Одна команда docker compose up -d должна работать одинаково для нового разработчика и в CI.

Когда приложение вырастает за пределы одного хоста, следующий шаг — Kubernetes для production-оркестрации.