Вопрос 7 · Раздел 14

Что такое Docker Compose?

Docker — это как управление отдельными музыкантами. Docker Compose — как дирижёр оркестра: он знает, кто когда вступает, как громко играть и как музыканты слышат друг друга.

Версии по языкам: English Russian Ukrainian

🟢 Junior Level

Простое объяснение

Docker Compose — это инструмент для определения и запуска многоконтейнерных приложений. Вы описываете всю инфраструктуру (сервисы, сети, тома) в одном YAML-файле. Если Docker управляет отдельными контейнерами, то Docker Compose управляет системой взаимосвязанных контейнеров.

Аналогия

Docker — это как управление отдельными музыкантами. Docker Compose — как дирижёр оркестра: он знает, кто когда вступает, как громко играть и как музыканты слышат друг друга.

Пример docker-compose.yml

version: "3.8"

services:
  app:
    build: .
    ports:
      - "8080:8080"
    environment:
      - DATABASE_URL=jdbc:postgresql://db:5432/mydb
    depends_on:
      db:
        condition: service_healthy

  db:
    image: postgres:15
    environment:
      - POSTGRES_DB=mydb
      - POSTGRES_USER=admin
      - POSTGRES_PASSWORD=secret
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U admin"]
      interval: 5s
      timeout: 3s
      retries: 5

Healthcheck -- периодическая проверка, жив ли сервис внутри контейнера
(не просто запущен, а принимает подключения).

volumes:
  postgres_data:

Основные команды

Команда Что делает
docker compose up -d Запуск всех сервисов в фоне
docker compose down Остановка и удаление контейнеров и сетей
docker compose logs -f Логи всех сервисов в реальном времени
docker compose exec app bash Войти в запущенный контейнер
docker compose ps Показать запущенные сервисы

Что запомнить

  • Docker Compose описывает всю инфраструктуру в одном YAML-файле
  • Одна команда docker compose up поднимает всё приложение
  • Сервисы общаются друг с другом по именам через внутреннюю сеть
  • Volumes сохраняют данные между перезапусками
  • Идеален для локальной разработки

🟡 Middle Level

Ключевые возможности

  • Декларативность — описываете желаемое состояние в docker-compose.yml.
  • Изоляция сред — для каждого проекта создаётся отдельная сеть, что позволяет запускать несколько копий без конфликтов портов.
  • Управление зависимостямиdepends_on с condition: service_healthy дожидается готовности БД.
  • Сохранение данных — volumes для персистентности данных БД.

Compose лучше потому что: одна команда вместо N команд docker run, автоматическая сеть между сервисами, декларативное описание вместо императивных команд.

Структура YAML-файла

version: "3.8"

services:        # Контейнеры приложения
  app:
    build: .
    ports: ["8080:8080"]
    environment:
      DATABASE_URL: jdbc:postgresql://db:5432/mydb
    depends_on:
      db: { condition: service_healthy }  # ждёт готовности БД, не просто старта контейнера
    networks: [app-network]

  db:
    image: postgres:15
    volumes: [postgres_data:/var/lib/postgresql/data]
    healthcheck:
      test: ["CMD-SHELL", "pg_isready"]
      interval: 5s
    networks: [app-network]

networks:        # Сети для связи сервисов
  app-network:
    driver: bridge

volumes:         # Внешние хранилища
  postgres_data:

Типичные ошибки

Ошибка Последствие Как избежать
depends_on без healthcheck Приложение стартует до готовности БД Используйте condition: service_healthy
Хардкод паролей в YAML Утечка секретов в git Используйте .env файлы
Нет restart policy Контейнер не перезапускается при падении restart: unless-stopped
Конфликты портов на хосте «Port already in use» Используйте разные порты или без ports для внутренних сервисов
Забыть networks Все сервисы на default сети, нет изоляции Создайте отдельную сеть

Когда НЕ использовать Docker Compose

НЕ используйте Compose для: продакшена с >1 сервером, требований к zero-downtime deploy, горизонтального масштабирования, self-healing. Для этого – Kubernetes.

