Introduction
Grafana has become the go-to tool for metrics visualization in 2026. Paired with Prometheus, it enables real-time monitoring of complex infrastructures. This intermediate tutorial guides you step by step through deploying a complete stack, configuring automatic provisioning, and setting up alerts. You will learn to create reusable dashboards and avoid common production pitfalls.
Prerequisites
- Docker and Docker Compose v2
- Basic knowledge of Prometheus
- Access to a Linux/macOS terminal
- Understanding of YAML and JSON
Stack Deployment
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
grafana:
image: grafana/grafana:latest
volumes:
- grafana-storage:/var/lib/grafana
- ./provisioning:/etc/grafana/provisioning
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
grafana-storage:This docker-compose file deploys Prometheus and Grafana with persistent volumes. The provisioning folder enables automatic configuration of datasources and dashboards at startup.
Prometheus Configuration
Prometheus collects the metrics. We will now create its main configuration to scrape targets.
Prometheus Configuration
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node-exporter'
static_configs:
- targets: ['node-exporter:9100']This file defines the scraping jobs. The 15-second interval suits most intermediate use cases. Add your own targets according to your services.
Grafana Provisioning
Provisioning allows automatic configuration of datasources and dashboards without manual interface interaction.
Datasource Provisioning
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
editable: falseThis YAML file is automatically loaded by Grafana at startup. It creates the Prometheus connection without manual intervention.
Complete Dashboard JSON
{
"dashboard": {
"title": "CPU & Mémoire",
"panels": [
{
"title": "CPU Usage",
"type": "timeseries",
"targets": [
{
"expr": "100 - (avg by (instance) (irate(node_cpu_seconds_total{mode=\"idle\"}[5m])) * 100)",
"refId": "A"
}
]
}
],
"time": {
"from": "now-1h",
"to": "now"
}
}
}This JSON dashboard displays CPU usage. Place it in the provisioning/dashboards folder so it appears automatically in Grafana.
Alerting Rules
groups:
- name: cpu_alerts
rules:
- alert: HighCPUUsage
expr: 100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
for: 5m
labels:
severity: warning
annotations:
summary: "CPU élevée sur {{ $labels.instance }}"These rules define an alert when CPU exceeds 80% for 5 minutes. Include this file in the Prometheus configuration to enable alerting.
Best Practices
- Always use provisioning for reproducible environments
- Limit permissions on shared dashboards
- Enable OAuth or LDAP authentication in production
- Store your JSON dashboards in Git
- Test alerts with realistic thresholds
Common Errors to Avoid
- Forgetting to mount the provisioning volume in Docker Compose
- Using overly expensive PromQL expressions without aggregation
- Not configuring Prometheus retention rules
- Ignoring Grafana volume permissions (403 errors)
Going Further
Explore Grafana Enterprise plugins and integrations with Loki and Tempo. Join our advanced training at Learni Group.