Intro
Docker logging drivers and container observability basics matter because containers start quickly but operating them consistently is harder. A practical guide shows what to configure, which command proves the configuration works, and what failure looks like when the setup is wrong.
This guide explains how Docker logging works, how to inspect container logs, how logging drivers affect observability, and how to prevent uncontrolled disk growth from unrotated log files.
The goal is practical: understand the moving parts, test them locally, and avoid surprises when the same pattern is reused in CI/CD or a production‑like environment.
Workflow Overview
Start by identifying the resource, the configuration change, and the verification command. Keep the workflow simple: configure one thing, verify the observed state, then document what breaks when the setup is missing, misconfigured, or moved to a production‑like host.
Key concepts: Docker logging, logging drivers, docker logs, log rotation, container observability. Related areas such as Docker debugging, production troubleshooting, and container operations matter because a storage choice influences deployment, debugging, backup, and rollback decisions.
Practical checks
- List running containers with details:
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" - View recent log lines:
docker logs <container> --tail 100 - Inspect container configuration:
docker inspect <container>(shows mounts, networks, environment, health status) - For Compose projects:
docker compose ps,docker compose logs -f <service>,docker compose exec <service> sh
Data location awareness
Before changing containers, confirm where files are stored.
- Named volume (managed by Docker):
app_data:/var/lib/app– easier to reuse across rebuilds. - Bind mount (host directory):
./data:/var/lib/app– useful for local development but can expose permission, portability, and backup problems if the path does not exist on another machine.
Restart test
Run a small production‑like test: stop the container, recreate it, and verify the application still sees the expected files. If data disappears, the service was likely writing to the container’s writable layer instead of a volume or mount.
Common logging drivers at a glance
| Driver | Typical Use | Rotation Support | Remote Destination |
|---|---|---|---|
| json-file | Default on most Linux hosts; local file storage | Size & count via max-size, max-file | No |
| syslog | Centralised syslog server | Handled by syslog daemon | Yes (UDP/TCP) |
| journald | systemd journal integration | Managed by journald | No (local) |
| gelf | Graylog / Logstash | Handled by remote endpoint | Yes (UDP/TCP) |
| fluentd | Fluentd forwarder | Handled by Fluentd | Yes (TCP) |
Hidden assumptions to surface
- The default driver on many distributions is
json-file, but some (e.g., Fedora, RHEL) default tojournald. - The host path
/var/lib/dockermust have enough free space for log files. - The user running Docker must have permission to read the log directory for manual inspection.
- In CI runners, the default logging driver may be
none; explicitly set the driver in the job definition.
Local Pilot Plan
Apply the same workflow to a local pilot. Choose a single service, enable a logging driver with rotation, and verify the behavior before scaling.
Example: enable json‑file driver with size‑based rotation
docker run -d \
--name webapp \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
nginx:alpine
Verify the driver and options
docker inspect --format '{{.HostConfig.LogConfig}}' webapp
# Expected output: map[Type:json-file Config:map[max-size:10m max-file:3]]
Observe rotation in action
Generate enough log data to trigger rotation, then list the log files on the host:
# Find the log path
docker inspect --format '{{.LogPath}}' webapp
# Example output: /var/lib/docker/containers/<id>/<id>-json.log
ls -lh /var/lib/docker/containers/<id>/
You should see up to three files, each ≤ 10 MiB. Without max-size and max-file, the single log file grows until the host disk fills – a common production failure.
Compose equivalent
services:
webapp:
image: nginx:alpine
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
Run docker compose up -d and verify with docker compose logs -f webapp.
Additional verification commands
- Show log disk usage:
docker system df -v(look for "Log" column). - Filter logs by time:
docker logs --since 1h --until 2h webapp. - Follow live output with timestamps:
docker logs --follow --timestamps webapp.
Simulate log growth for testing
docker run --rm \
--log-driver json-file \
--log-opt max-size=1m \
--log-opt max-file=2 \
alpine sh -c 'for i in $(seq 1 5000); do echo "log line $i\); done'
After the command finishes, inspect the container’s log directory to confirm two rotated files of roughly 1 MiB each.
Conclusion
Docker logging drivers and container observability basics work best when the team treats the configuration as something to test, not just copy. Keep examples small, run the commands locally, and confirm the expected behavior before adding more services or automation.
Next step: pick one service, document the exact commands used to build, run, inspect, stop, and recreate it. Compare the results with related areas such as Docker debugging, production troubleshooting, and container operations so the implementation fits the larger operating model.
A reliable container workflow makes failure visible: logs are easy to find, persistent data survives container rebuilds, and local behavior is close enough to production to catch mistakes early.