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

MetricMeaning
container_cpu_usage_seconds_totalProcessor time a container consumed, as a growing counter
container_memory_usage_bytesMemory a container holds right now
container_network_receive_bytes_totalIncoming network data
container_network_transmit_bytes_totalOutgoing network data
container_last_seenLast 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.