Learning Platform
Глоссарий Troubleshooting
Урок 05.04 · 18 мин
Начальный
dockerdocker-stopdocker-rmdocker-prunecleanup

docker stop, rm, prune

Поднимать контейнеры легко. Прибирать за собой — отдельный навык. Если ты не следишь, через месяц у тебя на диске будут десятки exited контейнеров, сотни orphaned image-слоёв, и куча неиспользуемых volumes. На mac, где VM имеет ограниченный диск, это особенно болезненно.

В этом уроке: как корректно останавливать контейнеры (с разницей stop vs kill), как удалять, и как массово чистить мусор через prune.


docker stop — корректная остановка

docker stop pg

Что физически происходит:

  1. Docker daemon посылает SIGTERM главному процессу контейнера (PID 1).
  2. Daemon ждёт 10 секунд.
  3. Если процесс не завершился — посылает SIGKILL.
  4. Контейнер переходит в state exited с exit code (130 для SIGTERM, 137 для SIGKILL).
Signals — kill, SIGTERM/SIGKILL и async-signal-safety

SIGTERM — это «вежливый» сигнал: «пожалуйста, заверши работу как следует». Хорошо написанный сервис (Postgres, Redis, nginx) ловит SIGTERM и делает graceful shutdown: дописывает буферы, закрывает соединения, флашит данные.

SIGKILL — это «жёсткое» убийство, которое процесс не может игнорировать. Это плохо для stateful сервисов — Postgres может остаться с inconsistent WAL, придётся recovery при старте.

Поэтому в норме мы хотим SIGTERM с timeout’ом. Если ты знаешь, что твой сервис долго закрывается (например, ETL job, который дописывает batch), увеличь timeout:

docker stop --time=60 pg
# даём 60 секунд на graceful shutdown

docker kill — без вежливости

docker kill pg

Сразу посылает SIGKILL (без SIGTERM, без timeout). Контейнер падает мгновенно.

Когда полезно:

  • Контейнер завис и не отвечает на stop.
  • Тестовая среда, нет состояния.
  • Тебе нужен быстрый выход.

Когда плохо:

  • Любой stateful сервис (Postgres, Kafka, MinIO). Можно потерять данные.

Опционально другие сигналы через -s:

docker kill -s SIGHUP nginx  # перечитать конфиг

docker rm — удалить контейнер

docker rm pg

Удаляет контейнер из системы. После этого контейнер больше не существует — его нет в docker ps -a, его логи стёрты, его writable layer удалён.

Контейнер можно удалить только если он остановлен. Запущенный контейнер удалить нельзя — Docker откажет:

Error response from daemon: cannot remove container <id>: container is running

Решения:

  1. Сначала docker stop, потом docker rm:
docker stop pg
docker rm pg
  1. Или force через -f:
docker rm -f pg

-f — это docker kill + docker rm. Удобно, но небезопасно для stateful сервисов.

Что удаляется вместе с контейнером

  • Writable layer контейнера (изменения, сделанные внутри).
  • Логи контейнера.
  • Привязки к network bridges.

Что не удаляется:

  • Образ, из которого был контейнер — он остаётся.
  • Named volumes — они остаются (это важно! данные сохранены).
  • Bind mount директории на хосте.

docker container prune — массово удалить остановленные

docker container prune

Удаляет все контейнеры в состоянии exited / dead. Спросит подтверждение:

WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
abc123...
def456...
Total reclaimed space: 124MB

Без подтверждения — флаг -f:

docker container prune -f

Это типичный шаг после интенсивной dev-сессии: очистить остановленные контейнеры.

С фильтром можно удалить только старые:

docker container prune --filter "until=24h"
# удалит контейнеры, остановленные более 24 часов назад

docker image prune — мусорные образы

После сборок и pull’ов накапливаются неиспользуемые образы. Их две категории:

  • Dangling — образы без тегов, на которые ничего не ссылается. Получаются от незавершённых build’ов или пересборок (старая версия теперь имеет тег <none>).
  • Unused — образы, которые есть локально, но из них не запущен ни один контейнер.
# Только dangling
docker image prune

# Все unused (более агрессивно)
docker image prune -a

Второй вариант часто сэкономит много места. На dev-машине образы накапливаются быстро — postgres:13, 14, 15, 16 и все pull’ы, которые ты делал.


docker volume prune — забытые volumes

docker volume prune

Удаляет volumes, которые не привязаны ни к одному контейнеру.

DANGER

ВНИМАНИЕ: volume prune удаляет данные. Если у тебя в volume лежит твоя локальная Postgres-база с важными dev-данными, и нет работающего контейнера, который её использует — она будет удалена. Сначала всегда проверь: docker volume ls.


