SSD Nodes Learn 🎉 VPS от $4.99/мес
Руководства Matt ConnorАвтор: Matt Connor · Обновлено 2026-08-07

Шпаргалка по командам Docker Compose для серверов

Основные команды Docker Compose V2 для управления контейнерами на сервере. Справочник по жизненному циклу, логам и сетям. Решение ошибки command not found для docker-compose.

Команды Compose, которые вы действительно используете

Docker Compose содержит более сорока подкоманд. В ежедневной работе на сервере используется около дюжины. На этой странице они сгруппированы по задачам, для каждой указана одна простая причина использования, а также даны ссылки на подробные руководства, если команда содержит скрытые ловушки.

Все описанное здесь относится к Compose V2: docker compose через пробел, а не старый скрипт docker-compose. V2 — это плагин на Go, который устанавливается вместе с Docker Engine, а V1 больше не входит в актуальные пакеты, поэтому docker-compose: command not found на свежей установке Ubuntu по состоянию на июль 2026 года — это ожидаемое поведение, а не ошибка. Проверьте версию с помощью docker compose version. Если команда ничего не выводит, установите пакет docker-compose-plugin.

Все приведенные ниже команды выполняются из директории, в которой находится ваш compose.yaml, так как Compose берет имя проекта из этой директории и ищет файл относительно неё. Если запустить ту же команду на уровень выше, Compose завершит работу с ошибкой no configuration file provided: not found. Если формат файла для вас в новинку, начните с создания первого файла Compose на VPS и вернитесь сюда за командами.

Жизненный цикл: четыре команды для запуска и одна для удаления контейнеров

docker compose up -d
docker compose up -d --wait
docker compose stop
docker compose start
docker compose restart web
docker compose down

up -d создает сеть, создает контейнеры, запускает их и завершает работу. Команда возвращает управление сразу после создания контейнеров, поэтому скрипт развертывания, который сразу после этого выполняет проверку curl, часто завершается ошибкой при первой попытке. up -d --wait блокирует выполнение до тех пор, пока каждый сервис, в котором объявлена проверка работоспособности (healthcheck), не перейдет в состояние healthy; если хотя бы один сервис не достигнет этого состояния, команда завершится с ненулевым кодом. Эффективность этого флага зависит от качества самой проверки, поэтому настройте надежный healthcheck для Compose, прежде чем использовать его в автоматизации.

stop останавливает контейнеры, но сохраняет их, поэтому start возвращает к работе те же самые контейнеры с тем же слоем записи. down останавливает контейнеры, а затем удаляет их и сеть проекта. Все данные, записанные внутри контейнера вне томов (volumes), будут удалены вместе с ним. Это самое частое и дорогостоящее заблуждение при работе с Compose, и в статье полная разница между down и stop подробно описано, к каким последствиям это приводит.

restart — это не перезагрузка. Команда останавливает и запускает тот же самый контейнер с уже имеющейся конфигурацией, поэтому изменение переменной окружения, новый тег образа или отредактированное сопоставление портов не дадут никакого эффекта. Чтобы применить изменения в файлах, снова запустите up -d. Compose сравнит каждый сервис с запущенным контейнером и пересоздаст только те, конфигурация которых изменилась.

Применение изменений: пересоздание, загрузка или пересборка

docker compose up -d --force-recreate
docker compose pull && docker compose up -d
docker compose build --no-cache web
docker compose up -d --build web

Команда up -d сама по себе ничего не делает, если изменений нет, что позволяет безопасно запускать её многократно. Флаг --force-recreate отменяет это сравнение и заменяет каждый контейнер, даже если конфигурация идентична, поэтому это самый быстрый способ очистить некорректное состояние внутри контейнера.

Обновление образа требует выполнения двух команд, так как они выполняют разные задачи. pull загружает актуальный образ для каждого тега, указанного в файле. Затем up -d обнаруживает, что ID образа сервиса больше не совпадает с ID запущенного контейнера, и пересоздаёт его. Если пропустить загрузку, up -d продолжит использовать latest прошлого месяца без каких-либо ошибок.

Команда build применяется к сервисам, в которых объявлена секция build: вместо image:. up -d --build выполняет сборку и запуск за один шаг; это стандартный цикл работы при изменении кода. Используйте --no-cache только тогда, когда кэшированный слой явно устарел, так как эта команда пересобирает каждый слой с нуля.

Просмотр запущенных процессов

docker compose ps
docker compose ps -a
docker compose logs -f --tail=100
docker compose logs --since 15m --timestamps db
docker compose top
docker compose ls

