Главная/Справочники/Справочник

Docker Compose cheat sheet

Атрибуты сервисов, команды и синтаксис часто используемых конструкций.

Поле version: устарело и игнорируется. Если оно есть в вашем файле — уберите.

Содержание


Команды

ЗадачаКоманда
Поднять в фонеdocker compose up -d
Поднять и дождаться готовностиdocker compose up -d --wait
Пересобрать и поднятьdocker compose up -d --build
Остановитьdocker compose stop
Остановить и удалитьdocker compose down
То же с томамиdocker compose down -v
Состояниеdocker compose ps
Логи всех сервисовdocker compose logs -f
Логи одногоdocker compose logs -f api
Выполнить в работающемdocker compose exec api команда
Запустить разовую задачуdocker compose run --rm migrate
Масштабироватьdocker compose up -d --scale worker=3
Итоговая конфигурацияdocker compose config
Проверить синтаксисdocker compose config -q
Собрать образыdocker compose build
Перезапустить сервисdocker compose restart api

docker compose config — главная команда для отладки. Она показывает файл после слияния override, подстановки переменных и раскрытия якорей: то, что Compose действительно будет выполнять.


Атрибуты сервиса

Образ и сборка

yaml
services:
  api:
    image: ghcr.io/org/api:1.4.2      # конкретный тег, не latest
    build:
      context: .
      dockerfile: Dockerfile
      target: runtime
      args: {VCS_REF: "${GIT_SHA:-unknown}"}

Запуск

АтрибутНазначение
commandЗаменяет CMD образа
entrypointЗаменяет ENTRYPOINT образа
user: "10001:10001"Пользователь; числом
working_dirРабочий каталог
init: trueДобавляет init-процесс для сбора зомби
stop_grace_period: 30sВремя до SIGKILL
stop_signal: SIGTERMСигнал остановки
restart: unless-stoppedПолитика перезапуска

Окружение

yaml
    environment:
      LOG_LEVEL: info
      DATABASE_URL: postgresql://app@db:5432/appdb
    env_file:
      - .env

Значения из environment перекрывают env_file.

Порты

yaml
    ports:
      - "8080:8000"              # доступен из сети
      - "127.0.0.1:8080:8000"    # только с хоста
    expose:
      - "8000"                   # только внутри сетей Compose

Ресурсы и логи

yaml
    deploy:
      resources:
        limits: {cpus: "0.5", memory: 256M}
    logging:
      driver: json-file
      options: {max-size: "10m", max-file: "3"}

Без logging.options логи не ротируются — частая причина заполнения диска.

Усиление

yaml
    read_only: true
    tmpfs: [/tmp]
    cap_drop: [ALL]
    security_opt:
      - no-new-privileges:true

Зависимости и готовность

yaml
services:
  api:
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started
      migrate:
        condition: service_completed_successfully
УсловиеЧто ждётДля чего
service_startedЗапуска container'аКогда готовность не важна
service_healthyУспешного healthcheckБаза, кэш, любая зависимость
service_completed_successfullyЗавершения с кодом 0Миграции, разовые задачи

Форма списка ждёт только запуска:

yaml
    depends_on: [db]     # НЕ ждёт готовности

Healthcheck

yaml
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app -d appdb"]
      interval: 5s
      timeout: 3s
      retries: 10
      start_period: 10s
Форма testКогда
["CMD", "программа", "арг"]Без оболочки; предпочтительно
["CMD-SHELL", "строка"]Нужны конвейеры или подстановка
["NONE"]Отключить проверку из образа

start_period должен превышать время старта приложения, иначе проверки во время инициализации пометят сервис нездоровым.


Сети и тома

yaml
services:
  api:
    networks: [frontend, backend]
  db:
    networks: [backend]

networks:
  frontend:
  backend:
    internal: true      # нет выхода наружу

volumes:
  pgdata:
  cachedata:
    driver: local
Форма монтированияСмысл
имя:/путьИменованный том
./каталог:/путьBind mount, относительный путь
имя:/путь:roТолько для чтения
type: tmpfsВ памяти

internal: true — не то же, что «не публиковать порты». Публикация управляет доступом снаружи внутрь; internal запрещает выход изнутри наружу.

Том, использованный в сервисе, но не объявленный в volumes:, становится анонимным: данные потеряются при пересоздании.


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

yaml
services:
  db:
    environment:
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    secrets: [db_password]

secrets:
  db_password:
    file: ./secrets/db_password.txt

Секрет монтируется файлом в /run/secrets/имя. В переменную передаётся путь, а не значение — переменные видны в docker inspect и в списке процессов.

Файл секрета должен быть в .gitignore.


Несколько файлов

bash
docker compose -f compose.yaml -f compose.dev.yaml up -d
docker compose -f compose.yaml -f compose.test.yaml run --rm tests

Файлы сливаются: скалярные значения заменяются, списки по умолчанию дополняются.

Управление слиянием

yaml
services:
  api:
    ports: !reset []            # убрать унаследованное
    volumes: !override          # заменить, а не дополнить
      - newdata:/data
    read_only: !override false
ТегДействие
!resetСбросить значение к пустому
!overrideЗаменить целиком вместо слияния

Профили

yaml
services:
  debug-tools:
    profiles: [debug]
bash
docker compose --profile debug up -d

Сервис с профилем не запускается, пока профиль не включён.

Профили или отдельные файлы? Профили — когда отличие сводится к «запускать или нет». Отдельные файлы — когда отличий много: в одном файле отладочные настройки рано или поздно уезжают в эксплуатацию.


Якоря и подстановка

Якоря YAML

yaml
x-app-base: &app-base
  image: ghcr.io/org/app:1.4.2
  user: "10001:10001"
  read_only: true
  cap_drop: [ALL]
  logging:
    driver: json-file
    options: {max-size: "10m", max-file: "3"}

services:
  api:
    <<: *app-base
    command: ["python", "-m", "app.main"]
  worker:
    <<: *app-base
    command: ["python", "-m", "app.worker"]

Ключи, начинающиеся с x-, Compose игнорирует — они существуют ради якорей.

Зачем. Настройки безопасности, повторённые трижды, рано или поздно разъедутся: одну копию поправят, две забудут.

Подстановка переменных

ФормаСмысл
${VAR}Значение или пусто
${VAR:-умолчание}Умолчание, если пусто или не задано
${VAR-умолчание}Умолчание, только если не задано
${VAR:?сообщение}Ошибка, если пусто или не задано
$$Литеральный знак доллара
yaml
    image: ghcr.io/org/app:${TAG:?укажите TAG}

Переменные берутся из окружения и из файла .env в каталоге проекта.


Быстрые проверки конфигурации

bash
# Синтаксис и слияние
docker compose config -q

# Ограничения ресурсов у всех сервисов
docker compose config | python3 -c '
import sys, yaml
d = yaml.safe_load(sys.stdin)
for name, svc in d["services"].items():
    limits = (svc.get("deploy") or {}).get("resources", {}).get("limits", {})
    print(f"{name:<12} {limits or \"НЕТ ОГРАНИЧЕНИЙ\"}")'

# Пароли в открытом виде
grep -riE 'password\s*[:=]\s*[^$/]' compose*.yaml || echo "не найдено"

# Зависимости без условия готовности
docker compose config | grep -B 2 -A 2 'depends_on' | head -20

# Внутренняя ли сеть
docker network inspect ПРОЕКТ_backend --format '{{.Internal}}'

Подробнее: раздел 09, урок 9.7.


Навигация

Вернуться к справочникам
Docker CLI cheat sheet
Dockerfile cheat sheet
Production checklist
Главное оглавление

Markdown на GitHub ↗