Set Up Home Monitoring System

Set Up Home Monitoring System

If you're running a homelab with multiple services, VMs, or physical machines, you need visibility into what's happening at 3 AM when something inevitably breaks. I built a monitoring stack that catches issues before users notice them—and it runs entirely on my own hardware. This guide walks you through setting up Uptime Kuma for status pages, Prometheus for metrics collection, and Grafana for beautiful dashboards.

Why Self-Hosted Monitoring Matters

I tried relying on third-party monitoring services for years. Uptime Robot tells you when your service is down, but it doesn't tell you why. And if your monitoring service goes down, you're blind. Self-hosting your monitoring stack gives you complete control, historical data retention, and the ability to monitor internal infrastructure that never touches the internet.

In my setup, I monitor Docker containers, Proxmox VMs, disk usage, memory consumption, network traffic, and application-specific metrics. When a service degrades, I get a Slack notification before customers do. That's the peace of mind worth the investment.

Tip: Start with Uptime Kuma if you're new to monitoring. It's lightweight, requires minimal configuration, and provides immediate value. Add Prometheus and Grafana later when you need deeper insights.

Hardware Requirements

You don't need much. I run my monitoring stack on a single 2-core, 2GB RAM VPS—but if you're monitoring a large homelab, dedicate a small machine locally. Here's what I recommend:

If you don't have spare hardware at home, a budget VPS from RackNerd (affiliate link) costs $10–15/month and handles monitoring beautifully. Their KVM and Hybrid Dedicated offerings are solid for homelabs that need external monitoring redundancy.

Install Uptime Kuma with Docker Compose

Uptime Kuma is the easiest entry point. It monitors HTTP/HTTPS endpoints, TCP ports, ping, DNS records, and more. Alerts go to Slack, Discord, Telegram, or email. Deploy it in seconds with Docker Compose.

mkdir -p ~/monitoring && cd ~/monitoring
cat > docker-compose.yml << 'EOF'
version: '3.8'

services:
  uptime-kuma:
    image: louislam/uptime-kuma:latest
    container_name: uptime-kuma
    restart: always
    ports:
      - "3001:3001"
    volumes:
      - uptime-kuma-data:/app/data
    environment:
      - PUID=1000
      - PGID=1000

volumes:
  uptime-kuma-data:
    driver: local
EOF

docker-compose up -d

Wait 10 seconds for the container to start, then visit http://localhost:3001 in your browser. You'll see the setup wizard. Create a username, set a strong password, and start adding monitors.

I typically monitor:

Each monitor can be configured independently. I set Nextcloud to check every 60 seconds, but less critical services can use 5-minute intervals to reduce overhead.

Add Prometheus for Deep Metrics

Uptime Kuma tells you if something is up or down. Prometheus answers the harder questions: Why is my database slow? How much disk space is left? Is CPU throttling? Prometheus scrapes metrics from exporters and stores them for analysis.

Extend your Docker Compose setup:

cat >> docker-compose.yml << 'EOF'

  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    restart: always
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus-data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--storage.tsdb.retention.time=30d'

  node-exporter:
    image: prom/node-exporter:latest
    container_name: node-exporter
    restart: always
    ports:
      - "9100:9100"
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command:
      - '--path.procfs=/host/proc'
      - '--path.sysfs=/host/sys'
      - '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'

volumes:
  prometheus-data:
    driver: local
EOF

Create the Prometheus configuration file:

cat > prometheus.yml << 'EOF'
global:
  scrape_interval: 15s
  evaluation_interval: 15s

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

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

  - job_name: 'docker'
    static_configs:
      - targets: ['unix:///var/run/docker.sock']
EOF

Restart the stack: docker-compose up -d. Visit http://localhost:9090 to access Prometheus. You can query metrics like node_memory_MemAvailable_bytes or node_filesystem_avail_bytes to see what data is being collected.

Watch out: Prometheus stores one year of data by default on disk. 15-second scrape intervals on 50+ metrics can eat 50GB+ per month. Adjust --storage.tsdb.retention.time based on your storage capacity. I use 30 days on constrained systems.

Visualize with Grafana

Raw Prometheus graphs are functional but ugly. Grafana transforms metrics into dashboards that actually make sense. Add it to your compose file:

cat >> docker-compose.yml << 'EOF'

  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    restart: always
    ports:
      - "3000:3000"
    volumes:
      - grafana-data:/var/lib/grafana
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
      - GF_USERS_ALLOW_SIGN_UP=false

volumes:
  grafana-data:
    driver: local
EOF

docker-compose up -d

Visit http://localhost:3000 and log in with admin / admin (change this immediately). Add a Prometheus data source:

Now import a community dashboard. I like the Node Exporter dashboard (ID: 1860). Click the + icon, select Import, enter 1860, and let Grafana pull it in automatically. Within seconds, you have CPU, memory, disk, and network graphs for your entire system.

Configure Alerts and Notifications

Monitoring is useless if you don't know when things break. I send alerts to Slack, but email, Discord, and Telegram work too.

In Uptime Kuma, add a Slack webhook:

  1. In your Slack workspace, create an incoming webhook in the app settings
  2. Copy the webhook URL
  3. In Uptime Kuma, go to SettingsNotificationsAdd Notification
  4. Choose Slack, paste the webhook URL
  5. Test it (you'll see a message in Slack immediately)
  6. Edit your monitors and enable Slack notifications

For Grafana alerts, the process is similar. Create an alert notification channel and attach it to alert rules tied to metrics. I set up thresholds like "disk usage > 80%" or "CPU load > 4 for 5 minutes."

Secure Your Monitoring Stack

Your monitoring system sees everything in your network. Protect it:

If your monitoring stack is on a local machine, this is less critical. But if you're using an external VPS (like those available from RackNerd), treat it as a production system.

Monitor Everything: Exporters and Integrations

Node Exporter monitors the OS, but you'll want application-specific metrics too. Popular exporters include:

Each exporter runs as a separate container and exposes metrics on a unique port. Add them to Prometheus's scrape config, and you get instant visibility into every layer of your stack.

Maintenance and Growth

Once your stack is running, maintenance is minimal. Docker containers auto-restart on failure. Prometheus and Grafana handle updates gracefully. The biggest operational task is managing disk space—Prometheus metrics grow predictably, so monitor /prometheus directory size.

As you add more services, you'll naturally add more monitors and exporters. I started with 5 monitors and now track 40+ metrics streams. The architecture scales beautifully because Prometheus is designed to handle it.

Next Steps

You now have the foundation for enterprise-grade monitoring on your own hardware. The natural next steps are:

  1. Set up alerting: Configure alert rules in Grafana to catch problems automatically
  2. Secure remote access: Use Tailscale or a reverse proxy to access your dashboards safely from anywhere
  3. Export metrics: Query Prometheus via API to build custom reports or integrations
  4. Plan retention: Decide how long you need to keep historical data and adjust Prometheus retention accordingly

If you're running this setup on a homelab server and need external redundancy, a small VPS can host a second monitoring instance that watches your primary systems. That way, if your home internet goes down, you still know about it.

```