Install Prometheus and Grafana Monitoring on Ubuntu 24.04

Maya SantosMaya SantosInfrastructure Security Engineer
Intermediate
Updated Apr 6, 202614 min read~30 minutes total
Monitoring
Ubuntu
DevOps
Prometheus
Grafana
Linux
Install Prometheus and Grafana Monitoring on Ubuntu 24.04

On This Page

Prerequisites

A Raff VM running Ubuntu 24.04 with at least 2 vCPU and 4 GB RAM (CPU-Optimized Tier 3 or higher), SSH access with a non-root user with sudo privileges, UFW firewall configured

Don't have a server yet? Deploy a Raff VM in 60 seconds.

Deploy a VM

Introduction

Monitoring is not optional for production servers. Without visibility into CPU usage, memory consumption, disk I/O, and network traffic, you are flying blind — problems become visible only when users report them, and by then the damage is done. A proper monitoring stack catches resource exhaustion, performance degradation, and anomalies before they escalate into downtime.

Prometheus and Grafana are the industry-standard open-source monitoring combination. Prometheus collects and stores time-series metrics by scraping targets at regular intervals, supports a powerful query language called PromQL, and handles alerting rules. Grafana connects to Prometheus as a data source and provides a web-based dashboard builder for visualizing metrics as graphs, gauges, tables, and heatmaps. Together, they give you complete observability into your server's health.

In this tutorial, you will install Prometheus to collect metrics, deploy Node Exporter to expose system-level metrics (CPU, memory, disk, network), install Grafana for dashboard visualization, connect Grafana to Prometheus, and import a pre-built dashboard to start monitoring immediately. On our own Raff infrastructure, we run this exact stack across all compute nodes — the setup you build in this tutorial mirrors what we use in production.

Step 1 — Create System Users for Prometheus

Prometheus and Node Exporter should run under dedicated system accounts with no login shell and no home directory. This follows the principle of least privilege — if either service is compromised, the attacker cannot use the account to log in or escalate privileges.

Create a system user for Prometheus:

bashsudo useradd --no-create-home --shell /usr/sbin/nologin prometheus

Create the directories Prometheus needs for configuration and data storage:

bashsudo mkdir -p /etc/prometheus
sudo mkdir -p /var/lib/prometheus

Set ownership so the Prometheus user can write to its data directory:

bashsudo chown prometheus:prometheus /var/lib/prometheus

Step 2 — Install Prometheus

Download the latest Prometheus release. Check the Prometheus downloads page for the current version — at the time of writing, the latest LTS is 2.53:

bashcd /tmp
curl -LO https://github.com/prometheus/prometheus/releases/download/v2.53.3/prometheus-2.53.3.linux-amd64.tar.gz

Extract the archive:

bashtar xvf prometheus-2.53.3.linux-amd64.tar.gz
cd prometheus-2.53.3.linux-amd64

Copy the binaries to the system path:

bashsudo cp prometheus promtool /usr/local/bin/

Copy the console templates and libraries to the configuration directory:

bashsudo cp -r consoles console_libraries /etc/prometheus/

Set ownership:

bashsudo chown -R prometheus:prometheus /etc/prometheus
sudo chown prometheus:prometheus /usr/local/bin/prometheus /usr/local/bin/promtool

Verify the installation:

bashprometheus --version

You should see the version number and build information.

Clean up the downloaded files:

bashcd ~
rm -rf /tmp/prometheus-*

Step 3 — Configure Prometheus

Create the Prometheus configuration file:

bashsudo nano /etc/prometheus/prometheus.yml

Add the following configuration:

yamlglobal:
  scrape_interval: 15s
  evaluation_interval: 15s

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

  - job_name: "node_exporter"
    static_configs:
      - targets: ["localhost:9100"]

This configuration tells Prometheus to scrape metrics every 15 seconds from two targets: itself (port 9090) and Node Exporter (port 9100, which you will install in the next step).

