Docker from Basics to Production · Operate Containers
Logs, Log Rotation and Resource Usage
Keep container logs from filling disks, ship them to a central store, and watch CPU and memory per container.
What you'll build
A chatty container with log rotation configured, a look at how Docker stores its logs, and a snapshot of per-container CPU and memory usage with docker stats.
The idea
- Docker's default json-file log driver keeps every line forever unless you configure rotation:
--log-opt max-size=10m --log-opt max-file=3, or set it once for all containers in/etc/docker/daemon.json. The local driver rotates and compresses by default. - In production, ship logs to a central system (Loki, Elasticsearch, a cloud logging service) via a driver or an agent reading container log files. Log structured JSON to stdout.
docker statsshows live CPU, memory (against the limit), network and block I/O per container; for history, export metrics (cAdvisor, the OpenTelemetry collector).
The code
trap 'docker rm -f rc-chatty > /dev/null 2>&1' EXIT
docker run -d --name rc-chatty --memory 64m \
--log-driver json-file --log-opt max-size=1k --log-opt max-file=2 \
alpine:3.24 sh -c 'i=0; while true; do i=$((i+1)); echo "{\"level\":\"info\",\"msg\":\"request handled\",\"n\":$i}"; [ $i -ge 500 ] && sleep 3600; done' > /dev/null
sleep 2
echo "log config: $(docker inspect rc-chatty --format '{{.HostConfig.LogConfig.Type}} {{json .HostConfig.LogConfig.Config}}')"
echo "lines still available: $(docker logs rc-chatty 2>&1 | wc -l) of 500 written (older lines rotated away)"
echo "newest line: $(docker logs --tail 1 rc-chatty)"
docker stats --no-stream --format '{{.Name}}: mem limit {{.MemUsage}}' rc-chatty | sed -E 's/: mem limit .* \/ /: memory limit /'
Output
log config: json-file {"max-file":"2","max-size":"1k"}
lines still available: 12 of 500 written (older lines rotated away)
newest line: {"level":"info","msg":"request handled","n":500}
rc-chatty: memory limit 64MiBRun this on your computer — see “Get Started” for setup.
Common mistakes
- No log rotation: a debug-level container fills the host disk and takes everything down.
- Writing logs to files inside the container, where nobody collects them.
- Unstructured text logs that can't be searched by field.
- Watching
docker statsby hand instead of collecting metrics with history and alerts.
Key points
- Configure log rotation (per container or in daemon.json), or use the local driver.
- Log structured JSON to stdout and ship it centrally.
- Use docker stats for a quick look and a metrics pipeline for history and alerts.
Further reading: Configure logging drivers · docker stats
Practice questions
What happens to container logs with Docker's default json-file driver and no options?
Answer
They grow without limit on the host disk; configure max-size and max-file (or use the local driver) to rotate them.
Where should a containerized application write its logs?
Answer
To stdout and stderr, ideally as structured JSON, so the runtime and a log agent can collect and ship them centrally.
What does docker stats show, and what's its limitation?
Answer
Live CPU, memory usage against the limit, network and block I/O per container; it has no history or alerting, so production needs a metrics pipeline.
Open in the app to mark lessons complete, take notes and track your progress.