ps выводит список только запущенных контейнеров. Сервис, который аварийно завершился при запуске, не будет там отображаться, пока вы не добавите -a. Поэтому ситуация, когда контейнер отсутствует в ps, но ps -a показывает его как Exited (1), является типичным признаком сбоя при старте. Проверьте код завершения, а затем изучите логи.

logs -f выводит логи всех сервисов одновременно, добавляя имя сервиса в начало каждой строки. Это именно тот режим просмотра, который нужен, когда сервисы взаимодействуют друг с другом и важна последовательность событий. Укажите имя сервиса, чтобы сузить область вывода. Флаг --tail=100 важен для контейнера, который работает уже месяц, так как по умолчанию команда выводит всю историю и переполняет терминал. --since 15m отвечает на типичный вопрос о том, что именно произошло во время только что выполненного перезапуска.

top выводит список процессов внутри каждого контейнера. Это позволяет разграничить понятия «контейнер запущен» и «процесс внутри него запущен». ls выходит за пределы текущего каталога и перечисляет все проекты Compose на хосте с указанием их статуса, что помогает найти стек, запущенный несколько месяцев назад.

Получение доступа к оболочке внутри сервиса

docker compose exec web sh
docker compose exec -u root web sh
docker compose run --rm web env
docker compose run --rm --no-deps web sh

exec выполняет команду внутри уже запущенного контейнера. run запускает новый контейнер на основе того же определения сервиса; это необходимо, если сервис не работает достаточно долго для выполнения exec. Всегда используйте run вместе с --rm, так как без этого каждый вызов оставляет после себя остановленный контейнер, и со временем их количество делает вывод docker compose ps -a нечитаемым.

Попробуйте sh перед bash. Образы на базе Alpine не содержат bash, и при попытке запуска возникает ошибка exec: "bash": executable file not found in $PATH. Добавление --no-deps к run позволяет пропустить зависимости сервиса, что предотвращает запуск всей базы данных при простой проверке конфигурации.

run --rm web env — самый быстрый способ увидеть среду, которую сервис получил в действительности после объединения всех файлов .env, блоков environment: и переменных оболочки. Если значение неверно, причина обычно кроется в порядке объединения, а как Compose обрабатывает файлы окружения и секреты описывает, какой источник имеет приоритет.

Сети, порты и разрешение имен

docker compose port web 80
docker compose exec web getent hosts db
docker compose config --networks

Compose помещает каждый сервис в одну проектную сеть, и имя каждого сервиса становится DNS-именем внутри этой сети. Запуск getent hosts db внутри web выводит IP-адрес контейнера, если разрешение имен работает, и ничего не выводит, если оно не работает. Это позволяет за две секунды проверить, «видят ли контейнеры друг друга». Если имя разрешается, но в соединении отказано, значит процесс внутри db привязан к 127.0.0.1, а не к 0.0.0.0, поэтому он не принимает пакеты от других контейнеров. Подробности этой модели описаны в как работают сети Compose и DNS сервисов.

port web 80 выводит адрес хоста и порт, на котором опубликован порт контейнера. Это избавляет от необходимости угадывать порт, если маппинг задан через переменную. Публикация порта также создает правило брандмауэра, которым Docker управляет самостоятельно. Это правило имеет приоритет перед вашими, поэтому сервис, который вы считали приватным, может оказаться доступным из Интернета. Этот случай разобран в почему опубликованные порты Docker обходят ufw.

Тома и данные

docker compose config --volumes
docker compose cp db:/etc/postgresql/pg_hba.conf ./pg_hba.conf
docker compose down -v

config --volumes выводит именованные тома, объявленные в проекте, по одному на строку. Этот список необходимо использовать для резервного копирования. cp копирует файл в контейнер или из него без открытия оболочки, используя формат service:path для стороны, являющейся контейнером.

down -v удаляет эти именованные тома вместе с контейнерами. Это подходящая команда для удаления тестового стека, но она не подходит для данных, которые необходимо сохранить, так как запрос подтверждения отсутствует, а действие нельзя отменить. Bind mounts сохраняются при этой операции, так как они находятся в файловой системе хоста. Разница в области воздействия — одна из причин осознанно выбирать между bind mounts и именованными томами.

Очистка диска без потери данных

docker compose down --remove-orphans
docker system df
docker image prune -a
docker builder prune

--remove-orphans удаляет контейнеры, которые относятся к проекту, но больше не указаны в файле конфигурации. Это происходит, например, после переименования сервиса. Без этой команды такие контейнеры продолжают работать, оставаясь невидимыми для docker compose ps.

