How to Redirect Docker Logs to a Single File
Learn how to redirect Docker logs to a single file using docker logs commands, json-file driver configuration, and the local driver. Practical guide with code examples.

Docker stores each container’s logs in separate files under /var/lib/docker/containers/. When you’re running multiple containers, searching through scattered log files gets old fast. This guide shows three ways to redirect Docker logs to a single file — from a quick one-liner to daemon-wide configuration.
Other Docker guides you might find useful:
- Add Users to a Docker Container
- Copy Multiple Files in One Layer Using a Dockerfile
- Install Docker & Docker-compose for Ubuntu ARM
- Environment Variables ARG and ENV in Docker
Method 1: One-off redirect with docker logs
The simplest way to dump container logs to a file:
docker logs my-container > container.log 2>&1
The 2>&1 part matters. Without it, you only capture stdout. stderr gets lost. This command merges both streams into one file.
To follow logs in real-time and write them continuously:
docker logs -f my-container > container.log 2>&1 &
The -f flag follows new output. The & runs it in the background. This is useful for debugging but has limitations — the process dies when your shell session ends.
To capture logs from multiple containers into one file:
for container in $(docker ps --format '{{.Names}}'); do
echo "=== $container ===" >> all-logs.log
docker logs "$container" >> all-logs.log 2>&1
done
When to use this method: Quick debugging, one-off log exports, or when you need a snapshot of what’s happening right now.
Method 2: Configure json-file driver with rotation
Docker uses the json-file logging driver by default. It writes logs as JSON to /var/lib/docker/containers/<id>/<id>-json.log. The catch: no rotation is enabled by default. A chatty container will fill your disk.
Per-container configuration
Set the logging driver when starting a container:
docker run -d \
--name my-app \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
my-app:latest
max-size=10m— caps each log file at 10 MBmax-file=3— keeps 3 rotated files (oldest gets deleted)
With these settings, the container uses at most 30 MB for logs.
Daemon-wide configuration
To apply rotation to every new container, edit /etc/docker/daemon.json:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
Restart Docker for the changes to take effect:
sudo systemctl restart docker
Important: Existing containers don’t pick up the new defaults. You need to recreate them. Also, all values in daemon.json must be strings — "max-file": 3 (without quotes) will break the daemon.
Verify the configuration
Check a container’s current logging driver:
docker inspect --format='{{.HostConfig.LogConfig}}' my-app
Find the log file path:
docker inspect --format='{{.LogPath}}' my-app
Method 3: Use the local driver (recommended for production)
The local driver is Docker’s recommended replacement for json-file in most situations. It uses a more efficient binary format, compresses rotated files automatically, and has sensible defaults (20 MB per file, 5 files kept).
{
"log-driver": "local"
}
Or per-container:
docker run -d \
--name my-app \
--log-driver local \
my-app:latest
The docker logs command works the same way with both drivers.
Why json-file is still the default: Docker can’t switch without breaking tools that depend on the json-file layout — Kubernetes being the main one. If you’re not running Kubernetes, use local.
Docker Compose configuration
For Compose stacks, use the logging key:
services:
api:
image: my-app:latest
logging:
driver: local
worker:
image: my-worker:latest
logging:
driver: json-file
options:
max-size: "20m"
max-file: "5"
To apply the same logging config across all services with a YAML anchor:
x-logging: &default-logging
driver: json-file
options:
max-size: "10m"
max-file: "3"
services:
api:
image: my-app:latest
logging: *default-logging
worker:
image: my-worker:latest
logging: *default-logging
Where Docker stores logs by default
Before redirecting logs, it helps to understand the default behavior:
- Docker captures stdout and stderr from every container
- Each container gets its own log file under
/var/lib/docker/containers/ - Logs are stored in JSON format with timestamps and stream type
- No rotation is enabled by default (this is the main problem)
Find the log file for a specific container:
docker inspect --format='{{.LogPath}}' my-container
Output looks like:
/var/lib/docker/containers/a4f8c9e1.../a4f8c9e1...-json.log
Each line is a JSON object:
{"log":"Listening on port 8080\n","stream":"stdout","time":"2023-07-03T10:14:02.123456789Z"}
Don’t use external log rotation tools (like logrotate) on Docker’s internal log files. Docker assumes exclusive access. External truncation can corrupt log state or prevent containers from being removed.
Forwarding logs to a central system
For production setups with multiple hosts, consider forwarding logs to a central system:
Syslog driver
docker run -d \
--log-driver syslog \
--log-opt syslog-address=tcp://logs.example.com:514 \
--log-opt tag="{{.Name}}" \
my-app:latest
Fluentd driver
docker run -d \
--log-driver fluentd \
--log-opt fluentd-address=localhost:24224 \
--log-opt tag="docker.{{.Name}}" \
my-app:latest
Since Docker 20.10, remote drivers (syslog, fluentd, splunk) automatically maintain a local cache alongside forwarding. docker logs still works. The cache uses the local driver internally with 5 files of 20 MB each.
Other available drivers: journald, gelf (Graylog), awslogs (CloudWatch), splunk.
Common issues
Container logs filling disk: Enable rotation with max-size and max-file. This is the most common Docker disk issue. Without rotation, json-file has no upper bound.
docker logs not showing output after changing driver: Make sure the container was created after the daemon configuration change. Existing containers keep their original settings.
Daemon won’t start after editing daemon.json: Validate the JSON first:
sudo dockerd --validate --config-file /etc/docker/daemon.json
If the daemon is already down, check journalctl -u docker for error details.
Want to disable local caching for remote drivers: Add "cache-disabled": "true" to log-opts.
Which method should you use?
| Method | Best for | Persistence |
|---|---|---|
docker logs > file |
Quick debugging, one-off exports | No (runs in shell) |
json-file with rotation |
Single-host setups, Kubernetes | Yes (managed by Docker) |
local driver |
Single-host production setups | Yes (more efficient) |
syslog/fluentd |
Multi-host, centralized logging | Yes (external system) |
For most self-hosted setups, the local driver with default settings is the right choice. It handles rotation automatically and uses less disk than json-file.