Docker Compose в разработке vs Продакшн

  • В разработке — идеальный инструмент. Одной командой разработчик поднимает бэкенд, фронтенд, Postgres, Redis и Kafka.
  • В продакшене — используется только для небольших проектов на одном сервере. Для масштабируемых систем используются оркестраторы (Kubernetes, Docker Swarm, Nomad).

Полезные фишки

  1. Environment Variables — поддержка файлов .env для хранения настроек.
  2. Profiles (v3.9+) — запуск только части сервисов: docker compose --profile monitoring up.
  3. Healthchecks — Compose дожидается полной готовности БД перед стартом зависимых сервисов.
  4. Override файлыdocker-compose.override.yml для локальных настроек поверх основного файла.

Что запомнить

  • Docker Compose — один из популярных инструментов для локальной разработки (альтернативы: docker run скрипты, devcontainer, Tilt, Okteto)
  • Автоматизирует настройку связей между микросервисами
  • Не храните пароли в YAML-файле, используйте .env
  • Для деплоя используйте Helm-чарты или K8s манифесты
  • depends_on без healthcheck не гарантирует порядок готовности

🔴 Senior Level

Docker Compose как архитектурный инструмент

Docker Compose — это не просто «удобный запуск», это декларативное описание топологии микросервисной системы. Он определяет: какие сервисы существуют, как они связаны, какие данные персистентны, как происходит service discovery.

Внутренняя работа

Docker Compose не является демоном. Он:

  1. Парсит docker-compose.yml и строит dependency graph
  2. Конвертирует compose-модель в Docker API calls (create network → create volume → create containers → start)
  3. При depends_on с healthcheck — polling health status перед стартом зависимых сервисов
  4. Создаёт Docker network с embedded DNS — сервисы резолвят друг друга по именам

Trade-offs

Аспект Docker Compose Kubernetes
Сложность Низкая (YAML + 1 команда) Высокая (множество объектов)
Масштабирование Ручное (docker compose up --scale) Автоматическое (HPA)
Self-healing Нет Да
Rolling updates Нет Да
Service discovery DNS внутри compose network kube-proxy + CoreDNS
Multi-node Нет (один хост) Да
Learning curve Часы Недели/месяцы

Edge Cases

  • depends_on не ждёт readiness по умолчанию: depends_on гарантирует только порядок старта контейнеров, не порядок готовности. Сервис БД может стартовать, но ещё не принимать подключения. Решение: condition: service_healthy + healthcheck.
  • Сетевое разрешение имён: Compose создаёт network с DNS. Сервис db резолвится как db. Но если docker compose up запущен из разных директорий, сети разные — db в проекте A ≠ db в проекте B.
  • Volume naming: postgres_data в Compose получает префикс проекта: myproject_postgres_data. Это может сломать миграции при переименовании проекта.
  • Resource limits: Compose v3 поддерживает deploy.resources, но только для Docker Swarm. Для одиночного Docker используйте v2 syntax mem_limit, cpus.
  • Windows paths: на Windows тома монтируются через CIFS/SMB. Проблемы с permissions, производительностью (особенно с множеством мелких файлов), symlink’ами.

Production-подход для небольших систем

version: "3.8"

services:
  app:
    image: myregistry.com/app:${APP_VERSION:-latest}  # pin version
    restart: unless-stopped
    deploy:
      resources:
        limits:
          cpus: "2"
          memory: 1G
        reservations:
          cpus: "0.5"
          memory: 512M
    environment:
      - SPRING_PROFILES_ACTIVE=prod
      - DATABASE_URL=jdbc:postgresql://db:5432/mydb
    depends_on:
      db: { condition: service_healthy }
    networks: [app-net]
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

  db:
    image: postgres:15.4-alpine
    restart: unless-stopped
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U admin"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s
    networks: [app-net]

volumes:
  postgres_data:
    driver: local

networks:
  app-net:
    driver: bridge

Безопасность

  • Не храните секреты в YAML — используйте .env файлы, добавленные в .gitignore.
  • Docker secrets — для Swarm-режима: echo "password" | docker secret create db_pass -.
  • Read-only контейнерыread_only: true + tmpfs для временных файлов.
  • Non-root пользовательuser: "1000:1000" в service definition.
  • Network isolation — отдельные сети для frontend/backend сервисов.

