Grafana Installation and Dashboard Creation

Grafana is a leading open-source visualization and alerting platform that works with multiple data sources including Prometheus, Elasticsearch, InfluxDB, and many others. It enables teams to query, visualize, understand metrics, and create dashboards that tell the story of your infrastructure. This comprehensive guide covers installation, configuration, data source setup, and dashboard creation.

Table of Contents

Introduction

Grafana transforms raw metrics into meaningful visualizations. It provides real-time dashboards, supports multiple data sources, offers powerful templating capabilities, and integrates seamlessly with alerting systems. Whether you're monitoring a single server or thousands of instances, Grafana scales with your infrastructure needs.

System Requirements

Before installing Grafana, verify system compatibility:

  • Linux kernel 2.6.32 or later
  • Minimum 256MB RAM (1GB+ recommended for production)
  • At least 5GB free disk space for database
  • Python 2.7 or 3.0+ (for some plugins)
  • Supported databases: SQLite (default), PostgreSQL, MySQL
  • Internet access for plugin and dashboard downloads

Installation Methods

Method 1: Repository Installation (Ubuntu/Debian)

The easiest way to install Grafana on Debian-based systems:

# Add Grafana repository
sudo apt-get install -y software-properties-common
sudo add-apt-repository "deb https://packages.grafana.com/oss/deb stable main"
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -

# Update and install
sudo apt-get update
sudo apt-get install -y grafana

# Enable and start service
sudo systemctl enable grafana-server
sudo systemctl start grafana-server
sudo systemctl status grafana-server

Method 2: Repository Installation (RHEL/CentOS)

For Red Hat-based systems:

# Create repository file
sudo tee /etc/yum.repos.d/grafana.repo > /dev/null << 'EOF'
[grafana]
name=grafana
baseurl=https://packages.grafana.com/oss/rpm
repo_gpgcheck=1
enabled=1
gpgcheck=1
gpgkey=https://packages.grafana.com/gpg.key
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
EOF

# Install Grafana
sudo yum install -y grafana

# Enable and start
sudo systemctl enable grafana-server
sudo systemctl start grafana-server

Method 3: Docker Installation

Deploy Grafana in a container:

# Create data directory
mkdir -p /data/grafana

# Run Grafana container
docker run -d \
  --name grafana \
  --restart unless-stopped \
  -p 3000:3000 \
  -e GF_SECURITY_ADMIN_PASSWORD=admin \
  -e GF_INSTALL_PLUGINS=grafana-piechart-panel,grafana-worldmap-panel \
  -v /data/grafana:/var/lib/grafana \
  grafana/grafana:latest

# Verify container is running
docker logs grafana
docker ps | grep grafana

Method 4: Binary Installation

For systems without package managers:

cd /tmp
wget https://dl.grafana.com/oss/release/grafana-11.0.0.linux-amd64.tar.gz
tar -xvzf grafana-11.0.0.linux-amd64.tar.gz
sudo mv grafana-11.0.0 /opt/grafana

# Create systemd service
sudo tee /etc/systemd/system/grafana.service > /dev/null << 'EOF'
[Unit]
Description=Grafana
After=network.target

[Service]
Type=simple
ExecStart=/opt/grafana/bin/grafana-server \
  --config=/opt/grafana/conf/defaults.ini \
  --homepath=/opt/grafana
Restart=always

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable grafana
sudo systemctl start grafana

Initial Configuration

First-Time Setup

Access Grafana at http://localhost:3000:

  1. Default credentials: admin/admin
  2. Change the admin password immediately
  3. Configure data sources
  4. Create dashboards

Configuration File

Edit Grafana configuration at /etc/grafana/grafana.ini:

sudo nano /etc/grafana/grafana.ini

Key configuration options:

[server]
protocol = http
http_addr = 0.0.0.0
http_port = 3000
domain = grafana.example.com
root_url = https://grafana.example.com

[database]
type = postgres
host = localhost:5432
name = grafana
user = grafana
password = secure_password

[security]
admin_user = admin
admin_password = strong_password
secret_key = new_secret_key_min_16_chars
cookie_secure = true
cookie_samesite = strict

[auth.basic]
enabled = true

[auth.anonymous]
enabled = false

[auth.github]
enabled = true
allow_sign_up = true
client_id = your_github_client_id
client_secret = your_github_client_secret

[session]
provider = postgres
provider_config = user=grafana password=secure_password host=localhost name=grafana_sessions
cookie_secure = true

[log]
mode = file
level = info

After modifying configuration:

sudo systemctl restart grafana-server
sudo journalctl -u grafana-server -f