docker system df показывает, чем занято дисковое пространство, прежде чем вы что-либо удалите. Утилита разделяет данные на образы, контейнеры, локальные тома и кэш сборки, указывая объем, который можно освободить для каждой категории. image prune -a удаляет все образы, на которые не указывает ни один тег. На сервере, где часто загружаются новые версии больших образов, это обычно дает наибольший прирост свободного места. builder prune очищает кэш сборки, который незаметно растет на любом сервере, где выполняется сборка собственных образов.

Ни одна из этих команд не затрагивает именованные тома. Это делают только docker volume prune и docker compose down -v.

Проверка файла перед внесением изменений

docker compose config --quiet
docker compose config --services
docker compose --dry-run up -d

config --quiet выполняет проверку и ничего не выводит в случае успеха, поэтому эту команду следует использовать на этапе подготовки к развертыванию или в git hook. Обычная команда config выводит полностью объединенный и интерполированный файл; это позволяет убедиться, что переменная была успешно разрешена, а файл переопределений применился ожидаемым образом. Неустановленная переменная отображается там как пустое значение рядом с предупреждением The "X" variable is not set. Defaulting to a blank string..

--dry-run — это глобальный флаг, а не флаг подкоманды, поэтому он указывается перед up. Он выводит все действия, которые выполнит Compose, не внося при этом никаких изменений. Это тридцать секунд, которые стоит потратить перед выполнением down для важного стека.

Работа с несколькими файлами, профилями и проектами

docker compose -f compose.yaml -f compose.prod.yaml up -d
docker compose --profile debug up -d
docker compose -p staging up -d

Несколько флагов -f объединяются в порядке их указания, при этом последующие файлы переопределяют предыдущие по каждому ключу. Это стандартный способ использования базового файла с небольшим переопределением для production, однако правила для списков и словарей различаются, поэтому ознакомьтесь с тем, как Compose объединяет несколько файлов, прежде чем приступать к отладке неожиданного поведения.

--profile запускает сервисы, помеченные этим профилем, вместе с сервисами без меток, что позволяет исключить инструменты отладки из обычного up. -p задает имя проекта, благодаря чему две копии одного стека могут работать одновременно с разделением сетей и томов. Восстановление стека после перезагрузки не требует ввода команд вручную — это выполняется автоматически с помощью юнита, описание которого приведено в автозапуске стеков Compose.

FAQ

Что заменило docker-compose с дефисом?

Compose V2, вызываемый как docker compose через пробел. Это плагин, поставляемый вместе с Docker Engine, и старый инструмент на Python версии V1 больше не устанавливается актуальными пакетами. Если команда с пробелом ничего не выводит, установите пакет docker-compose-plugin для вашего дистрибутива. Обновите старые скрипты на использование формы с пробелом вместо создания алиаса, так как V2 поддерживает флаги, которых не было в V1.

Почему docker compose restart не подхватывает изменения в конфигурации?

restart останавливает и запускает существующий контейнер с той конфигурацией, с которой он был создан, и никогда не перечитывает compose.yaml. Любое изменение переменных окружения, портов, томов или тега образа требует docker compose up -d, который сравнивает каждый сервис с запущенным контейнером и пересоздает те, что отличаются. Добавьте --force-recreate, если вы хотите принудительно выполнить замену, даже если в файле ничего не изменилось.

Как обновить сервис до более новой версии образа?

Выполните docker compose pull, затем docker compose up -d. Команда pull загружает актуальный образ для каждого тега в файле, а up -d пересоздает любой сервис, чей ID образа больше не совпадает с ID в контейнере. Запуск up -d сам по себе использует образ, который уже находится на диске; именно поэтому стек, привязанный к latest, может месяцами работать на старой сборке без вывода каких-либо ошибок.

Какие команды очистки безопасны на рабочем сервере?

docker system df, docker image prune -a и docker builder prune удаляют только образы и кэш, поэтому запущенные сервисы продолжают работать, а именованные тома остаются нетронутыми. Опасная пара — это docker compose down -v и docker volume prune, которые удаляют именованные тома без запроса подтверждения. Сначала запустите docker compose config --volumes, чтобы понимать, что находится под угрозой.

Можно ли выполнить одну команду без запуска всего стека?

Да. docker compose run --rm --no-deps web sh запускает отдельный контейнер на основе описания сервиса web, пропускает его зависимости и удаляет контейнер после завершения работы. Используйте exec, если контейнер уже запущен, так как exec подключается к работающему процессу и показывает реальное состояние сервиса.