✦ For everyone, free.

Practical knowledge for real and everyday life

Home

15.1.2.2 Local Log Driver

A focused guide to Local Log Driver, connecting core concepts with practical Docker and container operations.

The local logging driver is Docker's storage-optimized alternative to json-file, retaining the same local readability and docker logs compatibility while using a more compact, binary, custom file format that reduces both disk usage and the CPU overhead of writing log entries, making it the more efficient default for most production deployments that still want local log storage.

Why local exists alongside json-file

json-file's plain JSON text format is easy to inspect directly but carries real overhead: every log line is wrapped in JSON syntax with field names repeated on every entry, and rotation defaults to uncompressed storage unless explicitly configured otherwise. The local driver was introduced specifically to address this, using a more efficient on-disk representation while preserving the same fundamental capability, local storage that docker logs can read back:

docker run -d --log-driver=local my-api
docker logs my-api

From the perspective of docker logs, there is no functional difference in how output is displayed; the difference is entirely in how compactly and efficiently the driver stores that output on disk.

Built-in rotation and compression by default

Unlike json-file, where rotation and compression must be explicitly configured to avoid unbounded growth, the local driver applies sensible default limits automatically, rotating and compressing log files even if no explicit --log-opt values are provided:

docker inspect --format='{{.HostConfig.LogConfig}}' my-api
docker run -d --log-driver=local --log-opt max-size=20m --log-opt max-file=5 my-api

This default-safe behavior is one of the strongest practical arguments for preferring local over json-file as a daemon-wide default: a container started without any explicit logging configuration at all is still protected against unbounded local disk growth when local is the active driver.

Setting local as the daemon-wide default

Because local behaves safely out of the box and offers reduced overhead compared to json-file, configuring it as the daemon's default logging driver is a reasonable production hardening step that benefits every container on the host without requiring per-container configuration:

{
  "log-driver": "local",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
systemctl restart docker

Existing containers created before this daemon configuration change continue using whichever driver was active at their creation time; the new default only applies to containers created afterward, which means a full container recreation cycle is needed to migrate an entire host's running containers to the new default.

File format differences from json-file

The local driver does not store logs as human-readable JSON text; its on-disk format is a Docker-specific binary structure not intended to be read directly with standard text tools the way a json-file log can be:

cat /var/lib/docker/containers/3f29a8c1.../local-logs/container.log

Attempting to read this file directly typically produces unreadable binary output, which is the direct trade-off for the reduced size and overhead: the format is optimized for Docker's own read path through docker logs, not for ad hoc inspection with generic Unix tools the way json-file's plain JSON lines are.

Implications for log collection agents

A log collection agent designed to read json-file's plain-text format directly from disk will not work against the local driver's binary format without specific support for it, which is an important consideration when choosing a collection architecture that depends on reading container log files directly from the host filesystem rather than going through the Docker API:

[INPUT]
    Name tail
    Path /var/lib/docker/containers/*/*.log
    Parser docker

A tail-based collector configuration written for json-file's format generally needs to be reconsidered, or the collection approach changed to read through docker logs or a different mechanism, if the daemon's default driver is switched to local.

When local is and is not the right choice

local is the better default for the common case of a single-host or small-cluster deployment that wants local log storage with docker logs access but does not need the plain-text inspectability json-file provides, and benefits from the reduced overhead and safer default rotation behavior. It is the wrong choice if a log collection pipeline specifically depends on parsing json-file's plain JSON text format directly from disk without modification, or if an operator genuinely needs to inspect raw log files with standard Unix text tools without going through docker logs at all.

docker run -d --log-driver=local --log-opt max-size=10m my-api
docker logs --tail 100 my-api

Migrating from json-file to local

Switching a container from json-file to local requires recreating the container, since the logging driver is fixed at creation time; existing log history under the previous driver's format is not carried over or merged into the new driver's storage:

docker stop my-api
docker rm my-api
docker run -d --log-driver=local --name my-api my-api:1.4.0

Planning this migration as part of a routine deployment, rather than as a disruptive standalone change, is the most practical way to roll it out across a fleet of containers over time as they are naturally recreated through normal deployment activity.

Common mistakes

  • Assuming the local driver's on-disk files can be read directly with standard text tools the way json-file's can, leading to confusion when the output appears as unreadable binary data.
  • Continuing to use a json-file-specific log collection configuration unchanged after switching the daemon default to local, causing the collector to silently stop working.
  • Not realizing existing containers retain their original driver after a daemon-level default change, leading to inconsistent logging behavior across a host's containers until they are recreated.
  • Choosing json-file by habit for new deployments without considering that local generally provides equivalent functionality with better default safety and lower overhead.
  • Overlooking that local's default rotation and compression behavior, while safer than json-file's unconfigured defaults, can still be tuned explicitly if the defaults do not match a specific workload's actual log volume.

The local driver is generally the more sensible default than json-file for production use, offering the same docker logs compatibility with reduced overhead and safer out-of-the-box rotation behavior, provided any log collection tooling reading directly from disk is updated to handle its different, non-text on-disk format.