Питання 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 синтаксис 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 залишився для локальної розробки — як «документація до запуску».

Моніторинг

  • 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]] — моніторинг для production