Skip to main content

Capstone — Full Monitoring Dashboard for Campus Library

Time for the real thing. This challenge chains everything you learned into one complete monitoring dashboard. Plan for about one hour.

Goal

By the end, you should have a Grafana dashboard with CPU, memory, request rate, and error panels — with variables, thresholds, and alert notifications.

Step 1 · The Stack​

docker-compose.yml
services:
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- grafana-data:/var/lib/grafana
- ./provisioning:/etc/grafana/provisioning

prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml

node-exporter:
image: prom/node-exporter:latest
ports:
- "9100:9100"
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--path.rootfs=/rootfs'

app:
image: nginx:alpine
ports:
- "8080:80"

volumes:
grafana-data:

Step 2 · Prometheus Config​

prometheus.yml
global:
scrape_interval: 15s

scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']

- job_name: 'node'
static_configs:
- targets: ['node-exporter:9100']

- job_name: 'app'
static_configs:
- targets: ['app:80']

Step 3 · Auto-Provision Data Source​

provisioning/datasources/prometheus.yml
apiVersion: 1

datasources:
- name: Prometheus
type: prometheus
url: http://prometheus:9090
access: proxy
isDefault: true

Step 4 · Start and Build​

Start everything
docker compose up -d

Open http://localhost:3000 → Create a new dashboard with these panels:

Row 1: Overview (Stat panels)

PanelQueryType
CPU Usage100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)Gauge
Memory Usage(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100Gauge
Active Targetscount(up == 1)Stat

Row 2: Traffic (Time series)

PanelQuery
Request Ratesum(rate(http_requests_total[5m])) by (job)
Network Receiverate(node_network_receive_bytes_total[device!="lo"][5m])

Row 3: Saturation (Time series)

PanelQuery
Memory Over Time(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100
Disk Usage(1 - node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100

Step 5 · Add Variables​

  1. Dashboard Settings → Variables → Add variable
  2. Name: job, Query: label_values(up, job)
  3. Add to panel queries: rate(http_requests_total{job="$job"}[5m])

Step 6 · Add Alerts​

  1. Edit the CPU Usage panel → Alert tab → Create alert rule
  2. Condition: CPU > 80% for 5 minutes
  3. Notification: Send to Slack or email

Step 7 · Clean Up​

Stop everything
docker compose down -v
rm -f docker-compose.yml prometheus.yml
rm -rf provisioning/
Remember

This capstone chained: data source → panels → queries → variables → thresholds → alerts. This is exactly how production dashboards are built.