Skip to content

Home Lab: Self-Hosted Monitoring Dashboard on Raspberry Pi 5

A self-hosted home lab is only as good as its monitoring system. When running multiple services like Nextcloud, Pi-hole, Home Assistant, or media servers, you need to know immediately when a service goes down or when your hardware is under stress.

This guide walks you through building a unified monitoring dashboard on a Raspberry Pi 5 using a modern stack: - Netdata: For real-time, low-overhead system and hardware metrics. - Uptime Kuma: For uptime monitoring of your services with a beautiful status page and instant notifications. - Prometheus & Grafana: For long-term historical metrics visualization.

We will deploy the entire stack containerized using Docker Compose and configure it for optimal performance on Raspberry Pi.


Architecture Overview

graph TD A["Raspberry Pi 5 (Host)"] -->|Metrics Export| B["Netdata (Container)"] A -->|System Data| C["Prometheus (Container)"] B -->|Prometheus Endpoint| C C -->|Data Source| D["Grafana Dashboard (Container)"] E["External Services / Local Ports"] -->|Ping/HTTP Checks| F["Uptime Kuma (Container)"] F -->|Alerts| G["Discord / Telegram / Gotify"] style B fill:#4cc9f0,stroke:#4361ee,color:#000 style C fill:#4cc9f0,stroke:#4361ee,color:#000 style D fill:#f72585,stroke:#b5179e,color:#fff style F fill:#7209b7,stroke:#560bad,color:#fff

Step 1: Directory Structure and Prerequisites

First, ensure you have Docker and Docker Compose installed on your Raspberry Pi OS Bookworm. If you don't, run:

1
2
3
curl -sSL https://get.docker.com | sh
sudo usermod -aG docker $USER
# Log out and back in to apply group changes

Create a dedicated directory structure for your monitoring stack configuration and data storage:

mkdir -p ~/homelab-monitoring/{prometheus,grafana/provisioning/datasources}
cd ~/homelab-monitoring

Step 2: Configure Prometheus

Prometheus needs a configuration file defining how often to scrape metrics and from which targets (in this case, Netdata).

Create the configuration file:

nano prometheus/prometheus.yml

Add the following Prometheus configuration:

global:
  scrape_interval: 15s
  evaluation_interval: 15s

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

  - job_name: 'netdata'
    metrics_path: '/api/v1/allmetrics'
    params:
      format: ['prometheus']
    static_configs:
      - targets: ['netdata:19999']

Step 3: Create the Docker Compose Stack

This single Docker Compose file will launch Netdata (with host metrics access), Prometheus, Grafana, and Uptime Kuma.

Create the file:

nano docker-compose.yml

Add the following configuration:

version: '3.8'

services:
  # Netdata: Real-time host metrics collector
  netdata:
    image: netdata/netdata:latest
    container_name: netdata
    hostname: raspberrypi-netdata
    ports:
      - "19999:19999"
    restart: unless-stopped
    cap_add:
      - SYS_PTRACE
      - SYS_ADMIN
    security_opt:
      - apparmor:unconfined
    volumes:
      - netdataconfig:/etc/netdata
      - netdatalib:/var/lib/netdata
      - netdatacache:/var/cache/netdata
      - /etc/passwd:/host/etc/passwd:ro
      - /etc/group:/host/etc/group:ro
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /etc/os-release:/host/etc/os-release:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      - NETDATA_EXTRA_DEB_PACKAGES=lm-sensors

  # Prometheus: Historical metrics storage
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--storage.tsdb.retention.time=15d'
    ports:
      - "9090:9090"
    restart: unless-stopped
    depends_on:
      - netdata

  # Grafana: Rich visualization panels
  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    ports:
      - "3000:3000"
    volumes:
      - grafana_data:/var/lib/grafana
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin # Change this on first login!
    restart: unless-stopped
    depends_on:
      - prometheus

  # Uptime Kuma: Service Uptime & Beautiful Status Page
  uptime-kuma:
    image: louislam/uptime-kuma:1
    container_name: uptime-kuma
    ports:
      - "3001:3001"
    volumes:
      - uptime-kuma_data:/app/data
    restart: unless-stopped

volumes:
  netdataconfig:
  netdatalib:
  netdatacache:
  prometheus_data:
  grafana_data:
  uptime-kuma_data:

Step 4: Deploying and Optimizing for Raspberry Pi

Start the stack:

docker compose up -d

Raspberry Pi 5 Optimization Notes:

  1. Disk Write Wear Reduction: Prometheus writes historical metric chunks to the disk. By setting --storage.tsdb.retention.time=15d, we limit the size of database operations to avoid wearing out SD cards. If you run this long-term, booting from an NVMe SSD is highly recommended.
  2. Docker Socket Mapping: Netdata is mapped to the host's /var/run/docker.sock. This allows Netdata to automatically monitor CPU, memory, and network utilization for every other container running on your Raspberry Pi.
  3. lm-sensors: We passed NETDATA_EXTRA_DEB_PACKAGES=lm-sensors to Netdata, allowing it to collect Raspberry Pi 5 board temperatures natively.

Step 5: Dashboard Configuration

1. Real-Time Resource Auditing (Netdata)

Open your browser and navigate to http://<your-pi-ip>:19999. Netdata provides an incredibly detailed, zero-configuration dashboard showcasing: - Real-time CPU core frequencies and temperatures. - Network throughput across physical interfaces and Docker virtual bridges. - Raw Disk read/write IOPS and swap usage.

2. Service Monitoring & Status Pages (Uptime Kuma)

Open your browser and navigate to http://<your-pi-ip>:3001. 1. Create your admin account. 2. Click Add New Monitor. 3. Choose monitor types: - HTTP(s): Verify Web UI services (e.g. http://localhost:80 for your web server). - Ping: Monitor router or other local network device latency. - TCP Port: Verify if dockerized apps are alive (e.g., port 8123 for Home Assistant). 4. Go to Setup Notification and link it to Telegram, Discord Webhooks, Pushover, or email to receive instant alerts if services crash. 5. Create a public Status Page to visually list the uptime statistics of all your homelab apps.

3. Historical Visualizations (Grafana)

Open your browser and navigate to http://<your-pi-ip>:3000. 1. Log in with user admin and password admin (update the password immediately). 2. Go to Connections -> Data Sources -> Add data source -> Select Prometheus. 3. Set the Connection URL to: http://prometheus:9090 and click Save & Test. 4. To import a pre-configured system dashboard, hover over the + icon -> Import. 5. Input Dashboard ID 11159 (Netdata Linux System Overview) or 1860 (Node Exporter Full) to pull a beautiful pre-configured dashboard immediately from the Grafana community registry.


Troubleshooting & Maintenance

Check Container Statuses

docker compose ps

View Logs for specific service (e.g. Prometheus)

docker compose logs -f prometheus

Upgrading the Stack

To keep your tools secure and up-to-date, pull new images and restart the containers periodically:

docker compose pull
docker compose up -d --remove-orphans

By leveraging this unified monitoring system, you now have complete observability over your Raspberry Pi 5 homelab, securing maximum uptime for all your self-hosted apps.