Урок по треку Docker и Kubernetes 7 мин

Docker Compose за 7 минут

Сервисы, сети и тома в compose.yaml, depends_on и healthcheck, env, профили и override.

Compose описывает несколько контейнеров, их сети и тома в одном YAML-файле и поднимает их одной командой. Это стандарт для локальной разработки, стендов и небольших продов на одном сервере.

Минимальный файл

# compose.yaml
services:
  api:
    build: .
    image: registry.example.com/api:1.4.2
    ports:
      - "8080:8080"
    environment:
      DATABASE_URL: postgres://app:${DB_PASSWORD}@db:5432/app
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped

  db:
    image: postgres:16
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app"]
      interval: 5s
      retries: 10

volumes:
  pgdata:

Файл по умолчанию называется compose.yaml (старое имя docker-compose.yml тоже читается). Поле version: в начале файла устарело: Compose v2 его игнорирует и предупреждает.

Сейчас Compose это плагин Docker CLI: команда docker compose (через пробел). Отдельный docker-compose на Python это первая версия, она больше не развивается.

Сеть и имена

Compose создаёт для проекта отдельную сеть <проект>_default, и сервисы находят друг друга по имени сервиса: db, api. Имя проекта по умолчанию это имя каталога, задаётся -p или name: в файле. Порты публикуются только там, где они нужны снаружи: базе в примере порт не нужен, API ходит к ней по внутренней сети.

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

docker compose up -d              # поднять в фоне (собрать, если нужно)
docker compose up -d --build      # пересобрать образы
docker compose ps
docker compose logs -f api
docker compose exec db psql -U app
docker compose run --rm api npm test   # разовая команда в новом контейнере
docker compose pull                    # скачать новые образы
docker compose down                    # остановить и удалить контейнеры и сеть
docker compose down -v                 # ...и тома: данные пропадут!
docker compose config                  # итоговый конфиг после подстановок

up -d идемпотентен: пересоздаёт только сервисы, у которых изменился конфиг или образ.

depends_on и готовность

depends_on: [db] задаёт только порядок запуска: api стартует после того, как контейнер db создан и запущен, но база в этот момент может ещё не принимать соединения. Чтобы ждать готовности, нужны healthcheck у зависимости и condition: service_healthy. И всё равно приложение должно уметь переподключаться: база может перезапуститься позже.

Есть ещё condition: service_completed_successfully, удобно для миграций: сервис migrate выполняется и выходит, а api ждёт его успешного завершения.

Переменные и конфигурация

  • ${VAR} в файле подставляется из окружения shell и из файла .env рядом с compose-файлом. Подстановка происходит при разборе файла.
  • environment: задаёт переменные контейнера, env_file: берёт их из файла.
  • ${VAR:?нужно задать VAR} прерывает запуск, если переменной нет; ${VAR:-default} даёт значение по умолчанию.
  • Проверить итог: docker compose config.

Не путай: .env для подстановки в compose-файл и env_file: для передачи переменных в контейнер. Это разные механизмы.

Секреты

Переменные окружения видны в docker inspect и попадают в логи при отладке. Compose умеет secrets:: файл монтируется в контейнер как /run/secrets/<имя>, многие официальные образы понимают переменные *_FILE (POSTGRES_PASSWORD_FILE).

Несколько окружений

  • compose.override.yaml применяется автоматически поверх основного: удобно для разработки (bind mount кода, отладочные порты).
  • Явно: docker compose -f compose.yaml -f compose.prod.yaml up -d.
  • profiles: включают сервисы по требованию: docker compose --profile debug up.
  • extends и якоря YAML (x-common: &common) убирают повторы.

Ресурсы, рестарты, логи

    restart: unless-stopped
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: "1.0"
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

restart: unless-stopped поднимет сервис после ребута и падения. Без ограничения логов json-файлы растут без конца.

Compose в проде

Для одного сервера Compose годится: просто, понятно, воспроизводимо. Чего нет: нескольких узлов, самовосстановления при падении сервера, плавного обновления без простоя из коробки, автомасштабирования. Когда это нужно, переходят на Kubernetes или другой оркестратор.

Частые ошибки

  • Ждать готовности базы от простого depends_on.
  • docker compose down -v на проде.
  • Публиковать порт базы наружу «для удобства».
  • Пароли прямо в compose.yaml в репозитории.
  • latest у образов в продовом файле.

Что спросят на собесе

  • Как сервисы в compose находят друг друга.
  • Что делает depends_on и как дождаться готовности базы.
  • Чем down отличается от down -v, up от run.
  • Как разделить конфигурацию для разработки и прода.
  • Когда Compose перестаёт хватать и нужен Kubernetes.

Закрепите за 5 минут

После урока в тренажёре 3-5 проверочных вопросов, дальше модуль уходит в повторения.