Grafana Docker Monitoring
Containers come and go quickly. A host can run dozens of them, each with its own appetite for processor time and memory. Without monitoring, one greedy container slows its neighbours and nobody knows which one caused the trouble. This project uses cAdvisor, Prometheus, and Grafana to show the resource use of every container.
The Apartment Building Analogy
Think of a Docker host as an apartment building and containers as apartments. The building has one electricity meter, but the landlord wants to know which apartment burns the most power. cAdvisor installs a meter in each apartment. Prometheus records the readings, and Grafana draws the bill as a clear chart.
+--------------- Docker Host ---------------+
| [web] [api] [db] [cache] |
| \ | | / |
| +----+-----+----+ |
| cAdvisor (port 8080) |
+-----------------+-------------------------+
|
Prometheus --> Grafana
Run the Monitoring Stack
One Compose file starts everything. Save it as docker-compose.yml.
services:
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
ports:
- "8080:8080"
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
prometheus:
image: prom/prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
grafana:
image: grafana/grafana-oss
ports:
- "3000:3000"
volumes:
- grafana-storage:/var/lib/grafana
volumes:
grafana-storage:
Create prometheus.yml beside it.
global:
scrape_interval: 15s
scrape_configs:
- job_name: "cadvisor"
static_configs:
- targets: ["cadvisor:8080"]
Run docker compose up -d. Open Grafana at port 3000 and add Prometheus with the address http://prometheus:9090.
Know the Key Metrics
| Metric | Meaning |
|---|---|
| container_cpu_usage_seconds_total | Processor time a container consumed, as a growing counter |
| container_memory_usage_bytes | Memory a container holds right now |
| container_network_receive_bytes_total | Incoming network data |
| container_network_transmit_bytes_total | Outgoing network data |
| container_last_seen | Last time cAdvisor saw the container |
The label name carries the container name. Filter with name!="" to hide system entries without a name.
Build the Panels
CPU per Container
sum by (name) (
rate(container_cpu_usage_seconds_total{name!=""}[$__rate_interval])
) * 100
Draw a time series panel with the unit Percent (0-100). A value of 100 equals one full processor core, so busy multi-threaded containers can exceed 100.
Memory per Container
container_memory_usage_bytes{name!=""}
Use the unit bytes (IEC). A bar gauge sorts the containers and shows the heaviest on top.
Network per Container
sum by (name) (
rate(container_network_receive_bytes_total{name!=""}[$__rate_interval])
)
Running Containers
count(container_last_seen{name!=""})
A stat panel with this query shows how many containers currently exist.
Add a Container Selector
Create a variable named container with the query label_values(container_last_seen, name). Enable multi-value and the All option. Change the queries to use name=~"$container". Viewers pick the containers they care about.
Find a Noisy Neighbour
CPU % by container
web ___________________
api ___/\____/\________
db ____________/\/\/\/\/\/\/\ <-- climbing steadily
cache ___________________
10:00 10:30 11:00
The chart shows the database container rising while its neighbours stay calm. That pattern tells the team where to investigate.
Verify the Data Flow
Check each link in the chain before you build panels. Open http://localhost:8080/metrics to confirm that cAdvisor publishes numbers. Visit the Prometheus Targets page at port 9090 and look for the state UP. Run the query container_last_seen in Grafana Explore and confirm that your containers appear in the list. A failure at any link tells you where to look.
cAdvisor metrics page --> Prometheus targets page --> Grafana Explore
(numbers) (state UP) (series appear)
Compare Usage With Limits
A container with a memory limit can crash when it reaches that limit. Plot usage beside the limit to see the margin.
container_memory_usage_bytes{name!=""}
/ container_spec_memory_limit_bytes{name!=""} * 100
Containers without a limit report 0 for the limit metric, so filter them out with container_spec_memory_limit_bytes > 0. A gauge with thresholds at 75 and 90 shows which containers approach the ceiling.
Alert Ideas
- A container uses more than 90 percent of its memory limit for ten minutes.
- A container that should always run has not appeared for two minutes.
- A container restarts repeatedly within an hour.
Practical Tips
- Set CPU and memory limits on containers, so the numbers have a clear ceiling.
- Limit retention in Prometheus to control disk use.
- Pin image versions in production, and avoid the latest tag.
- Keep the monitoring stack on a private network.
