Logging & log drivers
Where container output goes, and how to ship it.
By default a container’s STDOUT and STDERR are captured by the daemon’s logging driver, and docker logs replays them. That default is intentional: containerized apps should log to stdout/stderr, not to files inside the container, so the platform can collect the stream. The choice that matters is which driver receives it — and the default, json-file, has a footgun.
$ docker logs -f --tail 50 web # follow the last 50 lines$ docker inspect -f '{{.HostConfig.LogConfig.Type}}' webjson-file # the default driver
json-file and the rotation footgun
json-file writes each container’s output to a JSON file on the node and, by default, never rotates it — a chatty container can fill the disk and take the host down. Always cap it, either per container or (better) as an engine-wide default in daemon.json, so every container inherits bounded logs. This is the single most common Docker-logging incident.
{"log-driver": "json-file","log-opts": { "max-size": "10m", "max-file": "3" } // bound + rotate, cluster-wide}// per-container override:// docker run --log-opt max-size=5m --log-opt max-file=2 ...
Choosing a driver
The driver decides where logs go. json-file (default) and local keep them on the node for docker logs. journald hands them to the systemd journal (queryable with journalctl). syslog, fluentd, gelf, and awslogs ship them off-box to a central collector or SIEM — the right choice in production, because node-local logs vanish with the node and are the first thing an attacker edits. Note docker logs only works with the file/journald drivers; with a remote driver you read logs in the collector, not from Docker.