Очистка Docker: почему «неиспользуемый» не значит «ненужный»
Как освободить диск от образов, томов и кэша — и не снести при этом то, без чего сервис потом не поднимется. С разбором реального случая.
miki/ochistka-docker-pochemu-neispolzuemyy-ne-znachit-nenuzhnyy · v1
Как освободить диск от образов, томов и кэша — и не снести при этом то, без чего сервис потом не поднимется. С разбором реального случая.
Docker не убирает за собой. Каждая сборка оставляет слои, каждый перезапуск — старые образы. На активном сервере десятки гигабайт накапливаются за месяцы, и однажды диск просто кончается. Причём в самый неудачный момент: когда сервису надо перезапуститься.
Но у очистки есть обратная сторона, про которую редко пишут. Она в конце списка, и это самая важная часть.
Разобраться
Сначала диск целиком, потом Docker отдельно:
docker system df разбивает по категориям: образы, контейнеры, тома, кэш сборки. Колонка RECLAIMABLE показывает, сколько можно освободить.
Подробнее — флаг -v.
docker system df -v- Ты знаешь, сколько процентов диска занято
- Ты знаешь, какая категория Docker занимает больше всего
Очистка
С этого начинай — риска почти нет, а освобождается много:
Кэш сборки обычно самая жирная строка на сервере, где регулярно собирают образы. Его потеря стоит только времени следующей сборки.
docker builder prune- Освобождённый объём виден в выводе команды
- Запущенные контейнеры не пострадали
Разница принципиальная. Без -a удаляются только висячие слои — остатки пересборок. С -a удаляются все образы, на которых прямо сейчас не запущен ни один контейнер.
Фильтр until=24h оставляет свежее — то, что скачали сегодня для выкатки.
docker image prune- Ты понимаешь разницу между prune и prune -a
Почти вся документация по очистке говорит: «безопасно, удаляются только неиспользуемые ресурсы». Это правда буквально и обманчива по сути.
Реальный случай. Сервис в кластере лежал в состоянии 0/1 — упал несколько недель назад и не поднялся. Контейнера нет, значит образ не используется. Прошла очистка с -a и честно его удалила.
Когда дошли руки починить сервис, оказалось:
Образ пришлось тянуть заново — а это требует сети, доступа к реестру и времени. Если реестр приватный, а ключи истекли — восстановление превращается в отдельный квест.
Что из этого следует:
| Ресурс | Когда считается неиспользуемым | Чем грозит удаление |
|---|---|---|
| Образ | на нём не запущен ни один контейнер прямо сейчас | лежачий сервис не поднимется без сети |
| Том | не прикреплён ни к одному контейнеру | потеря данных навсегда |
| Сеть | нет подключённых контейнеров | почти ничем, создастся заново |
Правило: перед prune -a проверь, нет ли сервисов в состоянии 0/N. Их образы выглядят ненужными ровно до того момента, когда понадобятся.
Очистка
Смотри список и удаляй поимённо:
Никогда не запускай docker volume prune на сервере с базами, не посмотрев список. Том остановленной базы считается неприкреплённым.
docker volume ls -f dangling=true- Ты просмотрел список томов глазами
- Ты не запускал volume prune без проверки
Автоматизация
Ручная очистка работает один раз — потом про неё забывают. Рабочая схема из двух задач cron:
Разумные пороги в скрипте мониторинга:
Обязательно пиши логи — иначе при пропаже образа не узнаешь, кто его удалил и когда.
crontab -l- Задачи видны в crontab -l
- Очистка пишет лог, и ты знаешь где он
- Автоочистка не использует prune для томов
Одна команда, которую стоит запомнить как опасную: docker system prune -a --volumes. Она убирает всё сразу, включая тома. На сервере с боевыми данными её не запускают никогда.

