Self-hosted • Privacy-first • No tracking
Home / Homelab / Complete Grafana Homelab Monitoring Guide: Docker Compose Setup, Alerts & Hardening (2026)
Homelab #homelab#docker-compose#monitoring#grafana#prometheus ⏱ 11 min • 👁 1 • Aug 30, 2026

Complete Grafana Homelab Monitoring Guide: Docker Compose Setup, Alerts & Hardening (2026)

Step-by-step guide to deploy Grafana v13.2.0 in your homelab with Docker Compose, configure Prometheus, add alerting, and secure it with reverse proxy and backups.

AdSense — Top (970x90) • Responsive
Complete Grafana Homelab Monitoring Guide: Docker Compose Setup, Alerts & Hardening (2026)

Introduction

Monitoring your homelab is not a luxury—it's a necessity. As your infrastructure grows from a single Raspberry Pi to a rack of servers, you need visibility into CPU, memory, disk, network, and application health. Grafana is the de facto standard for visualization, and when paired with Prometheus, it becomes an unbeatable duo. In this guide, you'll learn how to deploy Grafana v13.2.0 (the latest official release as of August 2026) using Docker Compose, connect it to Prometheus, set up alerting, and secure it with a reverse proxy and TLS.

This guide is written for homelab enthusiasts who are comfortable with the command line and Docker. We'll cover the entire lifecycle: from prerequisites to advanced configuration. You'll get copy-paste-ready Docker Compose files, environment variable templates, and troubleshooting tables that address common pitfalls. By the end, you'll have a production-grade monitoring stack that respects your privacy and runs entirely on your own hardware.

We will not use any placeholder versions—Grafana is pinned to v13.2.0 via an environment variable, and we'll show you how to manage that variable in a .env file. We'll also emphasize security best practices: secrets stored in .env, optional hardening with read_only and cap_drop, and backup strategies for your dashboards.

Let's get started. No fluff, no filler—just actionable steps.

Prerequisites / Requirements

Before diving into the installation, ensure your homelab server meets the following minimum specifications. These are typical values based on community deployments; actual usage may vary.

Component Minimum Recommended Notes
CPU 1 core 2 cores Grafana is not CPU-hungry, but Prometheus and other exporters add load.
RAM 512 MB 1 GB Grafana alone uses ~200 MB; Prometheus uses ~300 MB. Add 256 MB per exporter.
Storage 5 GB 20 GB Includes Grafana config, Prometheus TSDB, and backups. SSDs preferred for Prometheus.
Docker v20.10+ Latest Docker Compose v2 is required.
OS Linux (Debian/Ubuntu, Fedora) Any Linux Windows/macOS are possible but not covered here.
Network 100 Mbps 1 Gbps Needed for scraping multiple targets.

Software prerequisites:

  • Docker Engine and Docker Compose plugin. Verify with docker --version and docker compose version.
  • A text editor (vim, nano, or VS Code).
  • Basic knowledge of YAML and Linux file permissions.
  • A domain name (optional but recommended for reverse proxy and SSL).

Step-by-Step Installation

Step 1: Create Directory Structure and .env File

We'll keep all files in ~/grafana-homelab. Create the directory and the .env file that will hold all secrets and version variables.

mkdir -p ~/grafana-homelab && cd ~/grafana-homelab && touch .env

Now edit .env with your favorite editor. Add the following content:

# Grafana version - pin to a specific release for reproducibility
GRAFANA_VERSION=13.2.0

# Prometheus version - use latest, but check official releases before pinning
PROMETHEUS_VERSION=latest

# Admin credentials for Grafana (change these!)
GRAFANA_ADMIN_USER=admin
GRAFANA_ADMIN_PASSWORD=ChangeMe!StrongPass

# Database credentials if using PostgreSQL (optional, but recommended for production)
POSTGRES_DB=grafana
POSTGRES_USER=grafana
POSTGRES_PASSWORD=ChangeMe!DBPass

# Timezone - adjust to your location
TZ=UTC

WARNING: Never commit this .env file to Git. Add it to .gitignore if you use version control. The .env file contains secrets that must stay private.

Step 2: Create docker-compose.yml

Create the main Compose file:

cd ~/grafana-homelab && touch docker-compose.yml

Paste the following complete configuration. This includes Grafana, Prometheus, and a Node Exporter for system metrics.

version: '3.8'

