Docker Monitoring: The Complete 2026 Guide
Monitor Docker containers properly — docker stats limits, cAdvisor + Prometheus setup, the container metrics that matter, log collection, and restart-loop alerting.
Short answer: docker stats is a flashlight, not a monitoring system — it shows live numbers with no history, no alerts, no multi-host view. Real Docker monitoring means collecting container metrics (CPU throttling, memory vs limit, restart counts) via cAdvisor into Prometheus, collecting logs via a driver or agent, and alerting on the container-specific failure modes: OOM kills, restart loops, and CPU throttling. This guide gives you the commands, the compose file, and the alert rules for standalone Docker hosts; if you run Kubernetes, use the Kubernetes monitoring guide instead — same metrics, different plumbing.
Step 0: Know your built-ins (and their limits)
docker stats # live CPU/MEM/NET/IO per container — no history
docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
docker inspect -f '{{.State.OOMKilled}} {{.State.Restarting}} {{.RestartCount}}' <container>
docker events --filter event=die # the death stream — useful for debugging, not alerting
docker logs --tail 100 -f <container>
These answer "what is happening right now on this host." The moment you need "what happened last night" or "page me when a container restarts," you need collection.
The metrics that matter (and their container-specific traps)
| Metric | Source | The trap it catches |
|---|---|---|
container_cpu_cfs_throttled_seconds_total |
cAdvisor | CPU limit too tight — app slow while host CPU is idle |
container_memory_working_set_bytes vs limit |
cAdvisor | OOM kill incoming |
container_last_seen / OOMKilled flag |
runtime events | Silent container death |
| Restart count delta | engine/cAdvisor | Crash loops (deploy regression, bad config) |
container_fs_usage_bytes |
cAdvisor | Container filling its writable layer |
container_network_receive/transmit_errors_total |
cAdvisor | NIC/overlay issues |
Image age / :latest drift |
engine API | Unpatched, unreproducible deploys |
The single most misunderstood container metric: CPU throttling. A container pegged at its CPU limit shows low host utilization while its p99 latency burns. Always chart throttled seconds next to usage.
Related guideDocker Integration→
The reference stack: cAdvisor + Prometheus (+ Grafana)
# docker-compose.yml — monitoring sidecar stack
services:
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
ports: ["8080:8080"]
prometheus:
image: prom/prometheus:latest
volumes: [ "./prometheus.yml:/etc/prometheus/prometheus.yml" ]
ports: ["9090:9090"]
grafana:
image: grafana/grafana:latest
ports: ["3000:3000"]
# prometheus.yml
scrape_configs:
- job_name: cadvisor
static_configs: [ { targets: ['cadvisor:8080'] } ]
- job_name: node
static_configs: [ { targets: ['node-exporter:9100'] } ] # host-level context
Alert rules for standalone Docker hosts
# Container OOM-killed in the last 15 minutes
increase(container_oom_events_total[15m]) > 0
# Restart loop: more than 3 restarts in 30 minutes
increase(container_start_time_seconds[30m]) > 3 # or engine restart counts via events exporter
# CPU throttling above 10% of periods
rate(container_cpu_cfs_throttled_periods_total[5m])
/ rate(container_cpu_cfs_periods_total[5m]) > 0.10
# Memory above 85% of limit
container_memory_working_set_bytes / container_spec_memory_limit_bytes > 0.85
Don't forget the logs
Metrics tell you that a container died; logs tell you why. Minimal viable setup: the json-file driver with rotation (always set rotation — unrotated container logs are a classic disk-filler), and a collector (Fluent Bit, Promtail, or DataKit) tailing /var/lib/docker/containers:
Related guideKubernetes Monitoring: The Complete 2026 Guide→
// /etc/docker/daemon.json
{ "log-driver": "json-file",
"log-opts": { "max-size": "10m", "max-file": "3" } }
For structured apps, write JSON logs to stdout and let the collector parse — the twelve-factor rule that makes every downstream tool (Grafana Loki, Elasticsearch, Guance) work better.
When to skip the DIY stack
The cAdvisor + Prometheus + Grafana stack is the right answer for one to five hosts you already SSH into. It stops scaling when: hosts multiply beyond manual target lists, you need container logs and host metrics and app traces in one investigation view, or retention and uptime of the monitoring system itself become someone's unpaid job. At that point an agent-based platform earns its keep — Guance's DataKit, for example, collects container metrics, Docker events, and logs with one input config and prices on usage, and Datadog/New Relic/Grafana Cloud all have Docker integrations of their own. The metrics and alert rules above port to any of them — the collection mechanics are the only thing that changes.
FAQ
Q: How do I monitor Docker containers?
Built-in: docker stats, docker events, docker logs, and docker inspect state fields cover live debugging. For real monitoring: run cAdvisor to expose per-container metrics, scrape with Prometheus, visualize in Grafana, and alert on OOM kills, restart loops, CPU throttling, and memory-vs-limit. Add a log collector for /var/lib/docker/containers.
Q: What is the difference between docker stats and cAdvisor?
docker stats streams live point-in-time numbers to your terminal — no storage, no history, no alerts, one host only. cAdvisor is a daemon that continuously collects the same cgroup metrics (plus more) and exposes them for Prometheus scraping, giving you history, queries, dashboards, and alerting across all containers on the host.
Q: How do I know if a container was OOM-killed?
docker inspect -f '{{.State.OOMKilled}}' <container> shows the last state; docker events --filter event=oom streams occurrences; in metrics, alert on increase(container_oom_events_total[15m]) > 0. The host's dmesg also logs cgroup OOM kills. If your container "randomly restarts," check OOM first — it's the most common silent killer.
Q: What is CPU throttling in Docker?
When a container exceeds its --cpus/quota, the kernel freezes its runnable periods — measured as container_cpu_cfs_throttled_seconds_total. The host can be 90% idle while the container's latency explodes. Fix by raising the limit or optimizing the workload; monitor the throttled/total periods ratio and alert above 10%.
Q: Should I use Docker monitoring tools or Kubernetes monitoring?
Match the orchestrator you run. Standalone Docker hosts / Docker Compose → cAdvisor + Prometheus stack in this guide. Kubernetes → the K8s stack (metrics-server, kube-state-metrics, cAdvisor-via-kubelet) in our Kubernetes guide. Swarm is legacy — plan the migration rather than investing in Swarm-specific tooling.
Sources: Docker documentation (stats, logging drivers, daemon.json), cAdvisor and Prometheus project docs. Verified 2026-08-07. Published by Guance — the Docker integration collects metrics, events, and logs via DataKit.
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan