SSD Nodes Learn 8GB RAM — $66/год
Руководства Matt ConnorАвтор: Matt Connor · Обновлено 2026-08-01

Docker Compose stop и down: в чем разница

Команда stop сохраняет контейнеры, а down удаляет их вместе с сетью проекта. Именованные тома остаются в обоих случаях. Используйте флаг -v для удаления данных томов.

Краткий ответ

docker compose stop останавливает контейнеры, сохраняя их на диске. docker compose down останавливает их, а затем удаляет контейнеры и сеть, созданную Compose для данного проекта. Ни одна из этих команд не затрагивает именованные тома. Ваша база данных будет удалена только при добавлении -v, как в команде docker compose down -v, которая удаляет именованные тома, объявленные в разделе volumes файла Compose.

Это вся разница в одном абзаце. Остальная часть этого руководства подтверждает это на примере тома Postgres, который вы можете увидеть после выполнения down и который исчезнет после down -v, а также объясняет два случая, когда вам требуется --force-recreate.

docker compose stop: контейнеры остаются

stop отправляет сигнал SIGTERM основному процессу в каждом контейнере, ожидает, а затем отправляет SIGKILL, если процесс все еще активен. Время ожидания по умолчанию составляет 10 секунд, его можно изменить с помощью -t. Никакие данные не удаляются. Контейнер сохраняет свой ID, записываемый слой, зарезервированный IP-адрес и логи.

docker compose stop
docker compose ps -a

Команда docker compose ps сама по себе отображает только запущенные контейнеры, поэтому после stop она выводит пустую таблицу, и может показаться, что контейнеры исчезли. Флаг ps -a включает в вывод остановленные контейнеры, и именно там вы увидите статус Exited (0) рядом с каждой службой. Верните их в работу с помощью docker compose start, которая повторно использует те же самые контейнеры.

Поскольку контейнеры продолжают существовать, все данные, записанные внутри них вне томов, сохраняются. Это относится к пакетам, установленным вручную с помощью docker compose exec, и файлам конфигурации, которые вы редактировали внутри контейнера. Это практическая причина предпочесть stop во время отладки: вы можете перезапустить систему, сохранив текущее состояние.

docker compose down: удаление контейнеров и сетей

down останавливает контейнеры, а затем удаляет их вместе с сетью по умолчанию, созданной Compose для данного проекта. В документации Docker указано, что эта команда останавливает и удаляет контейнеры, сети, тома и образы, созданные с помощью up, однако удаление томов и образов происходит только при явном указании флагов -v и --rmi.

docker compose down
docker compose ps -a
docker network ls

После выполнения down команда ps -a не выводит информацию о проекте, а сеть <project>_default удаляется. Имя проекта берется из имени директории, если вы не задали name: в файле Compose или не передали флаг -p. Все изменения, внесенные в записываемый слой контейнера, после этого становятся невосстановимыми, поэтому рассматривайте down как команду, которая уничтожает контейнер, сохраняя при этом данные, размещенные в томах.

Если запустить команду в неверной директории, вы получите no configuration file provided: not found. Compose не может определить, какой проект имелся в виду, поэтому выполнение прерывается. Используйте docker compose -f /srv/myapp/compose.yaml down, если вы находитесь вне папки проекта.

Удаляет ли docker compose down мои тома?

Нет. Именованный том, объявленный в ключе верхнего уровня volumes, сохраняется после выполнения down, как и после удаления контейнера, к которому он был присоединен. Это наиболее распространенное опасение относительно данной команды, и ответ остается неизменным для Compose v2.

Подготовьте стек для тестирования. Разместите следующий код в compose.yaml в пустой директории с названием voltest.

services:
  db:
    image: postgres:16.4
    restart: unless-stopped
    environment:
      POSTGRES_PASSWORD: example
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:

Запустите стек и запишите строку, которую вы сможете распознать позже.

