Логи контейнера растут без ограничения: настраиваем ротацию json-file

На хосте заканчивается диск, а каталог данных приложения почти не меняется. Один шумный контейнер способен накопить большой json-file: Docker сохраняет stdout и stderr с метаданными времени и потока. Перед очисткой нужно установить фактический logging driver и настроить ограничение будущего роста. Удаление файлов вслепую оставляет причину на месте.

Проверяем драйвер контейнера, а не только default

docker info --format "{{.LoggingDriver}}"
docker inspect --format "{{json .HostConfig.LogConfig}}" CONTAINER_ID
docker inspect --format "{{.LogPath}}" CONTAINER_ID

Первая команда показывает текущий default daemon, вторая — настройку конкретного созданного контейнера. Они могут различаться: контейнер хранит конфигурацию со времени создания. LogPath полезен для установления расположения журнала, но это не приглашение изменять файл внешними утилитами. В Docker Desktop путь относится к среде Linux Engine, а не обязательно к доступному каталогу Windows.

Если драйвер journald, local или внешний, параметры json-file к нему не применяются. Если приложение пишет в собственный файл volume вместо stdout, ротация Docker этот файл не ограничит. Сопоставьте рост с конкретным источником. Для общей диагностики диска отдельно оценивают образы, build cache и данные; здесь рассматривается только журнал контейнера.

Задаём политику в Compose

В учебном примере сервис пишет время раз в секунду. Настройка logging ограничивает размер одного файла и количество сохраняемых файлов:

services:
  logger:
    image: alpine:3.22
    command: ["sh", "-c", "while true; do date; sleep 1; done"]
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
docker compose -p loglab config --quiet
docker compose -p loglab up -d
docker compose -p loglab ps logger
docker compose -p loglab logs --tail 20 logger

max-size включает ротацию при достижении границы, max-file ограничивает число файлов при такой ротации. Значения options задаются строками, включая "3". Оценка 10 × 3 = 30 MB полезна как порядок объёма одного контейнера, но не как точная гарантия общего использования диска: есть формат записей, границы ротации, другие контейнеры и другие данные Engine.

Выбирайте размер по интенсивности журнала и нужному локальному окну диагностики. Три файла могут хранить часы спокойного приложения или несколько минут аварийного потока. Если журналы нужны дольше, отправляйте их в систему хранения с собственной политикой retention. Локальная ротация защищает диск, но не заменяет доставку и поиск журналов.

Применяем к существующему сервису

Изменение Compose-файла нужно применить пересозданием контейнера в согласованное окно. Обычный restart старого контейнера не меняет его LogConfig. Перед пересозданием сохраните нужную историю инцидента: локальные журналы связаны с конкретным контейнером и могут исчезнуть вместе с ним. Проверьте доступность приложения после обновления конфигурации.

Default можно задать в daemon.json через log-driver и log-opts. Эта настройка требует принятой процедуры изменения Docker daemon и не меняет уже существующие контейнеры автоматически. На Docker Desktop редактируется конфигурация его Engine, а на Linux — конфигурация соответствующей установки. Не перезапускайте daemon рабочего хоста без понимания затрагиваемых сервисов; локальная настройка Compose удобнее для отдельного приложения.

Подтверждаем фактический результат

docker inspect --format "{{json .HostConfig.LogConfig}}" NEW_CONTAINER_ID

У нового контейнера должны быть driver json-file и выбранные options. Затем наблюдайте рост на достаточном интервале или проведите отдельный нагрузочный тест логирования в учебном проекте. Проверка config подтверждает структуру, inspect — применённую конфигурацию, а измерение файлов — реальную ротацию. Это разные уровни доказательства.

Не запускайте truncate, logrotate или ручное удаление файлов json-file, которыми управляет Docker daemon. Внешнее вмешательство может нарушить его работу и оставить занятое место у открытого файла. Если диск уже критически заполнен, согласуйте ограничение источника потока и управляемую замену контейнера с сохранением нужных данных, вместо стихийной очистки системных каталогов.

Дополнительно исправьте причину чрезмерного потока: debug-уровень, повтор одной ошибки или вывод большого payload. Ротация ограничивает последствия, а качество журнала влияет на возможность найти причину следующего сбоя. Сохраните интенсивность потока и срок доступной локальной истории вместе с выбранными max-size и max-file.

Ещё по теме

Продолжить изучение

Хотите разобраться в контейнеризации целиком, от образа до работающего окружения? Сборка, сети, данные и запуск приложений входят в программу «Docker и Docker Compose: контейнеризация приложений».

Продолжить на практике

  • Docker и Docker Compose: контейнеризация приложений ↗

    Упакуйте приложение в Docker и запустите его с PostgreSQL через Compose. Образы, сети, тома, диагностика поломок, обновление версий и восстановление данных — с практикой и итоговым проектом.