# How to Set Up Monitoring with Grafana and Prometheus: A Complete Self-Hosting Guide

> Learn to set up monitoring with Grafana and Prometheus. Deploy using Docker, configure Prometheus scraping, and connect Grafana for powerful data visualization and alerts.

- Repository: [Michael Royal/Self-Hosting-Guide](https://github.com/mikeroyal/Self-Hosting-Guide)
- Tags: how-to-guide
- Published: 2026-06-17

---

**To set up monitoring with Grafana and Prometheus, deploy both services using Docker Compose, configure Prometheus to scrape metrics from HTTP `/metrics` endpoints, and connect Grafana to Prometheus as a data source to visualize time-series data and configure alerts.**

The mikeroyal/Self-Hosting-Guide repository, specifically in its [`README.md`](https://github.com/mikeroyal/Self-Hosting-Guide/blob/main/README.md) monitoring section, provides a production-ready approach to building a scalable monitoring stack using these open-source tools. According to the guide, Prometheus operates as a time-series database that **pulls** metric data from any HTTP-exposed endpoint, while Grafana connects to Prometheus via the PromQL API to provide visualization and alerting capabilities. This article implements the exact configuration patterns found in the repository to deploy a fully functional monitoring solution.

## Architecture Overview

The monitoring stack consists of two core components working together. **Prometheus** runs a time-series database (TSDB) that scrapes metrics from configured targets using the pull model. It collects raw samples, performs aggregation, and exposes a flexible query language called **PromQL** via HTTP API.

**Grafana** functions as the visualization layer that queries Prometheus to render charts, dashboards, and alerts. It reads metrics through the Prometheus HTTP API and can combine data from multiple sources, including Loki logs and VictoriaMetrics.

Typical data flow follows this pattern: exporters (such as node_exporter) expose metrics at `/metrics` endpoints → Prometheus scrapes and stores the data → Grafana queries Prometheus to display dashboards.

## Step-by-Step Setup Guide

### Step 1: Install Prometheus via Docker

Launch Prometheus using the official Docker image. The container requires a mounted configuration file and specific command-line flags to define the configuration path and storage location.

Create a [`docker-compose.yml`](https://github.com/mikeroyal/Self-Hosting-Guide/blob/main/docker-compose.yml) file in your project directory:

```yaml
version: "3.8"

services:
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
    command:
      - "--config.file=/etc/prometheus/prometheus.yml"
      - "--storage.tsdb.path=/prometheus"
    ports:
      - "9090:9090"
    networks:
      - monitoring

networks:
  monitoring:
    driver: bridge

```

The `--config.file` flag points to [`/etc/prometheus/prometheus.yml`](https://github.com/mikeroyal/Self-Hosting-Guide/blob/main//etc/prometheus/prometheus.yml) inside the container, while `--storage.tsdb.path` defines where Prometheus stores its time-series data.

### Step 2: Configure Scrape Targets

Create a [`prometheus.yml`](https://github.com/mikeroyal/Self-Hosting-Guide/blob/main/prometheus.yml) file to define your scrape configurations. This file controls which targets Prometheus monitors and how often it collects data.

```yaml
global:
  scrape_interval: 15s
  evaluation_interval: 15s

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

  - job_name: "node"
    static_configs:
      - targets: ["host.docker.internal:9100"]

```

The `scrape_interval` of `15s` tells Prometheus to pull metrics from each target every 15 seconds. The `evaluation_interval` controls how often Prometheus evaluates alerting rules.

### Step 3: Install and Configure Grafana

Add the Grafana service to your [`docker-compose.yml`](https://github.com/mikeroyal/Self-Hosting-Guide/blob/main/docker-compose.yml) file. Grafana must connect to the same Docker network as Prometheus to enable service discovery.

```yaml
  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    depends_on:
      - prometheus
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - ./grafana/provisioning:/etc/grafana/provisioning
    networks:
      - monitoring

```

The `depends_on` directive ensures Prometheus starts before Grafana. Port `3000` exposes the Grafana web interface, while the environment variable sets the admin password.

### Step 4: Provision the Prometheus Data Source

Automate Grafana configuration by creating provisioning files. Create [`grafana/provisioning/datasources/prometheus.yaml`](https://github.com/mikeroyal/Self-Hosting-Guide/blob/main/grafana/provisioning/datasources/prometheus.yaml) to register Prometheus as a data source automatically:

```yaml
apiVersion: 1

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

```

This configuration uses `access: proxy` to route queries through the Grafana backend and points to the Prometheus service URL at `http://prometheus:9090`.

### Step 5: Configure Dashboard Provisioning

Create [`grafana/provisioning/dashboards/dashboard.yaml`](https://github.com/mikeroyal/Self-Hosting-Guide/blob/main/grafana/provisioning/dashboards/dashboard.yaml) to enable automatic dashboard loading:

```yaml
apiVersion: 1

providers:
  - name: "default"
    folder: ""
    type: file
    options:
      path: /etc/grafana/provisioning/dashboards

```

Place any JSON dashboard files in the `./grafana/provisioning/dashboards/` directory on your host, and Grafana will load them automatically on startup.

### Step 6: Launch the Stack

Execute the following command to start both services:

```bash
docker compose up -d

```

Access Prometheus at `http://localhost:9090` to verify targets are being scraped. Access Grafana at `http://localhost:3000` using the credentials `admin/admin`.

Import the Node Exporter Full dashboard (ID 1860) or copy pre-bundled JSON files into your provisioning directory to visualize system metrics immediately.

## Summary

- **Prometheus** pulls metrics from HTTP `/metrics` endpoints using the scrape configuration defined in [`prometheus.yml`](https://github.com/mikeroyal/Self-Hosting-Guide/blob/main/prometheus.yml) and stores them in a time-series database.
- **Grafana** connects to Prometheus at `http://prometheus:9090` to query metrics using PromQL and render visualization dashboards.
- The [`docker-compose.yml`](https://github.com/mikeroyal/Self-Hosting-Guide/blob/main/docker-compose.yml) file orchestrates both services on a shared Docker network named `monitoring` for seamless communication.
- Provisioning files in [`grafana/provisioning/datasources/prometheus.yaml`](https://github.com/mikeroyal/Self-Hosting-Guide/blob/main/grafana/provisioning/datasources/prometheus.yaml) and [`grafana/provisioning/dashboards/dashboard.yaml`](https://github.com/mikeroyal/Self-Hosting-Guide/blob/main/grafana/provisioning/dashboards/dashboard.yaml) automate the initial setup and configuration.
- Node Exporter provides host-level metrics such as CPU, memory, and disk usage when configured as a scrape target in [`prometheus.yml`](https://github.com/mikeroyal/Self-Hosting-Guide/blob/main/prometheus.yml).

## Frequently Asked Questions

### What is the difference between Prometheus and Grafana?

Prometheus is a time-series database that collects and stores metrics using a pull-based model, while Grafana is a visualization platform that queries data sources like Prometheus to create dashboards and alerts. Prometheus handles data collection and storage, whereas Grafana focuses on the presentation layer and user interface.

### How do I secure my Grafana installation?

Change the default administrator password by modifying the `GF_SECURITY_ADMIN_PASSWORD` environment variable in your [`docker-compose.yml`](https://github.com/mikeroyal/Self-Hosting-Guide/blob/main/docker-compose.yml) file. For production environments, configure HTTPS using a reverse proxy like Nginx or Traefik, and enable Grafana's built-in authentication providers or LDAP integration.

### Can Prometheus monitor services running outside of Docker?

Yes, Prometheus can monitor any service that exposes a metrics endpoint via HTTP, regardless of whether it runs inside Docker, on a virtual machine, or on bare metal. Update the `targets` array in your [`prometheus.yml`](https://github.com/mikeroyal/Self-Hosting-Guide/blob/main/prometheus.yml) scrape configurations to include the IP addresses and ports of external services or exporters.

### How do I set up alerting in this monitoring stack?

Define alerting rules in a separate [`alerting_rules.yml`](https://github.com/mikeroyal/Self-Hosting-Guide/blob/main/alerting_rules.yml) file and reference it in your [`prometheus.yml`](https://github.com/mikeroyal/Self-Hosting-Guide/blob/main/prometheus.yml) configuration under the `rule_files` section. Configure Alertmanager to handle notifications, or use Grafana's alerting feature by creating alert rules directly in the Grafana UI that evaluate PromQL queries against your Prometheus data source.