docker compose up -d
sleep 10
docker compose exec -T db psql -U postgres -c "create table marker (note text);"
docker compose exec -T db psql -U postgres -c "insert into marker values ('survived');"

Теперь удалите контейнер и проверьте состояние тома.

docker compose down
docker volume ls

В выводе по-прежнему отображается voltest_pgdata. Контейнер удален, но данные остались. Запустите стек снова и прочитайте строку.

docker compose up -d
sleep 10
docker compose exec -T db psql -U postgres -c "select * from marker;"

Вы получите одну строку, содержащую survived. Новый контейнер — это другой экземпляр с другим ID, присоединенный к тому же тому. Если вам нужна более подробная информация, руководство по основам Compose описывает разницу между именованными томами и bind mounts, а также расположение данных на хосте.

Что именно удаляет down -v

-v (полная форма --volumes) удаляет именованные тома, объявленные в разделе volumes файла Compose, а также анонимные тома, присоединенные к контейнерам. Запустите эту команду для того же стека.

docker compose down -v
docker volume ls

voltest_pgdata больше не отображается в списке. Запустите стек снова, и точка входа Postgres обнаружит пустой каталог данных, после чего инициализирует новый кластер. Журнал контейнера сообщает об этом прямо.

The files belonging to this database system will be owned by user "postgres".
PostgreSQL init process complete; ready for start up.

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

Некоторые хранилища никогда не удаляются командой -v. Bind mount представляет собой путь на хосте, поэтому Docker лишь отмонтирует его, а ваши файлы остаются на месте. Том, помеченный как external: true, объявлен как принадлежащий объекту вне данного проекта, и Compose никогда его не удаляет. Именованный том, который вы удалили из файла Compose перед запуском down -v, больше не объявлен, поэтому Compose не знает о необходимости его удаления, и он остается в системе как «сирота» для docker volume prune.

Последний случай часто встречается при рефакторинге. Если удалить сервис и его том из файла, а затем запустить down -v, том сохранится, так как файл больше не содержит упоминаний о нем. Запускайте down -v до редактирования файла, а не после.

Когда на самом деле нужен --force-recreate

docker compose up -d не пересобирает всё окружение каждый раз. Compose сохраняет хеш разрешенной конфигурации каждой службы в виде метки контейнера. Если хеш совпадает и ID образа идентичен, контейнер остается без изменений, и вы получаете Container voltest-db-1 Running вместо Recreated. Это поведение, которое требуется почти всегда, так как оно делает up -d безопасным для многократного запуска.

Именно поэтому некоторые изменения кажутся неэффективными. Compose хеширует разрешенное определение службы, а не содержимое файлов, на которые это определение ссылается. Файл конфигурации, смонтированный в контейнер и прочитанный один раз при запуске, не вызовет пересоздание при редактировании, так как путь монтирования не изменился. Служба продолжает работать со значениями, считанными при загрузке.

docker compose up -d --force-recreate

Эта команда останавливает и удаляет каждый контейнер, а затем создает новый на основе того же определения. Используйте её после редактирования смонтированного файла конфигурации или когда состояние контейнера стало необъяснимым. Тома остаются нетронутыми, поэтому база данных сохраняется после принудительного пересоздания. Чтобы применить более новый образ с тем же тегом, необходимо также выполнить обновление.

docker compose pull
docker compose up -d

pull загружает новый ID образа, после чего up -d обнаруживает отличие ID образа от запущенного контейнера и автоматически пересоздает его. Использование --force-recreate без pull приведет к созданию нового контейнера из того же старого образа. Именно поэтому жалоба «я выполнил принудительное пересоздание, но версия осталась старой» встречается так часто.

docker compose restart не выполняет ничего из вышеперечисленного. Команда перезапускает существующие контейнеры и не считывает файл Compose повторно, поэтому измененная переменная окружения или измененная привязка портов не применятся. Если вы отредактировали файл, используйте up -d.

Концептуальная модель

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