docker system prune — большая уборка

docker system prune

Эта команда чистит сразу:

  • Все остановленные контейнеры.
  • Все dangling образы.
  • Неиспользуемые networks.
  • Build cache.
docker system prune -a

Дополнительно: все unused образы (не только dangling).

docker system prune -a --volumes

Дополнительно: все unused volumes. Это самая агрессивная команда — после неё на диске остаётся только то, что прямо сейчас используется.

docker system prune — что чистится при разных флагах
system pruneОстанов контейнеров, dangling images, unused networks, build cache. Volumes НЕ трогает
system prune -a+ все unused images (не только dangling). Если у тебя 30 postgres-образов разных версий и сейчас работает только один — остальные удалятся
system prune -a --volumes+ все unused volumes. Самая агрессивная команда. Volumes без работающего контейнера будут удалены — это удаление ДАННЫХ
system prune -fБез подтверждения. В скриптах. Для интерактивной работы лучше с подтверждением

docker system df — сколько занято

Перед уборкой полезно посмотреть, что у тебя занимает место:

docker system df

Пример вывода:

TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          47        8         12.3 GB   9.1 GB (74%)
Containers      23        4         512 MB    498 MB (97%)
Local Volumes   12        3         3.2 GB    2.8 GB (87%)
Build Cache     156       0         4.7 GB    4.7 GB

RECLAIMABLE — сколько можно освободить через prune. Здесь видно, что 9 ГБ images + 4.7 ГБ build cache можно убрать.

С -v (verbose) — детально по каждому образу/контейнеру:

docker system df -v

Восстановление диска на mac (специфика)

На mac контейнеры и образы живут в VM, которая представлена одним большим виртуальным диском. Этот диск растёт по мере использования, но не сжимается обратно автоматически после prune.

После docker system prune место освобождается внутри VM, но размер виртуального диска не уменьшается. Чтобы реально вернуть место на хост-mac:

  • Docker Desktop: Settings -> Resources -> Advanced -> “Clean / Purge data” или уменьшить Disk image size (с пересозданием VM).
  • OrbStack: orb info disks — посмотреть размер. orb purge — пересоздать VM с нуля.

Это редкая, но важная процедура — раз в полгода полезно «фактически» вернуть место.


Попробуй сам

# 1. Запусти несколько контейнеров
docker run --rm hello-world
docker run --rm hello-world
docker run -d --name temp1 nginx
docker run -d --name temp2 redis:alpine

# 2. Посмотри состояние
docker ps -a
docker system df

# 3. Останови (graceful)
docker stop temp1 temp2

# 4. Удали
docker rm temp1 temp2

# 5. Глобально подчистись
docker container prune -f
docker image prune -f

# 6. Большая уборка (осторожно — удаляет всё неиспользуемое!)
# docker system prune -a -f --volumes

# 7. Проверь
docker system df

Обрати внимание, как меняется размер RECLAIMABLE после каждого prune.


Связь с дальнейшими модулями

  • Модуль 08 (volumes): подробнее про docker volume. Очень аккуратно с volume prune — это удаление данных.
  • Модуль 13 (debug): иногда не удалять контейнер — это часть стратегии дебага. Сначала логи и inspect, потом rm.
  • Модуль 17 (CI): в CI важно, чтобы build cache не разрастался — там docker system prune -f --filter "until=72h" в cron’е.

Проверка знанийKnowledge check
В чём разница между docker stop и docker kill, и почему важно использовать stop для stateful сервисов как Postgres?
ОтветAnswer
docker stop посылает главному процессу контейнера SIGTERM (вежливый сигнал «пожалуйста, заверши работу»), ждёт 10 секунд по умолчанию (можно изменить через --time=N), и только потом, если процесс не завершился, посылает SIGKILL. docker kill сразу посылает SIGKILL, без SIGTERM и без timeout. Разница принципиальна для stateful сервисов. Postgres, например, на SIGTERM делает graceful shutdown: завершает активные транзакции, дописывает WAL-журнал, флашит буферы на диск, корректно закрывает файлы. На SIGKILL Postgres падает мгновенно — WAL может остаться inconsistent, при следующем старте придётся делать crash recovery, в редких случаях возможна потеря последних транзакций. То же касается Kafka, MinIO, Redis, любой базы данных или queue. Для stateless сервисов (например, тестового nginx) разница не критична. Если контейнер завис и не отвечает на stop в течение нескольких минут — kill оправдан. Но как привычку в daily-работе — всегда сначала docker stop, и только если не сработало — kill. То же в Compose: docker compose down делает stop по-умолчанию, не kill.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 5. Что делает docker stop?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 5