Set the file ownership:

bashsudo chown prometheus:prometheus /etc/prometheus/prometheus.yml

Create a systemd service file so Prometheus starts automatically:

bashsudo nano /etc/systemd/system/prometheus.service

Add the following:

ini[Unit]
Description=Prometheus Monitoring System
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.console.templates=/etc/prometheus/consoles \
  --web.console.libraries=/etc/prometheus/console_libraries \
  --storage.tsdb.retention.time=30d
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

The --storage.tsdb.retention.time=30d flag keeps 30 days of metrics data. Adjust this based on your disk space — each day of metrics for a single server typically uses 10-50 MB depending on the number of metrics collected.

Start Prometheus and enable it at boot:

bashsudo systemctl daemon-reload
sudo systemctl start prometheus
sudo systemctl enable prometheus

Verify it is running:

bashsudo systemctl status prometheus

You should see active (running). Test that Prometheus is responding:

bashcurl -s http://localhost:9090/-/healthy

Expected output:

Prometheus Server is Healthy.

Step 4 — Install Node Exporter

Node Exporter is a Prometheus exporter that exposes hardware and OS-level metrics — CPU usage, memory, disk I/O, network traffic, filesystem usage, and more. It runs as a lightweight daemon on each server you want to monitor.

Create a system user for Node Exporter:

bashsudo useradd --no-create-home --shell /usr/sbin/nologin node_exporter

Download and install Node Exporter:

bashcd /tmp
curl -LO https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz
tar xvf node_exporter-1.8.2.linux-amd64.tar.gz
sudo cp node_exporter-1.8.2.linux-amd64/node_exporter /usr/local/bin/
sudo chown node_exporter:node_exporter /usr/local/bin/node_exporter

Create the systemd service file:

bashsudo nano /etc/systemd/system/node_exporter.service

Add the following:

ini[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
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Start Node Exporter and enable it at boot:

bashsudo systemctl daemon-reload
sudo systemctl start node_exporter
sudo systemctl enable node_exporter

Verify it is running:

bashsudo systemctl status node_exporter

Test that metrics are being exposed:

bashcurl -s http://localhost:9100/metrics | head -20

You should see lines starting with # HELP and # TYPE followed by metric names and values. Each metric represents a measurement — CPU seconds, memory bytes, disk operations, network packets.

Clean up:

bashrm -rf /tmp/node_exporter-*

Tip

To monitor additional Raff VMs, install Node Exporter on each server and add its IP to the node_exporter job targets in /etc/prometheus/prometheus.yml. For example: targets: ["localhost:9100", "10.0.0.5:9100", "10.0.0.6:9100"]. Prometheus will scrape all targets at the configured interval.

Step 5 — Install Grafana

Grafana provides the visualization layer. Install it from the official Grafana APT repository to receive the latest updates.

Install the prerequisites and add the Grafana GPG key:

bashsudo apt install -y apt-transport-https software-properties-common
curl -fsSL https://apt.grafana.com/gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/grafana.gpg

Add the Grafana repository:

bashecho "deb [signed-by=/usr/share/keyrings/grafana.gpg] https://apt.grafana.com stable main" | sudo tee /etc/apt/sources.list.d/grafana.list

Install Grafana:

bashsudo apt update
sudo apt install -y grafana

Start Grafana and enable it at boot:

bashsudo systemctl start grafana-server
sudo systemctl enable grafana-server

Verify it is running:

bashsudo systemctl status grafana-server

You should see active (running).

Step 6 — Configure the Firewall and Access Grafana

Allow access to Grafana's web interface through UFW:

bashsudo ufw allow 3000/tcp

Tip

For production environments, restrict Grafana access to your own IP: sudo ufw allow from your_ip to any port 3000. You can also place Grafana behind Nginx with HTTPS for encrypted access, or use a WireGuard VPN to access it privately without exposing the port.

Open your browser and navigate to:

http://your_server_ip:3000

Log in with the default credentials:

  • Username: admin
  • Password: admin

Grafana immediately prompts you to change the admin password. Set a strong password and click Save.

Step 7 — Connect Grafana to Prometheus

After logging in, add Prometheus as a data source so Grafana can query metrics.

Click the hamburger menu (three horizontal lines) in the top left, then navigate to ConnectionsData sourcesAdd data source.

Select Prometheus from the list.

In the configuration form, set the Prometheus server URL to:

http://localhost:9090

Leave all other settings at their defaults. Scroll to the bottom and click Save & Test. You should see a green banner confirming "Successfully queried the Prometheus API."

Step 8 — Import a Dashboard

Instead of building dashboards from scratch, import a pre-built community dashboard for Node Exporter metrics. The most popular one is "Node Exporter Full" (Dashboard ID: 1860).

Click the hamburger menuDashboardsNewImport.

In the Import via grafana.com field, enter:

1860

Click Load. Grafana fetches the dashboard configuration from grafana.com.

In the Prometheus dropdown at the bottom, select the Prometheus data source you configured in Step 7. Click Import.

You should see a comprehensive dashboard with panels showing CPU usage, memory usage, disk I/O, network traffic, filesystem usage, and system load. The data updates automatically at the scrape interval you configured (15 seconds).

Key panels to monitor:

  • CPU Busy — Percentage of CPU time spent on work. Sustained values above 80% suggest you need a larger VM or need to optimize your application.
  • RAM Used — Memory consumption. If this consistently exceeds 85% of total RAM, consider upgrading your Raff VM tier.
  • Disk I/O — Read and write operations per second. NVMe SSD storage on Raff VMs handles high IOPS without bottlenecking.
  • Network Traffic — Bytes sent and received. With unmetered bandwidth on Raff, you do not need to worry about overage charges regardless of traffic volume.

Step 9 — Verify Prometheus Targets

Confirm that Prometheus is successfully scraping both targets. Allow temporary access to the Prometheus UI:

bashsudo ufw allow 9090/tcp

Navigate to http://your_server_ip:9090/targets in your browser. You should see two targets — prometheus and node_exporter — both showing UP in green. If either shows DOWN, check that the respective service is running with systemctl status.

After verifying, remove public access to the Prometheus UI:

bashsudo ufw delete allow 9090/tcp

Conclusion

You have installed Prometheus and Grafana on your Raff Ubuntu 24.04 VM, deployed Node Exporter for system metrics, connected Grafana to Prometheus, and imported a comprehensive monitoring dashboard. Your server now has full observability into CPU, memory, disk, and network performance.

From here, you can:

  • Monitor additional Raff VMs by installing Node Exporter on each server and adding them as Prometheus scrape targets
  • Set up Grafana alerting to send notifications via email, Slack, or PagerDuty when metrics cross thresholds
  • Complement this stack with Uptime Kuma for HTTP endpoint monitoring alongside infrastructure metrics
  • Secure Grafana behind Nginx with HTTPS for encrypted dashboard access
  • Add application-specific exporters for MySQL, PostgreSQL, Redis, or Docker containers
  • Protect access to your monitoring stack using fail2ban and UFW

Prometheus and Grafana together use approximately 300-700 MB of RAM, which fits comfortably on a Raff Tier 2 VM ($9.99/month) alongside lightweight services. For monitoring multiple servers or retaining longer metric history, the Tier 3 ($19.99/month) provides more headroom. NVMe SSD storage ensures fast metric writes and dashboard query responses even with 30 days of retention data.

This tutorial was tested by our security engineering team on a Raff CPU-Optimized Tier 3 VM with Prometheus 2.53 and Grafana 11.

Get notified when we publish new tutorials

Cloud tips, step-by-step guides, and infrastructure insights — straight to your inbox.

Frequently Asked Questions

Ready to get started?

Deploy an Ubuntu 24.04 VM and follow along in under 60 seconds.

Deploy a VM Now