Software & Configuration

Grafana + Prometheus: Monitoring Stack

Install Prometheus and Grafana to monitor CPU, RAM, disk and network of your VPS with visual dashboards and alerting.

Prometheus collects metrics from the server, Grafana visualizes them in dashboards. Together they form the most widespread monitoring stack in Linux environments.

Architecture

VPS → node_exporter → Prometheus → Grafana → Browser

                             Alertmanager → Email/Telegram
  • node_exporter: exports system metrics (CPU, RAM, disk, network)
  • Prometheus: scrapes and saves metrics over time
  • Grafana: web dashboard to visualize data

Install node_exporter

# Latest version from https://github.com/prometheus/node_exporter/releases
NODE_EXPORTER_VERSION="1.8.2"

cd /tmp
wget https://github.com/prometheus/node_exporter/releases/download/v${NODE_EXPORTER_VERSION}/node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64.tar.gz
tar xvf node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64.tar.gz
mv node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64/node_exporter /usr/local/bin/

systemd service for node_exporter

useradd --no-create-home --shell /bin/false node_exporter

cat > /etc/systemd/system/node_exporter.service << 'EOF'
[Unit]
Description=Prometheus Node Exporter
After=network.target

[Service]
User=node_exporter
Group=node_exporter
ExecStart=/usr/local/bin/node_exporter \
  --web.listen-address=":9100" \
  --collector.systemd \
  --collector.processes
Restart=always

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now node_exporter

Verify: curl http://localhost:9100/metrics | head -20


Install Prometheus

PROMETHEUS_VERSION="2.53.0"

cd /tmp
wget https://github.com/prometheus/prometheus/releases/download/v${PROMETHEUS_VERSION}/prometheus-${PROMETHEUS_VERSION}.linux-amd64.tar.gz
tar xvf prometheus-${PROMETHEUS_VERSION}.linux-amd64.tar.gz

mv prometheus-${PROMETHEUS_VERSION}.linux-amd64/prometheus /usr/local/bin/
mv prometheus-${PROMETHEUS_VERSION}.linux-amd64/promtool /usr/local/bin/

mkdir -p /etc/prometheus /var/lib/prometheus
mv prometheus-${PROMETHEUS_VERSION}.linux-amd64/consoles /etc/prometheus/
mv prometheus-${PROMETHEUS_VERSION}.linux-amd64/console_libraries /etc/prometheus/

useradd --no-create-home --shell /bin/false prometheus
chown -R prometheus:prometheus /etc/prometheus /var/lib/prometheus

Prometheus configuration

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

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

  - job_name: "node"
    static_configs:
      - targets: ["localhost:9100"]
        labels:
          instance: "my-vps"
          env: "production"
EOF

systemd service for Prometheus

cat > /etc/systemd/system/prometheus.service << 'EOF'
[Unit]
Description=Prometheus
After=network.target

[Service]
User=prometheus
Group=prometheus
ExecStart=/usr/local/bin/prometheus \
  --config.file=/etc/prometheus/prometheus.yml \
  --storage.tsdb.path=/var/lib/prometheus \
  --storage.tsdb.retention.time=30d \
  --web.listen-address=":9090" \
  --web.enable-lifecycle
Restart=always

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now prometheus

Verify: curl http://localhost:9090/-/healthy


Install Grafana

# Add Grafana repository
apt install -y apt-transport-https software-properties-common
wget -q -O - https://packages.grafana.com/gpg.key | gpg --dearmor > /etc/apt/keyrings/grafana.gpg
echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://packages.grafana.com/oss/deb stable main" > /etc/apt/sources.list.d/grafana.list

apt update
apt install -y grafana

systemctl enable --now grafana-server

Grafana is now available at http://SERVER_IP:3000.

Default login: admin / admin (change the password immediately on first access).


Secure access to Grafana

Grafana should not be exposed directly. Two options:

Option 1: SSH tunnel (local development)

ssh -L 3000:localhost:3000 root@SERVER_IP
# Then visit http://localhost:3000

Option 2: Nginx reverse proxy with SSL

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

    ssl_certificate /etc/letsencrypt/live/grafana.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/grafana.yourdomain.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-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Add Prometheus as datasource in Grafana

  1. Go to Connections → Data Sources → Add data source
  2. Choose Prometheus
  3. URL: http://localhost:9090
  4. Click Save & Test

Ready-to-use dashboards

Import the official dashboard for node_exporter:

  1. Dashboards → Import
  2. ID: 1860 (Node Exporter Full: most complete)
  3. Select the Prometheus datasource
  4. Import

Other useful dashboards:

  • 3662: Node Exporter (simpler)
  • 14282: Prometheus 2.0 Stats
  • 7362: cAdvisor (for Docker)

Useful PromQL queries

# CPU usage %
100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

# Available RAM in GB
node_memory_MemAvailable_bytes / 1024^3

# Disk usage %
(1 - node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100

# Network traffic in Mbps
rate(node_network_transmit_bytes_total{device="eth0"}[5m]) * 8 / 1024^2

# Load average 1m
node_load1

Alerting on Telegram

# Create a Telegram bot: talk to @BotFather → /newbot
# Get the TOKEN and CHAT_ID

nano /etc/grafana/grafana.ini
[alerting]
enabled = true

[unified_alerting]
enabled = true

In Grafana: Alerting → Contact points → Add contact point → Telegram

Enter the BOT_TOKEN and CHAT_ID. Then create alert rules on panels.


Monitor multiple servers

Add other servers to prometheus.yml:

scrape_configs:
  - job_name: "node"
    static_configs:
      - targets:
          - "localhost:9100"         # main server
          - "10.0.0.2:9100"          # secondary server (private network)
          - "1.2.3.4:9100"           # another VPS (expose only if protected)
        labels:
          env: "production"

Push Gateway

If a server is not directly reachable from Prometheus (NAT, firewall), use Pushgateway: the server sends metrics instead of being scraped.

On this page