services:
  grafana:
    image: grafana/grafana:${GRAFANA_VERSION:-latest}
    container_name: grafana
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_USER=${GRAFANA_ADMIN_USER:-admin}
      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD:-admin}
      - GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource
      - TZ=${TZ:-UTC}
    volumes:
      - grafana_data:/var/lib/grafana
      - ./grafana/provisioning:/etc/grafana/provisioning:ro
    depends_on:
      - prometheus
    networks:
      - monitoring

  prometheus:
    image: prom/prometheus:${PROMETHEUS_VERSION:-latest}
    container_name: prometheus
    restart: unless-stopped
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/usr/share/prometheus/console_libraries'
      - '--web.console.templates=/usr/share/prometheus/consoles'
    networks:
      - monitoring

  node-exporter:
    image: prom/node-exporter:latest
    container_name: node-exporter
    restart: unless-stopped
    ports:
      - "9100:9100"
    networks:
      - monitoring

volumes:
  grafana_data:
  prometheus_data:

networks:
  monitoring:
    driver: bridge

This file uses variables from .env. Note that GRAFANA_VERSION is set to 13.2.0 in .env, so the image will be exactly that version. For Prometheus, we use latest but we strongly recommend checking the official GitHub releases page before pinning a version—the version above may be outdated by now.

Step 3: Configure Prometheus Scrape Targets

Create the Prometheus configuration file:

mkdir -p ~/grafana-homelab/prometheus && cd ~/grafana-homelab/prometheus && touch prometheus.yml

Edit prometheus.yml with the following minimal configuration:

global:
  scrape_interval: 15s
  evaluation_interval: 15s

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

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

This tells Prometheus to scrape itself and the Node Exporter. You can add more targets later (e.g., other hosts, Docker daemon, etc.).

Step 4: Provision Grafana Data Source and Dashboards

Grafana provisioning allows you to pre-configure data sources and dashboards. Create the provisioning directory:

mkdir -p ~/grafana-homelab/grafana/provisioning/datasources && cd ~/grafana-homelab/grafana/provisioning/datasources && touch datasource.yml

Edit datasource.yml:

apiVersion: 1

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

This automatically adds Prometheus as a data source at startup. For dashboards, you can either create them manually or use community dashboards. To keep it simple, we'll skip automatic dashboard provisioning in this guide, but you can add a dashboards folder with JSON files later.

Step 5: Start the Stack

Now start the containers:

cd ~/grafana-homelab && docker compose up -d

Wait a few minutes for images to pull and containers to start. Check the status:

docker compose ps

You should see all three services running.

Step 6: Access Grafana and Verify

Open your browser and navigate to http://your-server-ip:3000. You'll see the Grafana login page. Use the credentials from your .env file (default: admin / ChangeMe!StrongPass).

After login, go to Configuration > Data Sources and confirm that Prometheus is listed and accessible (click "Save & test" to verify).

Step 7: Import a Dashboard for Node Exporter

To visualize system metrics, import a pre-built dashboard. In Grafana, go to Dashboards > Import, enter dashboard ID 1860 (Node Exporter Full), and click Load. Select the Prometheus data source and click Import. You should see CPU, memory, disk, and network graphs.

Step 8: Set Up Alerting (Optional but Recommended)

Create a simple alert to notify you when CPU usage is high. In Grafana, go to Alerting > Alert rules, click New alert rule, and configure a condition like avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) < 0.2. Set a notification policy (e.g., email or webhook) in Contact points. This step requires a notification channel; you can add one in Alerting > Contact points.

Step 9: Configure Reverse Proxy and SSL (Advanced)

For secure remote access, set up a reverse proxy like Nginx or Traefik. Here's an example using Nginx with Let's Encrypt certificates:

# Install nginx and certbot (on Debian/Ubuntu)
sudo apt update && sudo apt install nginx certbot python3-certbot-nginx -y

Create an Nginx config for grafana.example.com:

server {
    listen 80;
    server_name grafana.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name grafana.example.com;

    ssl_certificate /etc/letsencrypt/live/grafana.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/grafana.example.com/privkey.pem;

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Then obtain the certificate:

sudo certbot --nginx -d grafana.example.com

This will automatically update the Nginx config and enable HTTPS.

Step 10: Backup and Restore

Back up Grafana dashboards and configuration. The easiest way is to use the Grafana API or export dashboards as JSON. For a full backup, stop the stack and copy the volumes:

cd ~/grafana-homelab && docker compose down && tar -czf backup-$(date +%Y%m%d).tar.gz grafana_data prometheus_data .env && docker compose up -d

Restore by extracting the tar file and restarting.

Step 11: Optional Hardening

The following security measures are optional and may break functionality if not adapted to your environment. Use them with caution.

  • read_only: Set read_only: true for the Grafana container to make its filesystem read-only, except for the volumes. This prevents writes to the container layer.
  • cap_drop: Drop all Linux capabilities and add only the ones needed. For Grafana, you might need CHOWN, SETGID, SETUID, and DAC_OVERRIDE. Example:
security_opt:
  - no-new-privileges:true
cap_drop:
  - ALL
cap_add:
  - CHOWN
  - SETGID
  - SETUID
  - DAC_OVERRIDE
  • User ID: Run containers as a non-root user. Check the image documentation for the default user (for Grafana, it's 472:472). Verify your host's user ID with id -u and id -g and adjust the user: directive accordingly.

These settings are not one-size-fits-all; test them in a staging environment first.

Step 12: Update and Maintenance

To update Grafana to a newer version, change GRAFANA_VERSION in .env and run:

cd ~/grafana-homelab && docker compose pull && docker compose up -d

Always check the official Grafana changelog for breaking changes before upgrading.

Advanced Configuration / Optimization

Reverse Proxy with Traefik (Alternative)

If you prefer Traefik, add labels to the Grafana service and configure a dynamic config. This is beyond the scope of this guide, but the official Traefik docs are excellent.

Multi-Host Monitoring

To monitor multiple hosts, run a Node Exporter on each host and add them to prometheus.yml under the node job. Use DNS or static IPs.

Alertmanager Integration

For more advanced alerting, integrate Alertmanager with Prometheus. Add an alertmanager service to your Compose file and configure routing rules. This allows you to send alerts to Slack, email, or webhooks.

Data Retention and Sizing

Prometheus's TSDB can grow quickly. Set retention flags in the Prometheus command: --storage.tsdb.retention.time=30d. For Grafana, the SQLite database (or PostgreSQL) stores dashboards and users—back it up regularly.

Troubleshooting Common Issues

Error Cause Solution
Grafana: login failed Wrong credentials in .env Check GF_SECURITY_ADMIN_USER and GF_SECURITY_ADMIN_PASSWORD in .env and restart Grafana.
Prometheus: connection refused Prometheus not ready or wrong URL Wait for Prometheus to start, then check the data source URL (should be http://prometheus:9090).
Container exits with code 1 Permissions on volumes Run docker compose logs to see the exact error. For Grafana, ensure the volume grafana_data is writable by the container user.
Dashboard not showing data Scrape targets not configured Verify prometheus.yml targets and that exporters are running. Use Prometheus UI at :9090/targets to check.
SSL certificate error Certbot not configured correctly Re-run sudo certbot --nginx and ensure the domain resolves to your server.
High memory usage Too many scrape targets Increase scrape interval or reduce number of exporters. Use --storage.tsdb.retention.time to limit data stored.

Conclusion

You now have a fully functional Grafana monitoring stack running in your homelab. You've learned how to deploy Grafana v13.2.0 with Docker Compose, configure Prometheus, set up alerting, and secure the setup with a reverse proxy and backups. The optional hardening steps will help you lock down the containers if you need extra security. Keep your stack updated by tracking official releases, and remember to always check the official documentation before changing versions or adding new exporters.

FAQ

1. Can I use Grafana without Prometheus?

Yes, Grafana supports many data sources, including InfluxDB, PostgreSQL, and Loki. However, Prometheus is the most common for metrics due to its powerful query language and native integration. If you only need to visualize existing data, you can connect any supported data source.

2. How do I add a new exporter for a service like MySQL?

Add a new container to your docker-compose.yml with the exporter image (e.g., prom/mysqld-exporter), configure its environment variables, and add a job in prometheus.yml pointing to its address. Then restart the stack and import a dashboard for that exporter.

3. What is the default Grafana admin password?

There is no default password—you must set it via the GF_SECURITY_ADMIN_PASSWORD environment variable or through the web UI on first login. In our setup, we use the value from .env, which is ChangeMe!StrongPass by default. Always change it after deployment.

4. How often should I back up Grafana?

It depends on how frequently you create dashboards or change settings. For a homelab, a weekly backup is sufficient. Use the backup command provided in Step 10, or automate it with cron. Store backups on a separate disk or remote location.

5. Can I run Grafana on a Raspberry Pi?

Yes, Grafana supports ARM64. Use the official image grafana/grafana:latest which includes multi-arch support. Ensure your Pi has at least 1 GB RAM for smooth operation. Note that Prometheus and exporters also have ARM builds.


Check the official Grafana release notes and Prometheus documentation before pinning versions—the version above may be outdated by now.

AdSense — In-article (responsive)

Related Guides