In this tutorial, you’ll install Prometheus, Node Exporter, and Grafana on a Raff Ubuntu 24.04 VM, then verify live server monitoring through a Grafana dashboard.
Prometheus collects and stores time-series metrics, Node Exporter exposes Linux system metrics, and Grafana visualizes those metrics in browser dashboards. This tutorial installs Prometheus 3.5 LTS, Node Exporter, and Grafana on a single Raff VM with Prometheus kept private on localhost and Grafana exposed through port 3000. Raff Technologies has supported 10,000+ VM deployments across its compute platform, and Raff Linux VMs can be provisioned in 60 seconds with NVMe storage and unmetered bandwidth.
This tutorial was tested on a Raff VM with 2 vCPU, 4 GB DDR5 RAM, 80 GB NVMe storage, running Ubuntu 24.04 LTS.
Tested on Raff infrastructure by Aybars Altınyay, platform engineer at Raff Technologies.
Prerequisites:
- A Raff Ubuntu 24.04 VM
- SSH access with sudo privileges
- A terminal connected to the VM
- Port
3000/tcpavailable for Grafana browser access - Basic familiarity with Linux services and firewall rules
📌 Note: This tutorial keeps Prometheus and Node Exporter private to the VM. Grafana is the browser-facing monitoring interface.
Step 1 — Update system packages
Update the Ubuntu package index and install the tools required for downloading binaries, verifying archives, and configuring repositories:
sudo apt update sudo apt upgrade -y sudo apt install -y curl wget tar nano gnupg ca-certificates apt-transport-https software-properties-common ufw
Verify that package upgrades are complete:
sudo apt list --upgradable
Expected output:
Listing... Done
Step 2 — Create Prometheus system users
Create dedicated system users and directories for Prometheus and Node Exporter:
sudo useradd --no-create-home --shell /usr/sbin/nologin prometheus sudo useradd --no-create-home --shell /usr/sbin/nologin node_exporter sudo mkdir -p /etc/prometheus sudo mkdir -p /var/lib/prometheus
Set ownership for the Prometheus data directory:
sudo chown -R prometheus:prometheus /etc/prometheus /var/lib/prometheus
Verify that the users and directories exist:
getent passwd prometheus getent passwd node_exporter ls -ld /etc/prometheus /var/lib/prometheus
Expected output includes:
prometheus:x: node_exporter:x: prometheus prometheus /etc/prometheus prometheus prometheus /var/lib/prometheus
Step 3 — Install Prometheus 3.5 LTS
Download Prometheus 3.5.3 LTS for Linux AMD64:
cd /tmp PROMETHEUS_VERSION="3.5.3" wget "https://github.com/prometheus/prometheus/releases/download/v${PROMETHEUS_VERSION}/prometheus-${PROMETHEUS_VERSION}.linux-amd64.tar.gz"
Verify the archive checksum:
echo "8c30b9d99664e39b0363c0ba54fab30a7958e9d3de27246bf26ed85e6cfb8946 prometheus-${PROMETHEUS_VERSION}.linux-amd64.tar.gz" | sha256sum -c -
Expected output:
prometheus-3.5.3.linux-amd64.tar.gz: OK
Extract the archive:
tar xvf "prometheus-${PROMETHEUS_VERSION}.linux-amd64.tar.gz" cd "prometheus-${PROMETHEUS_VERSION}.linux-amd64"
Install the Prometheus binaries:
sudo cp prometheus promtool /usr/local/bin/ sudo chown prometheus:prometheus /usr/local/bin/prometheus /usr/local/bin/promtool
Install the console libraries:
sudo cp -r consoles console_libraries /etc/prometheus/ sudo chown -R prometheus:prometheus /etc/prometheus/consoles /etc/prometheus/console_libraries
Verify the installed version:
prometheus --version promtool --version
Expected output includes:
prometheus, version 3.5.3 promtool, version 3.5.3
Step 4 — Configure Prometheus
Create the Prometheus configuration file:
sudo nano /etc/prometheus/prometheus.yml
Paste this configuration:
global: scrape_interval: 15s evaluation_interval: 15s scrape_configs: - job_name: "prometheus" static_configs: - targets: ["127.0.0.1:9090"] - job_name: "node_exporter" static_configs: - targets: ["127.0.0.1:9100"]
Set file ownership:
sudo chown prometheus:prometheus /etc/prometheus/prometheus.yml
Validate the Prometheus configuration:
promtool check config /etc/prometheus/prometheus.yml
Expected output:
SUCCESS: /etc/prometheus/prometheus.yml is valid prometheus config file syntax
Step 5 — Create the Prometheus systemd service
Create the Prometheus service file:
sudo nano /etc/systemd/system/prometheus.service
Paste this service definition:
[Unit] Description=Prometheus Monitoring Wants=network-online.target After=network-online.target [Service] User=prometheus Group=prometheus Type=simple ExecStart=/usr/local/bin/prometheus \ --config.file=/etc/prometheus/prometheus.yml \ --storage.tsdb.path=/var/lib/prometheus \ --web.listen-address=127.0.0.1:9090 \ --web.console.templates=/etc/prometheus/consoles \ --web.console.libraries=/etc/prometheus/console_libraries Restart=on-failure [Install] WantedBy=multi-user.target
Reload systemd, start Prometheus, and enable it at boot:
sudo systemctl daemon-reload sudo systemctl enable --now prometheus
Verify that Prometheus is running:
sudo systemctl status prometheus --no-pager
Expected output includes:
Active: active (running)
Verify the Prometheus API locally:
curl -s http://127.0.0.1:9090/-/ready
Expected output:
Prometheus Server is Ready.
Step 6 — Install Node Exporter
Download Node Exporter 1.11.1 for Linux AMD64:
cd /tmp NODE_EXPORTER_VERSION="1.11.1" wget "https://github.com/prometheus/node_exporter/releases/download/v${NODE_EXPORTER_VERSION}/node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64.tar.gz"
Verify the archive checksum:
echo "9f5ea48e5bc7b656f8a91a32e7d7deb89f70f73dabd0d974418aca15f37d6810 node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64.tar.gz" | sha256sum -c -
Expected output:
node_exporter-1.11.1.linux-amd64.tar.gz: OK
Extract and install the binary:
tar xvf "node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64.tar.gz" sudo cp "node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64/node_exporter" /usr/local/bin/ sudo chown node_exporter:node_exporter /usr/local/bin/node_exporter
Verify the installed version:
node_exporter --version
Expected output includes:
node_exporter, version 1.11.1
Step 7 — Create the Node Exporter systemd service
Create the Node Exporter service file:
sudo nano /etc/systemd/system/node_exporter.service
Paste this service definition:
[Unit] Description=Prometheus Node Exporter Wants=network-online.target After=network-online.target [Service] User=node_exporter Group=node_exporter Type=simple ExecStart=/usr/local/bin/node_exporter \ --web.listen-address=127.0.0.1:9100 Restart=on-failure [Install] WantedBy=multi-user.target
Reload systemd, start Node Exporter, and enable it at boot:
sudo systemctl daemon-reload sudo systemctl enable --now node_exporter
Verify that Node Exporter is running:
sudo systemctl status node_exporter --no-pager
Expected output includes:
Active: active (running)
Verify that Node Exporter exposes local metrics:
curl -s http://127.0.0.1:9100/metrics | head
Expected output includes metric lines such as:
# HELP # TYPE
Step 8 — Verify Prometheus scrape targets
Restart Prometheus so it scrapes both configured targets:
sudo systemctl restart prometheus
Query the Prometheus targets API:
curl -s http://127.0.0.1:9090/api/v1/targets | grep -o '"health":"up"' | wc -l
Expected output:
2
Verify each target by name:
curl -s http://127.0.0.1:9090/api/v1/targets | grep -E '"job":"prometheus"|"job":"node_exporter"|"health":"up"'
Expected output includes both jobs and health":"up" entries.
Step 9 — Install Grafana
Install Grafana from the official APT repository:
sudo mkdir -p /etc/apt/keyrings sudo wget -O /etc/apt/keyrings/grafana.asc https://apt.grafana.com/gpg-full.key sudo chmod 644 /etc/apt/keyrings/grafana.asc
Add the stable Grafana repository:
echo "deb [signed-by=/etc/apt/keyrings/grafana.asc] https://apt.grafana.com stable main" | \ sudo tee /etc/apt/sources.list.d/grafana.list
Install Grafana OSS:
sudo apt update sudo apt install -y grafana
Start Grafana and enable it at boot:
sudo systemctl enable --now grafana-server
Verify that Grafana is running:
sudo systemctl status grafana-server --no-pager
Expected output includes:
Active: active (running)
Verify the local Grafana HTTP service:
curl -I http://127.0.0.1:3000/login
Expected output includes:
HTTP/1.1 200 OK
Step 10 — Configure UFW firewall rules
Allow SSH and Grafana access, while keeping Prometheus and Node Exporter private on localhost:
sudo ufw allow 22/tcp sudo ufw allow 3000/tcp sudo ufw deny 9090/tcp sudo ufw deny 9100/tcp sudo ufw --force enable
Verify the firewall status:
sudo ufw status numbered
Expected output includes:
22/tcp ALLOW IN 3000/tcp ALLOW IN 9090/tcp DENY IN 9100/tcp DENY IN
Open Grafana in your browser:
http://your-server-ip:3000
Log in with the default credentials:
Username: admin Password: admin
Grafana prompts you to change the admin password after the first login. Set a strong password before continuing.

Visible state check: Grafana loads in the browser and the login page appears on port 3000.
Step 11 — Connect Grafana to Prometheus
In Grafana, open:
Connections → Data sources → Add data source → Prometheus
Set the Prometheus server URL to:
http://127.0.0.1:9090
Click Save & test.
Expected visible result:
Successfully queried the Prometheus API.

Verify the data source from the VM as well:
curl -s http://127.0.0.1:9090/api/v1/query?query=up
Expected output includes:
"status":"success"
Step 12 — Import the Node Exporter dashboard
In Grafana, open:
Dashboards → New → Import
Use dashboard ID:
1860
Select the Prometheus data source you created, then click Import.

Visible state check: Grafana shows the dashboard import screen for the Node Exporter Full dashboard and lets you select the Prometheus data source.
Step 13 — Verify monitoring end to end
Open the imported Node Exporter dashboard in Grafana.
Set the time range to:
Last 15 minutes
Refresh the dashboard.

End-to-end verification is complete when:
- Prometheus is active under
systemd - Node Exporter is active under
systemd - Prometheus reports both
prometheusandnode_exportertargets asup - Grafana can query Prometheus successfully
- The imported Node Exporter dashboard shows live CPU, memory, disk, and network metrics
Verify the services one final time from the VM:
systemctl is-active prometheus systemctl is-active node_exporter systemctl is-active grafana-server
Expected output:
active active active
Cleanup (Optional)
Use this section only when you want to remove Prometheus, Node Exporter, Grafana, service files, metrics data, dashboards, and firewall rules from the VM.
⚠️ Warning: The following commands permanently delete Prometheus time-series data, Grafana dashboards, Grafana data sources, local Grafana users, and monitoring configuration files. Back up anything you need before proceeding.
Stop the services:
sudo systemctl stop prometheus sudo systemctl stop node_exporter sudo systemctl stop grafana-server sudo systemctl disable prometheus sudo systemctl disable node_exporter sudo systemctl disable grafana-server
Remove Prometheus and Node Exporter binaries and service files:
sudo rm -f /usr/local/bin/prometheus sudo rm -f /usr/local/bin/promtool sudo rm -f /usr/local/bin/node_exporter sudo rm -f /etc/systemd/system/prometheus.service sudo rm -f /etc/systemd/system/node_exporter.service sudo rm -rf /etc/prometheus sudo rm -rf /var/lib/prometheus
Remove Grafana:
sudo apt remove --purge grafana -y sudo rm -rf /etc/grafana sudo rm -rf /var/lib/grafana sudo rm -rf /var/log/grafana sudo rm -f /etc/apt/sources.list.d/grafana.list sudo rm -f /etc/apt/keyrings/grafana.asc
Remove system users:
sudo userdel prometheus 2>/dev/null || true sudo userdel node_exporter 2>/dev/null || true
Reload systemd:
sudo systemctl daemon-reload
Remove the firewall rules:
sudo ufw delete allow 3000/tcp sudo ufw delete deny 9090/tcp sudo ufw delete deny 9100/tcp sudo ufw status numbered
Verify that the services are removed:
systemctl status prometheus --no-pager systemctl status node_exporter --no-pager systemctl status grafana-server --no-pager
Expected output includes:
Unit prometheus.service could not be found. Unit node_exporter.service could not be found. Unit grafana-server.service could not be found.
Troubleshooting
Prometheus fails to start
Cause: The Prometheus configuration file has invalid YAML or an incorrect scrape target.
Fix:
promtool check config /etc/prometheus/prometheus.yml sudo journalctl -u prometheus --no-pager -n 80
Fix any reported configuration error, then restart Prometheus:
sudo systemctl restart prometheus sudo systemctl status prometheus --no-pager
Expected output includes:
Active: active (running)
Node Exporter target is down
Cause: Node Exporter is not running, or Prometheus cannot reach 127.0.0.1:9100.
Fix:
sudo systemctl status node_exporter --no-pager curl -s http://127.0.0.1:9100/metrics | head
If Node Exporter is stopped, restart it:
sudo systemctl restart node_exporter sudo systemctl restart prometheus
Verify the targets again:
curl -s http://127.0.0.1:9090/api/v1/targets | grep -o '"health":"up"' | wc -l
Expected output:
2
Grafana cannot connect to Prometheus
Cause: The Prometheus data source URL is wrong, or Prometheus is not running.
Fix:
systemctl is-active prometheus curl -s http://127.0.0.1:9090/api/v1/query?query=up
Expected output includes:
"status":"success"
In Grafana, set the Prometheus data source URL to:
http://127.0.0.1:9090
Then click Save & test again.
Grafana login page does not load
Cause: Grafana is stopped, port 3000 is blocked, or the browser is using the wrong server IP.
Fix:
sudo systemctl status grafana-server --no-pager sudo ufw status numbered curl -I http://127.0.0.1:3000/login
If Grafana is stopped, restart it:
sudo systemctl restart grafana-server
If port 3000 is blocked, allow it:
sudo ufw allow 3000/tcp sudo ufw reload
Open Grafana again:
http://your-server-ip:3000
Dashboard panels show no data
Cause: The dashboard time range is too narrow, Prometheus has not scraped enough samples yet, or the dashboard is using the wrong data source.
Fix:
curl -s http://127.0.0.1:9090/api/v1/query?query=node_cpu_seconds_total | grep -o '"status":"success"'
Expected output:
"status":"success"
In Grafana:
- Set the time range to Last 15 minutes.
- Click the refresh icon.
- Confirm the dashboard uses the Prometheus data source created in Step 11.
Conclusion and next steps
You now have Prometheus, Node Exporter, and Grafana running on a Raff Ubuntu 24.04 VM, with Prometheus and Node Exporter kept private and Grafana displaying live server metrics. If you have not deployed your Raff VM yet, you can spin one up in 60 seconds at rafftechnologies.com.
Next: How to Secure Your Ubuntu 24.04 Server
Related: How to Install Docker on Ubuntu 24.04