docker compose — стек контейнеров одним файлом
docker compose описывает стек контейнеров с сетью, томами и переменными в compose.yaml и поднимает его одной командой.
Шпаргалка
8 команд Версия для печати-
sudo docker compose up -dподнять всё из compose.yaml -
sudo docker compose psконтейнеры проекта и здоровье -
sudo docker compose logs -f backendлоги одного сервиса -
sudo docker compose exec proxy shоболочка в сервисе -
sudo docker compose config -qпроверить файл -
sudo docker compose restart proxyперезапустить сервис -
sudo docker compose downудалить контейнеры и сеть -
sudo docker compose down -v… и тома вместе с данными
Обзор
docker compose — плагин Docker для стека из
нескольких контейнеров. Сервисы, их образы, порты, тома, переменные и
порядок запуска описаны в одном файле compose.yaml. docker compose
up -d создаёт по нему сеть, тома и контейнеры, down убирает их. Всё,
что делает compose, можно сделать и руками командами docker — файл
избавляет от длинных docker run и порядка запуска в голове.
На машине тренажёра — Docker Compose 2.40, команда пишется через пробел:
docker compose. Старой программы docker-compose через дефис нет.
Как и остальные команды Docker, compose идёт через sudo.
Compose ищет compose.yaml (или docker-compose.yml) в текущем
каталоге. Другой файл — -f stack.yaml.
Файл compose.yaml
Стек из двух сервисов: backend отдаёт страницу из тома, proxy —
nginx перед ним, единственный с портом наружу.
Рядом лежит nginx.conf с proxy_pass http://backend:8000; — nginx
ходит к соседу по имени сервиса.
| Ключ сервиса | Что задаёт | То же в docker run |
|---|---|---|
image |
образ | имя образа |
build |
каталог с Dockerfile — собрать образ | docker build |
command |
команда вместо CMD образа |
слова после образа |
environment |
переменные окружения | -e |
ports |
"хост:контейнер" |
-p |
volumes |
том:/путь или ./каталог:/путь |
-v |
depends_on |
кого запускать раньше | — |
healthcheck |
проверка здоровья | --health-cmd |
restart |
политика перезапуска | --restart |
Ключ volumes верхнего уровня объявляет именованные тома, networks —
дополнительные сети. Синтаксис — YAML: отступы пробелами,
табуляция запрещена. Порт пиши в кавычках: "8090:80".
Том, созданный заранее (docker volume create keep), подключают как
внешний — compose его не создаёт и не удаляет:
Внешнего тома нет — up падает: external volume "keep" not found. Без
external: true compose создаёт свой пустой том <проект>_data, даже
если рядом лежит keep с данными.
Без ключа networks все сервисы проекта в одной сети. Свои сети
объявляют в networks: верхнего уровня и перечисляют у сервиса:
networks: [front, back]. Имя сервиса видно только в общих сетях:
web из сети front не находит db из back
(server can't find db), а app, подключённый к обеим, видит обоих.
Проект: имена контейнеров, сети и томов
Файл описывает проект. Имя проекта — имя каталога, где лежит
compose.yaml; от него строятся имена всего, что создаёт compose:
| Что | Имя |
|---|---|
| сеть | <проект>_default — stack_default |
том data |
<проект>_data — stack_data |
| контейнер сервиса | <проект>-<сервис>-1 — stack-backend-1 |
Все сервисы проекта в одной сети, и каждый виден соседям по имени сервиса:
Команды compose работают с сервисами по их именам из файла:
logs backend, exec proxy, restart proxy. Их нужно запускать из
каталога проекта — или с -f и -p.
Переменные
${GREETING:-hello} в файле compose подставляет сам, до запуска
контейнеров: значение переменной окружения или hello, если её нет.
Переменные берутся из файла .env рядом с compose.yaml:
up -d пересоздал только backend: у него поменялось окружение.
proxy не менялся и продолжил работать.
Переменная оболочки перед sudo до compose не доходит: sudo чистит
окружение, и GREETING=privet sudo docker compose up -d ничего не
меняет. Пиши значение в .env.
$$ — буквальный знак доллара: $$GREETING в command compose не
трогает, его раскроет оболочка внутри контейнера. Что получилось после
подстановки, показывает docker compose config.
Порядок запуска и healthcheck
depends_on: [backend] только задаёт порядок: proxy стартует после
того, как контейнер backend запущен, — готов он отвечать или нет.
Ждать готовности умеет condition: service_healthy — тогда compose
ждёт статуса healthy от проверки здоровья
backend.
healthcheck.test — команда внутри контейнера: код 0 — здоров. Docker
выполняет её каждые interval, ждёт не дольше timeout, после
retries неудач подряд ставит unhealthy. Статус виден в ps:
У proxy в столбце PORTS — 0.0.0.0:8090->80/tcp, [::]:8090->80/tcp.
Команда проверки должна быть в образе: в busybox и alpine есть
wget, curl нет.
Команды стека
| Команда | Что делает |
|---|---|
up -d |
создаёт недостающее и пересоздаёт сервисы, чьё описание изменилось (Recreate), остальные не трогает (Running) |
restart backend |
перезапускает тот же контейнер: окружение и ключи прежние |
stop, start |
останавливает и запускает, не удаляя контейнеры |
ps |
статус контейнеров: Up … (healthy), Restarting (1) …, Exited (137) |
logs backend |
вывод сервиса; без имени — всех сервисов |
down |
удаляет контейнеры и сеть проекта; именованные тома остаются |
down -v |
то же вместе с томами проекта |
Правку compose.yaml или .env применяет только up -d. restart
перезапускает процесс в старом контейнере: файлы с хоста он прочитает
заново, а переменные останутся прежними.
Ключи
20Основные подкоманды и ключи — в таблице ниже. Полный список —
docker compose --help и docker compose <команда> --help.
| Ключ | Что делает | Пример |
|---|---|---|
up |
Создать и запустить всё из compose.yaml; изменённые сервисы пересоздаются, остальные не трогает. | docker compose up -d |
-d --detach |
Запустить в фоне и вернуть приглашение; без него up держит терминал и показывает логи. | docker compose up -d |
ps |
Контейнеры проекта — статус, здоровье, порты; с -a и остановленные. | docker compose ps -a |
logs |
Вывод сервисов с именем сервиса в начале строки; -f — следить, --tail — последние строки. | docker compose logs -f --tail 20 backend |
exec |
Команда в работающем контейнере сервиса; сервис называют именем из compose.yaml. | docker compose exec proxy nslookup backend |
config |
Проверить файл и показать итоговую конфигурацию с подставленными переменными. | docker compose config |
down |
Остановить и удалить контейнеры и сеть проекта; именованные тома остаются. | docker compose down |
--build |
Пересобрать образы сервисов с ключом build перед запуском. | docker compose up -d --build |
--wait |
Дождаться, пока сервисы будут running или healthy; не дождался — код не 0. | docker compose up -d --wait |
--format json |
Объект JSON на строку для каждого контейнера — для скриптов и jq. | docker compose ps --format json |
-q --quiet |
Только проверка — без вывода, код 0, если файл верен. | docker compose config -q |
restart |
Перезапустить контейнеры сервиса без пересоздания; правки compose.yaml так не применяются. | docker compose restart proxy |
stop |
Остановить сервисы, не удаляя контейнеры; вернуть — start или up -d. | docker compose stop backend |
-v --volumes |
Удалить и тома проекта — данные в них пропадут. опасно | docker compose down -v |
build |
Собрать образы сервисов, у которых есть ключ build. | docker compose build |
-f --file FILE |
Взять другой файл вместо compose.yaml в текущем каталоге. | docker compose -f stack.yaml up -d |
-T |
Без терминала — для скриптов и конвейеров. | docker compose exec -T backend cat /etc/hosts |
--services |
Только имена сервисов, по одному на строку. | docker compose config --services |
-p --project-name NAME |
Имя проекта вместо имени каталога — префикс контейнеров, сети и томов. | docker compose -p demo up -d |
--env-file FILE |
Файл переменных для подстановки вместо .env рядом с compose.yaml. | docker compose --env-file prod.env up -d |
Ничего не найдено. Попробуй запрос короче.
Рецепты
4Состояние стека для скрипта
--format json печатает объект JSON на строку для каждого контейнера —
jq разбирает их по одному.
Остановить один сервис
Логи всех сервисов сразу
Перед строкой — имя сервиса. Один сервис — logs backend, следить —
logs -f.
Неполадки
11no configuration file provided: not found
В текущем каталоге нет compose.yaml. Перейди в каталог проекта или
укажи файл: docker compose -f /srv/stack/compose.yaml ps.
additional properties '…' not allowed
Ключ с опечаткой или не на своём уровне отступа. Путь до ошибки —
services.backend; сверь имя ключа с таблицей выше.
yaml: line 3: found character that cannot start any token
В строке 3 табуляция или другой символ, с которого YAML не начинает значение. Отступы в YAML — только пробелами. Место ошибки покажет и инструмент сайта «YAML ⇄ JSON» в разделе «Инструменты».
service "backend" refers to undefined volume
Сервис подключает именованный том, которого нет в volumes: верхнего
уровня. Объяви его там же или пиши путь bind mount с ./ или /.
external volume "…" not found
Том с external: true должен существовать до up; сеть проекта compose
к этому моменту уже создал. Сверь имя в name: со списком
docker volume ls. Тома нет — создай его (docker volume create keep)
или верни данные из резервной копии.
dependency failed to start: container … is unhealthy
backend не прошёл проверку здоровья, и proxy с condition:
service_healthy остался в статусе Created. Посмотри, что отвечает
проверка: docker compose ps -a (статус unhealthy) и
docker inspect -f '{{json .State.Health}}' <контейнер> — там вывод
последних попыток. Частые причины: не тот порт в test, в образе нет
wget, сервис стартует дольше, чем interval × retries.
The "X" variable is not set
The "MODE" variable is not set. Defaulting to a blank string. —
переменной нет ни в окружении, ни в .env, и compose подставил пустую
строку. Задай её в .env или значение по умолчанию: ${MODE:-prod}.
the attribute version is obsolete
Строка version: "3.8" в начале файла устарела, compose её
пропускает. Удали её — предупреждение уйдёт.
Сервис в цикле перезапусков
docker compose ps показывает Restarting: главный процесс падает, а
restart: поднимает его снова. Причина — в docker compose logs
<сервис>: неверная переменная, нет файла, занят порт. Исправь
compose.yaml или .env и выполни up -d.
Pulling … failed to resolve reference
Образа сервиса нет на машине, и compose пошёл за ним в реестр. Без сети
загрузи образ из файла (docker load -i) и сверь имя и тег в image:
с docker images.
service "proxy" is not running
exec работает только в запущенном сервисе. docker compose ps -a —
что с ним; поднять — docker compose up -d.
Опасно
2docker compose down -v
down удаляет контейнеры и сеть, тома оставляет. -v удаляет и тома
проекта: база, загрузки, всё, что сервисы хранили в volumes:, пропадёт
безвозвратно. Внешние тома (external: true) -v не трогает.
Другое имя проекта — другие тома
Имя тома строится из имени проекта: stack_data. Скопировал
compose.yaml в другой каталог или запустил с -p — compose создаст
новый пустой том <новое имя>_data, и сервис стартует без данных.
Старые данные целы в старом томе: docker volume ls.
Термины
2- сервис compose compose service
- Запись в разделе services файла compose.yaml: образ, команда, порты и тома контейнера. Имя сервиса — его имя в DNS сети проекта.
- проверка здоровья (healthcheck)
- Команда, которую Docker регулярно выполняет внутри контейнера: код 0 — healthy, после нескольких неудач подряд — unhealthy. Статус виден в docker ps. Ещё встречается в: Docker
См. также
- docker — контейнеры, тома, сети и
inspectбез compose. - container-images — откуда берутся образы сервисов.
- dockerfile — собрать свой образ для
build:. - env-vars — переменные окружения в сервисах.
- nginx — прокси перед сервисами стека.
- curl — проверить ответ стека с хоста.
- jq — разобрать
ps --format json.
Есть неточность? Сообщить об ошибке в статье