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 действительно будет выполнять.
Атрибуты сервиса
Образ и сборка
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 | Политика перезапуска |
Окружение
environment:
LOG_LEVEL: info
DATABASE_URL: postgresql://app@db:5432/appdb
env_file:
- .env
Значения из environment перекрывают env_file.
Порты
ports:
- "8080:8000" # доступен из сети
- "127.0.0.1:8080:8000" # только с хоста
expose:
- "8000" # только внутри сетей Compose
Ресурсы и логи
deploy:
resources:
limits: {cpus: "0.5", memory: 256M}
logging:
driver: json-file
options: {max-size: "10m", max-file: "3"}
Без logging.options логи не ротируются — частая причина заполнения диска.
Усиление
read_only: true
tmpfs: [/tmp]
cap_drop: [ALL]
security_opt:
- no-new-privileges:true
Зависимости и готовность
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 | Миграции, разовые задачи |
Форма списка ждёт только запуска:
depends_on: [db] # НЕ ждёт готовности
Healthcheck
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 должен превышать время старта приложения, иначе проверки во время инициализации пометят сервис нездоровым.
Сети и тома
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:, становится анонимным: данные потеряются при пересоздании.
Секреты и конфигурация
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.
Несколько файлов
docker compose -f compose.yaml -f compose.dev.yaml up -d
docker compose -f compose.yaml -f compose.test.yaml run --rm tests
Файлы сливаются: скалярные значения заменяются, списки по умолчанию дополняются.
Управление слиянием
services:
api:
ports: !reset [] # убрать унаследованное
volumes: !override # заменить, а не дополнить
- newdata:/data
read_only: !override false
| Тег | Действие |
|---|---|
!reset | Сбросить значение к пустому |
!override | Заменить целиком вместо слияния |
Профили
services:
debug-tools:
profiles: [debug]
docker compose --profile debug up -d
Сервис с профилем не запускается, пока профиль не включён.
Профили или отдельные файлы? Профили — когда отличие сводится к «запускать или нет». Отдельные файлы — когда отличий много: в одном файле отладочные настройки рано или поздно уезжают в эксплуатацию.
Якоря и подстановка
Якоря 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:?сообщение} | Ошибка, если пусто или не задано |
$$ | Литеральный знак доллара |
image: ghcr.io/org/app:${TAG:?укажите TAG}
Переменные берутся из окружения и из файла .env в каталоге проекта.
Быстрые проверки конфигурации
# Синтаксис и слияние
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
Главное оглавление