Производительность

Метрика Compose (один хост) Kubernetes (кластер)
Макс. сервисов ~50-100 (ограничение хоста) Тысячи
Время старта всех сервисов 10-60s 1-5 минут
Потребление RAM Минимальное (только контейнеры) 500MB+ (системные компоненты)
Network overhead Bridge network, минимальный kube-proxy, CNI overlay

Migration Compose → Kubernetes

Существуют инструменты для конвертации:

  • Komposekompose convert -f docker-compose.yml → K8s манифесты
  • Docker Compose для K8s (experimental) — docker compose up напрямую в K8s
  • Okteto — разработка в K8s с Compose-подобным DX

Но автоматическая конвертация не даёт production-ready K8s манифестов. Нужно вручную настраивать: HPA, PDB, ingress, liveness/readiness probes, resource quotas.

Production Story

Стартап из 5 разработчиков использовал Docker Compose для продакшена на одном VPS (8 CPU, 16GB RAM). Приложение: 6 микросервисов + PostgreSQL + Redis + Nginx. Работало стабильно 18 месяцев. Когда трафик вырос в 10x, Compose перестал хватать: нет горизонтального масштабирования, нет rolling updates, нет self-healing. Миграция на Kubernetes заняла 3 недели, но дала: автоматическое масштабирование под нагрузку, zero-downtime деплой, автоматическое восстановление при падении. Compose остался для локальной разработки — как «документация к запуску».

Monitoring

  • docker compose ps — статус сервисов
  • docker compose top — процессы в контейнерах
  • docker stats — CPU/RAM/network в реальном времени
  • Log aggregation: driver: json-file + fluentd/Fluentbit для централизованного логирования
  • Healthcheck status: docker compose ps показывает unhealthy сервисы

Резюме

  • Docker Compose — стандарт для локальной разработки и прототипирования.
  • Позволяет автоматизировать настройку связей между микросервисами.
  • depends_on без healthcheck не гарантирует порядок готовности — критическая ошибка.
  • Для продакшена на одном сервере допустим, но с ограничениями (no scaling, no self-healing).
  • В крупных системах — Compose как «документация к локальному запуску», для деплоя — K8s.
  • Безопасность: .env для секретов, non-root user, read-only filesystem.

🎯 Шпаргалка для интервью

Обязательно знать:

  • Docker Compose — декларативный запуск многоконтейнерных приложений из одного YAML-файла
  • Сервисы общаются через внутреннюю сеть по именам (embedded DNS)
  • depends_on без condition: service_healthy гарантирует порядок старта, не готовности
  • Volumes обеспечивают персистентность данных между перезапусками контейнеров
  • Compose — стандарт для локальной разработки; для продакшена — Kubernetes
  • Override файлы (docker-compose.override.yml) для локальных настроек
  • Kompose конвертирует Compose → K8s манифесты (но не production-ready)

Частые уточняющие вопросы:

  • «Почему depends_on без healthcheck недостаточен?» — Контейнер БД стартовал, но ещё не принимает подключения
  • «Как сервисы находят друг друга?» — Compose создаёт network с DNS; сервис db резолвится как db
  • «Можно ли использовать Compose в продакшене?» — Да, для небольших проектов на одном сервере (нет HA, scaling)
  • «Что такое profiles в Compose?» — Позволяют запускать только часть сервисов (--profile monitoring)

Красные флаги (НЕ говорить):

  • «Compose — замена Kubernetes» (нет HA, self-healing, rolling updates)
  • «Храню пароли прямо в docker-compose.yml» (используйте .env, Docker secrets)
  • «depends_on гарантирует, что БД готова» (гарантирует только порядок старта)
  • «Compose работает на нескольких серверах» (только один хост)

Связанные темы:

  • [[Что такое Kubernetes и зачем он нужен]] — оркестрация для продакшена
  • [[Что такое контейнеризация и зачем она нужна]] — основы контейнеризации
  • [[Как мониторить приложения в Kubernetes]] — monitoring для production