Проблема переполнения диска в Docker: безопасная очистка overlay2 и работа с огромными логами на продакшене

Как очистить папку /var/lib/docker/overlay2 и безопасно удалить логи контейнеров

Ситуация, когда мониторинг внезапно сообщает о нулевом свободном месте на разделе /var/lib/docker, знакома практически каждому системному администратору или DevOps-инженеру. В такие моменты первой под руку попадается папка overlay2, которая весит десятки, а то и сотни гигабайт.

Почему нельзя удалять overlay2 вручную?

Попытка бездумно очистить эту директорию командой rm -rf на работающем сервере — это самый короткий путь к полному отказу всех сервисов. Дело в том, что именно здесь Docker хранит не просто кэш, а физические слои ваших образов и, что критически важно, записываемые слои (writable layers) запущенных контейнеров.

Удаление этих данных «на горячую» приведет к катастрофическим последствиям:

  1. Контейнеры моментально потеряют доступ к своим файловым системам.
  2. База данных Docker придет в негодность.
  3. Потребуется полная переустановка Docker и перезапуск всех сервисов.

Скрытая угроза: JSON-логи

Часто истинная причина нехватки места кроется вовсе не в самих образах, а в логах, которые Docker заботливо собирает в формате JSON. Если вы обнаружили внутри вложенных директорий файл с расширением -json.log, который разросся до невероятных 60–70 гигабайт, знайте — это и есть ваш главный враг.

Обычное удаление такого файла через rm тоже не поможет. В Linux-системах процесс, пишущий в файл, удерживает его дескриптор, поэтому место на диске не освободится до тех пор, пока вы не перезапустите контейнер. На работающем продакшене это лишний простой, которого можно легко избежать.

Как правильно очистить логи без перезагрузки

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

Для очистки конкретного файла используйте команду:

truncate -s 0 /var/lib/docker/containers/<container_id>/<container_id>-json.log

Если же нужно почистить всё разом, можно воспользоваться поиском через find по всей директории контейнеров, применяя ту же операцию обнуления ко всем найденным лог-файлам:

find /var/lib/docker/containers/ -type f -name "*.log" -exec truncate -s 0 {} +

Настройка ротации логов (daemon.json)

Чтобы не превращаться в «пожарного» и не заниматься ручной очисткой каждую неделю, проблему нужно решать на уровне конфигурации демона. По умолчанию Docker не ограничивает размер лог-файлов, что и приводит к подобным инцидентам.

В файле настроек /etc/docker/daemon.json следует обязательно прописать параметры ротации, такие как max-size и max-file.

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "50m",
    "max-file": "3"
  }
}

Например, ограничение в пятьдесят мегабайт и хранение всего трех архивных копий навсегда застрахует вас от внезапного переполнения диска.

Важно: Эти настройки применятся только к вновь создаваемым контейнерам. Старые «тяжелые» инстансы придется пересоздать (docker-compose up -d --force-recreate) после внесения правок в конфиг и перезагрузки демона Docker.

Очистка неиспользуемых ресурсов

Помимо логов, стоит обратить внимание на «висячие» ресурсы. Команда docker system prune является отличным санитаром системы, так как она удаляет только те данные, которые гарантированно не используются:

  • Остановленные контейнеры
  • Неиспользуемые сети
  • Образы без тегов (dangling images)
docker system prune

Это верный и безопасный способ поддерживать чистоту в /var/lib/docker/overlay2, не рискуя стабильностью продакшена. Комбинируя правильную настройку ротации логов и периодическую очистку неиспользуемых объектов, можно навсегда забыть о критических уведомлениях о нехватке места.