Каждая команда Compose соответствует этому разделению. stop и start сохраняют контейнер. down и up заменяют контейнер, сохраняя том. down -v — это единственная стандартная команда, которая удаляет состояние, поэтому для нее требуется явный флаг. Прежде чем вводить ее для реальных данных, убедитесь, что у вас есть резервная копия, которую вы хотя бы раз успешно восстанавливали.

Та же логика применима к секретам. Пароль, заданный через POSTGRES_PASSWORD, считывается только при первой инициализации базы данных, поэтому изменение его в файле окружения и выполнение up -d приведет к password authentication failed for user "postgres". Контейнер будет новым, а том — старым, и в старом томе по-прежнему будет храниться старый пароль. Как Compose обрабатывает файлы окружения и секреты объясняет, какой слой имеет приоритет, если одна и та же переменная задана дважды.

Типы сбоев и сообщения об ошибках

no configuration file provided: not found означает, что Compose запущен в каталоге, где отсутствуют compose.yaml и docker-compose.yml. Передайте -f с указанием полного пути.

network voltest_default has active endpoints в down означает, что к сети проекта подключен контейнер, не относящийся к данному проекту; как правило, он был запущен вручную с помощью docker run --network. Удалите этот контейнер, а затем снова выполните down.

Found orphan containers ([voltest-old-1]) for this project появляется после переименования или удаления службы. Старый контейнер по-прежнему содержит метку проекта. docker compose down --remove-orphans удаляет такие контейнеры; эту команду безопасно выполнять для работающего стека.

Error response from daemon: remove voltest_pgdata: volume is in use при ручном docker volume rm означает, что какой-либо контейнер все еще ссылается на том, включая остановленные контейнеры. Сначала выполните docker compose down, затем удалите том, либо просто используйте down -v. В более крупных проектах многосервисный стек Compose демонстрирует, какое количество томов может накапливать один проект.

FAQ

Удаляет ли docker compose down мою базу данных?

Нет, если база данных находится в именованном томе или примонтированном каталоге (bind mount). down удаляет контейнеры и сеть проекта, а том остается на диске вместе с данными. Следующая команда docker compose up -d подключит новый контейнер к тому же тому, и данные будут доступны. Только docker compose down -v удаляет именованные тома, причем только те, что объявлены в секции volumes файла Compose.

В чем разница между stop и down для контейнера, который мне нужен в будущем?

stop сохраняет контейнер, поэтому docker compose start возвращает вас к тому же самому контейнеру с тем же слоем для записи. Все, что вы установили или изменили внутри контейнера вручную, сохраняется. down удаляет контейнер, поэтому при следующем up -d будет создан новый контейнер из образа, и все внесенные вручную изменения будут потеряны. Используйте stop во время отладки.

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

docker compose down -v --rmi all --remove-orphans удаляет контейнеры, сеть проекта, именованные тома, объявленные в файле, образы, которые использовали службы, и любые контейнеры, помеченные именем проекта. Эта команда не затрагивает примонтированные каталоги (bind mounts) или тома, помеченные external: true. Проверьте, что именно будет удалено, с помощью docker volume ls перед запуском.

Почему мой контейнер игнорирует изменения в примонтированном файле конфигурации?

Compose определяет необходимость пересоздания контейнера путем сравнения хеша разрешенного определения службы, и этот хеш не включает содержимое примонтированного файла. Путь не изменился, поэтому Compose оставляет контейнер запущенным с теми значениями, которые были считаны при старте. Выполните docker compose up -d --force-recreate, чтобы создать новый контейнер, который заново считает файл.

Почему мой новый POSTGRES_PASSWORD не работает после изменения?

Образ Postgres считывает POSTGRES_PASSWORD только при инициализации пустого каталога данных. Ваш том уже содержит инициализированный кластер, поэтому переменная игнорируется, и продолжает действовать старый пароль. Вы увидите password authentication failed for user "postgres". Измените пароль с помощью ALTER USER внутри работающей базы данных или удалите данные и начните заново с помощью docker compose down -v.