User Management

Create new users for team members:

# Via CLI
sudo grafana-cli admin create-user --username newuser --password password --admin

# Or through web interface
# Settings > Admin > Users > New User

Data Sources

Adding Prometheus Data Source

Connect Grafana to Prometheus:

  1. Navigate to Configuration > Data Sources
  2. Click "Add data source"
  3. Select "Prometheus"
  4. Configure settings:
Name: Prometheus Production
URL: http://prometheus.example.com:9090
Access: Server (default)
Scrape interval: 15s
Query timeout: 60s
HTTP method: GET
  1. Click "Save & Test"

Adding InfluxDB Data Source

Name: InfluxDB
URL: http://localhost:8086
Database: metrics
Username: influxuser
Password: influxpassword

Adding Elasticsearch Data Source

Name: Elasticsearch
URL: http://elasticsearch:9200
Index name: logs-[yyyy.MM.dd]
Time field name: @timestamp
Min interval: 10s

Adding PostgreSQL Data Source

Name: PostgreSQL Database
Host: postgres.example.com:5432
Database: analytics
User: grafana_user
Password: secure_password
SSL Mode: require

Data Source Variables

Create data source variables in dashboards:

{
  "datasource": {
    "type": "datasource",
    "uid": "000000002",
    "name": "prometheus",
    "value": "prometheus_uid"
  }
}

Panel Types and Visualization

Time Series Panels

Most common visualization for metrics over time:

{
  "type": "timeseries",
  "title": "CPU Usage",
  "targets": [
    {
      "expr": "100 - (avg by (instance) (irate(node_cpu_seconds_total{mode=\"idle\"}[5m])) * 100)",
      "legendFormat": "{{instance}}"
    }
  ],
  "fieldConfig": {
    "defaults": {
      "unit": "percent",
      "min": 0,
      "max": 100,
      "thresholds": {
        "mode": "absolute",
        "steps": [
          {"color": "green", "value": null},
          {"color": "yellow", "value": 70},
          {"color": "red", "value": 90}
        ]
      }
    }
  }
}

Gauge Panels

Showing current values with threshold visualization:

{
  "type": "gauge",
  "title": "Memory Usage",
  "targets": [
    {
      "expr": "(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100"
    }
  ],
  "fieldConfig": {
    "defaults": {
      "unit": "percent",
      "min": 0,
      "max": 100,
      "mappings": [],
      "thresholds": {
        "mode": "percentage",
        "steps": [
          {"color": "green", "value": null},
          {"color": "yellow", "value": 60},
          {"color": "orange", "value": 80},
          {"color": "red", "value": 90}
        ]
      }
    }
  }
}

Table Panels

Display data in tabular format:

{
  "type": "table",
  "title": "Top Memory Consumers",
  "targets": [
    {
      "expr": "topk(10, (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100)"
    }
  ],
  "options": {
    "showHeader": true,
    "sortBy": []
  }
}

Stat Panels

Highlight single important metrics:

{
  "type": "stat",
  "title": "Error Rate",
  "targets": [
    {
      "expr": "rate(errors_total[5m]) * 100"
    }
  ],
  "options": {
    "textMode": "auto",
    "colorMode": "background",
    "graphMode": "area",
    "justifyMode": "auto",
    "orientation": "auto"
  }
}

Heatmap Panels

Visualize distributions over time:

{
  "type": "heatmap",
  "title": "Request Latency Heatmap",
  "targets": [
    {
      "expr": "sum(rate(http_request_duration_seconds_bucket[5m])) by (le)"
    }
  ],
  "options": {
    "bucketSize": null,
    "bucketOffset": 0,
    "sortByField": null
  }
}

Dashboard Variables

String Variables

Create variables for dynamic filtering:

{
  "name": "environment",
  "type": "custom",
  "value": "production",
  "options": ["production", "staging", "development"]
}

Query Variables

Fetch options from data source:

{
  "name": "instance",
  "type": "query",
  "datasource": "Prometheus",
  "query": "label_values(up, instance)",
  "current": {"selected": false, "text": "All", "value": "$__all"}
}

Using Variables in Queries

rate(http_requests_total{environment="$environment", instance=~"$instance"}[5m])

Multi-Select Variables

Allow selecting multiple values:

{
  "name": "servers",
  "type": "query",
  "multi": true,
  "query": "label_values(node_uname_info, instance)",
  "current": {"selected": true, "text": "All", "value": "$__all"}
}

Importing Dashboards

Download Community Dashboards

Grafana has thousands of community dashboards available at https://grafana.com/grafana/dashboards:

# Popular dashboards:
# 1860 - Node Exporter for Prometheus
# 3662 - Prometheus 2.0 Overview
# 3119 - Prometheus Alert Overview

Import via Web Interface

  1. Go to Dashboards > Import
  2. Enter dashboard ID (e.g., 1860)
  3. Select data source (Prometheus)
  4. Click "Import"

Import via API

# Get dashboard JSON
curl -H "Authorization: Bearer $GRAFANA_API_TOKEN" \
  https://grafana.example.com/api/dashboards/home

# Import dashboard
curl -X POST -H "Content-Type: application/json" \
  -H "Authorization: Bearer $GRAFANA_API_TOKEN" \
  -d @dashboard.json \
  https://grafana.example.com/api/dashboards/db

Custom Dashboard Export

# Export dashboard as JSON
curl -H "Authorization: Bearer $TOKEN" \
  https://grafana.example.com/api/dashboards/uid/my-dashboard-uid > dashboard.json

# Import elsewhere
curl -X POST -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d @dashboard.json \
  https://other-grafana.example.com/api/dashboards/db

Alerting Setup

Configure Alert Notification Channels

Navigate to Alerting > Notification Channels:

Email Notifications

# Configure SMTP in grafana.ini
[smtp]
enabled = true
host = smtp.gmail.com:587
user = [email protected]
password = your-app-password
from_address = [email protected]
from_name = Grafana

Slack Integration

{
  "type": "slack",
  "name": "Slack Notifications",
  "settings": {
    "url": "https://hooks.slack.com/services/YOUR/WEBHOOK/URL",
    "uploadImage": true,
    "mention": "@devops"
  }
}

PagerDuty Integration

{
  "type": "pagerduty",
  "name": "PagerDuty",
  "settings": {
    "integrationKey": "your-integration-key"
  }
}

Create Alert Rules

Add alerts to dashboard panels:

  1. Edit panel
  2. Go to "Alert" tab
  3. Define conditions:
# Alert if CPU > 80%
100 - (avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
  1. Configure notification policy
  2. Set frequency and pending duration

User Management

Create Organizations

For multi-tenant setups:

# Via API
curl -X POST -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"name":"Engineering Team"}' \
  https://grafana.example.com/api/orgs

Configure Teams

Manage team permissions:

# Create team
curl -X POST -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"name":"DevOps","orgId":1}' \
  https://grafana.example.com/api/teams

# Add user to team
curl -X POST -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"userId":1}' \
  https://grafana.example.com/api/teams/1/members

Role-Based Access Control

Set permissions for dashboards:

curl -X POST -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"role":"Viewer","permission":1}' \
  https://grafana.example.com/api/dashboards/uid/my-dashboard/permissions

Backup and Migration

Export All Dashboards

#!/bin/bash
GRAFANA_URL="http://localhost:3000"
API_TOKEN="your-api-token"
BACKUP_DIR="./grafana-backup"

mkdir -p $BACKUP_DIR

# Get all dashboards
curl -H "Authorization: Bearer $API_TOKEN" \
  "$GRAFANA_URL/api/search?type=dash-db&limit=1000" | jq -r '.[] | .uid' | while read uid; do
  curl -H "Authorization: Bearer $API_TOKEN" \
    "$GRAFANA_URL/api/dashboards/uid/$uid" | jq . > "$BACKUP_DIR/$uid.json"
done

echo "Dashboards exported to $BACKUP_DIR"

PostgreSQL Backup

If using PostgreSQL backend:

sudo -u postgres pg_dump -d grafana > grafana_backup.sql
sudo -u postgres pg_dump -d grafana_sessions > grafana_sessions_backup.sql

# Restore
sudo -u postgres psql -d grafana < grafana_backup.sql

Volume Backup

For Docker installations:

# Backup volume
docker run --rm \
  -v grafana-storage:/data \
  -v $(pwd):/backup \
  alpine tar czf /backup/grafana-backup.tar.gz -C /data .

# Restore
docker run --rm \
  -v grafana-storage:/data \
  -v $(pwd):/backup \
  alpine tar xzf /backup/grafana-backup.tar.gz -C /data

Conclusion

Grafana transforms monitoring data into actionable insights through intuitive visualizations and dashboards. By following this guide, you've established a powerful observability platform that scales with your infrastructure. Focus on creating meaningful dashboards that tell stories about your systems, regularly backup your configurations and dashboards, and leverage community resources for continued learning and improvement. With Grafana as your visualization layer, you empower teams to understand system behavior and respond quickly to issues.