Grafana is an open-source analytics and visualization platform that turns time-series data into actionable dashboards. Prometheus is a CNCF-graduated monitoring system that collects metrics from targets using a pull model and stores them in a time-series database. Together, they form the standard monitoring stack for Linux servers, containers, and applications.
This guide walks through installing Grafana with Prometheus on Oracle Linux 9 and Oracle Linux 10. We cover Prometheus binary installation with systemd, node_exporter for host metrics, Grafana OSS from the official RPM repository, dashboard imports, alerting rules, YAML-based provisioning, and an Nginx reverse proxy with Let’s Encrypt SSL.
Prerequisites
Before starting, confirm the following are in place.
- A server running Oracle Linux 9 or Oracle Linux 10 with at least 2 GB RAM and 2 CPU cores
- Root or sudo access
- A registered domain name pointing to the server IP (for Nginx SSL section)
- Ports 3000/tcp (Grafana), 9090/tcp (Prometheus), 9100/tcp (node_exporter), 80/tcp, and 443/tcp open
- Internet connectivity to download packages and binaries
Update your system packages before proceeding.
sudo dnf update -y
Step 1: Install Prometheus on Oracle Linux 9/10
Prometheus is distributed as a standalone binary. We download the latest release, create a dedicated system user, and configure systemd to manage the process.
Create Prometheus System User and Directories
Create a dedicated user with no login shell and the required directory structure.
sudo useradd --no-create-home --shell /bin/false prometheus
sudo mkdir -p /etc/prometheus /var/lib/prometheus
sudo chown prometheus:prometheus /etc/prometheus /var/lib/prometheus
Download and Extract Prometheus Binary
Fetch the latest Prometheus release from GitHub and extract it.
VER=$(curl -s https://api.github.com/repos/prometheus/prometheus/releases/latest | grep tag_name | cut -d '"' -f 4 | sed 's/v//')
echo "Downloading Prometheus version ${VER}"
wget https://github.com/prometheus/prometheus/releases/download/v${VER}/prometheus-${VER}.linux-amd64.tar.gz
tar -xvzf prometheus-${VER}.linux-amd64.tar.gz
Copy the binaries and supporting files into the correct locations.
sudo cp prometheus-${VER}.linux-amd64/prometheus /usr/local/bin/
sudo cp prometheus-${VER}.linux-amd64/promtool /usr/local/bin/
sudo cp -r prometheus-${VER}.linux-amd64/consoles /etc/prometheus/
sudo cp -r prometheus-${VER}.linux-amd64/console_libraries /etc/prometheus/
sudo chown -R prometheus:prometheus /usr/local/bin/prometheus /usr/local/bin/promtool
sudo chown -R prometheus:prometheus /etc/prometheus
Verify the installed version.
$ prometheus --version
prometheus, version 3.2.1 (branch: HEAD, revision: xxxxxxx)
build user: root@builder
build date: 2025-xx-xx
go version: go1.23.x
platform: linux/amd64
Create Prometheus Configuration File
Write a base configuration that scrapes Prometheus itself. We will add more scrape targets later.
echo 'global:
scrape_interval: 15s
evaluation_interval: 15s
rule_files:
- "alert_rules.yml"
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"]' | sudo tee /etc/prometheus/prometheus.yml
Set ownership on the configuration file.
sudo chown prometheus:prometheus /etc/prometheus/prometheus.yml
Create the Prometheus Systemd Service
Create the unit file so systemd manages Prometheus startup, restarts, and logging.
echo '[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
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
[Install]
WantedBy=multi-user.target' | sudo tee /etc/systemd/system/prometheus.service
Reload systemd, enable, and start Prometheus.
sudo systemctl daemon-reload
sudo systemctl enable --now prometheus
Confirm Prometheus is running.
$ systemctl status prometheus
● prometheus.service - Prometheus Monitoring System
Loaded: loaded (/etc/systemd/system/prometheus.service; enabled; preset: disabled)
Active: active (running)
Main PID: 4521 (prometheus)
Tasks: 10
Memory: 85.2M
CGroup: /system.slice/prometheus.service
Open port 9090/tcp in firewalld so you can reach the Prometheus web UI.
sudo firewall-cmd --add-port=9090/tcp --permanent
sudo firewall-cmd --reload
Browse to http://192.168.1.10:9090 (replace with your server IP) and confirm the Prometheus expression browser loads.
Step 2: Install Node Exporter for Host Metrics
Node Exporter exposes hardware and kernel metrics (CPU, memory, disk, network) that Prometheus scrapes. Install it on every host you want to monitor with Prometheus and Grafana.
Download and Install Node Exporter
NE_VER=$(curl -s https://api.github.com/repos/prometheus/node_exporter/releases/latest | grep tag_name | cut -d '"' -f 4 | sed 's/v//')
wget https://github.com/prometheus/node_exporter/releases/download/v${NE_VER}/node_exporter-${NE_VER}.linux-amd64.tar.gz
tar -xvzf node_exporter-${NE_VER}.linux-amd64.tar.gz
sudo cp node_exporter-${NE_VER}.linux-amd64/node_exporter /usr/local/bin/
sudo useradd --no-create-home --shell /bin/false node_exporter
sudo chown node_exporter:node_exporter /usr/local/bin/node_exporter
Create Systemd Service for Node Exporter
echo '[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=on-failure
[Install]
WantedBy=multi-user.target' | sudo tee /etc/systemd/system/node_exporter.service
Enable and start node_exporter.
sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter
Check that the service is running and metrics are exposed on port 9100.
$ systemctl status node_exporter
● node_exporter.service - Prometheus Node Exporter
Active: active (running)
$ curl -s http://localhost:9100/metrics | head -5
# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 2.3456e-05
go_gc_duration_seconds{quantile="0.25"} 3.1234e-05
go_gc_duration_seconds{quantile="0.5"} 4.5678e-05
Allow port 9100/tcp in the firewall if you scrape this node from a remote Prometheus server.
sudo firewall-cmd --add-port=9100/tcp --permanent
sudo firewall-cmd --reload
Add Node Exporter Target to Prometheus
Edit the Prometheus configuration to add the node_exporter job.
sudo vi /etc/prometheus/prometheus.yml
Append this block under scrape_configs.
- job_name: "node_exporter"
static_configs:
- targets: ["localhost:9100"]
labels:
instance: "oracle-linux-server"
The full /etc/prometheus/prometheus.yml should now look like this.
global:
scrape_interval: 15s
evaluation_interval: 15s
rule_files:
- "alert_rules.yml"
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"]
- job_name: "node_exporter"
static_configs:
- targets: ["localhost:9100"]
labels:
instance: "oracle-linux-server"
Reload Prometheus to pick up the changes without restarting the service.
sudo systemctl reload prometheus
Go to http://192.168.1.10:9090/targets in your browser and verify both targets show a State of UP.
Step 3: Install Grafana OSS on Oracle Linux 9/10
Grafana OSS (Open Source) is available from the official Grafana RPM repository. Installing from the repo ensures future updates come through dnf update.
Add the Grafana RPM Repository
Create the repo file.
echo '[grafana]
name=grafana
baseurl=https://rpm.grafana.com
repo_gpgcheck=1
enabled=1
gpgcheck=1
gpgkey=https://rpm.grafana.com/gpg.key
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt' | sudo tee /etc/yum.repos.d/grafana.repo
Install Grafana
Install the grafana package from the newly added repository.
sudo dnf install -y grafana
Verify the installed version.
$ rpm -qi grafana | grep -E "^(Name|Version)"
Name : grafana
Version : 11.5.2
Start and Enable Grafana
Enable the service and start it immediately.
sudo systemctl enable --now grafana-server
Check the service status.
$ systemctl status grafana-server
● grafana-server.service - Grafana instance
Loaded: loaded (/usr/lib/systemd/system/grafana-server.service; enabled; preset: disabled)
Active: active (running)
Main PID: 5612 (grafana)
Memory: 48.3M
CGroup: /system.slice/grafana-server.service
Key file locations for the Grafana RPM install:
- Binary:
/usr/sbin/grafana-server - Configuration:
/etc/grafana/grafana.ini - Provisioning:
/etc/grafana/provisioning/ - Logs:
/var/log/grafana/grafana.log - SQLite database:
/var/lib/grafana/grafana.db - Plugins:
/var/lib/grafana/plugins
Open port 3000/tcp in the firewall for initial access.
sudo firewall-cmd --add-port=3000/tcp --permanent
sudo firewall-cmd --reload
Browse to http://192.168.1.10:3000. Log in with the default credentials – username admin and password admin. Grafana prompts you to set a new password on first login.
Step 4: Configure Prometheus Data Source in Grafana
With both Prometheus and Grafana running, connect them by adding Prometheus as a data source.
- In the Grafana sidebar, go to Connections > Data sources
- Click Add data source and select Prometheus
- Set the Prometheus server URL to
http://localhost:9090 - Scroll down and click Save & test
You should see the message “Successfully queried the Prometheus API.” If it fails, confirm Prometheus is running and that port 9090 is accessible from the Grafana host.
Step 5: Import Node Exporter Full Dashboard (ID 1860)
The Node Exporter Full dashboard (ID 1860) is a community-maintained Grafana dashboard that shows CPU, memory, disk, network, and dozens of other metrics from node_exporter.
- In Grafana, go to Dashboards > New > Import
- Enter dashboard ID 1860 and click Load
- Select the Prometheus data source from the dropdown
- Click Import
The dashboard loads with panels for CPU utilization, memory usage, disk I/O, network traffic, filesystem usage, and system load. Give node_exporter a few minutes to collect enough data points before the graphs start populating.
Step 6: Create Custom Grafana Panels
While imported dashboards are useful, production setups usually need custom panels tailored to your environment. Here is how to create a new dashboard with a few practical panels.
Create a New Dashboard
Go to Dashboards > New > New Dashboard, then click Add visualization. Select the Prometheus data source.
CPU Usage Panel
In the query editor, enter this PromQL expression to show overall CPU usage as a percentage.
100 - (avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
Set the panel title to “CPU Usage %” and choose Time series as the visualization type. Under the Axes settings, set the Y-axis unit to Percent (0-100).
Memory Usage Panel
Add another panel with this PromQL query.
(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100
Title it “Memory Usage %” and use the same time series visualization with a percent Y-axis.
Disk Usage Panel
This query shows filesystem usage for the root partition.
(1 - (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"})) * 100
Use a Gauge visualization for this one, with thresholds set to green below 70%, yellow from 70-85%, and red above 85%. Click Apply on each panel, then save the dashboard.
Step 7: Configure Prometheus Alerting Rules
Prometheus evaluates alerting rules at the interval defined in evaluation_interval. When a rule fires, Prometheus marks the alert as pending and then firing. Create a rules file with common alerts.
echo 'groups:
- name: node_alerts
rules:
- alert: HighCPUUsage
expr: 100 - (avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85
for: 5m
labels:
severity: warning
annotations:
summary: "High CPU usage on {{ $labels.instance }}"
description: "CPU usage is above 85% for more than 5 minutes."
- alert: HighMemoryUsage
expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 90
for: 5m
labels:
severity: critical
annotations:
summary: "High memory usage on {{ $labels.instance }}"
description: "Memory usage is above 90% for more than 5 minutes."
- alert: DiskSpaceLow
expr: (1 - (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"})) * 100 > 85
for: 10m
labels:
severity: warning
annotations:
summary: "Disk space low on {{ $labels.instance }}"
description: "Root filesystem usage is above 85%."
- alert: InstanceDown
expr: up == 0
for: 2m
labels:
severity: critical
annotations:
summary: "Instance {{ $labels.instance }} is down"
description: "Target has been unreachable for more than 2 minutes."' | sudo tee /etc/prometheus/alert_rules.yml
Set ownership and validate the rules file with promtool.
sudo chown prometheus:prometheus /etc/prometheus/alert_rules.yml
promtool check rules /etc/prometheus/alert_rules.yml
Expected output:
Checking /etc/prometheus/alert_rules.yml
SUCCESS: 4 rules found
Reload Prometheus to apply the rules.
sudo systemctl reload prometheus
Navigate to http://192.168.1.10:9090/alerts to see all configured alert rules and their current state.
Step 8: Grafana Provisioning via YAML
Grafana supports file-based provisioning for data sources and dashboards. This is useful when deploying Grafana across multiple servers or in infrastructure-as-code workflows – you define everything in YAML and Grafana picks it up on startup.
Provision the Prometheus Data Source
Create a provisioning file for the data source.
echo 'apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://localhost:9090
isDefault: true
editable: false' | sudo tee /etc/grafana/provisioning/datasources/prometheus.yml
Provision a Dashboard
Create the dashboard provider configuration.
echo 'apiVersion: 1
providers:
- name: "default"
orgId: 1
folder: "Provisioned"
type: file
disableDeletion: false
updateIntervalSeconds: 60
options:
path: /var/lib/grafana/dashboards
foldersFromFilesStructure: false' | sudo tee /etc/grafana/provisioning/dashboards/default.yml
Create the dashboards directory.
sudo mkdir -p /var/lib/grafana/dashboards
sudo chown grafana:grafana /var/lib/grafana/dashboards
You can export any dashboard as JSON from the Grafana UI (Dashboard > Share > Export) and place the JSON file in /var/lib/grafana/dashboards/. Grafana loads it automatically within 60 seconds.
Restart Grafana to apply the provisioning configuration.
sudo systemctl restart grafana-server
Log back into Grafana and confirm the Prometheus data source appears under Connections without needing manual setup.
Step 9: Set Up Nginx Reverse Proxy with SSL for Grafana
Running Grafana behind Nginx with TLS is the recommended production setup. It allows access over HTTPS on port 443 instead of exposing Grafana directly on port 3000.
Install Nginx and Certbot
sudo dnf install -y nginx
sudo dnf install -y certbot python3-certbot-nginx
Enable and start Nginx.
sudo systemctl enable --now nginx
Open HTTP and HTTPS ports in the firewall.
sudo firewall-cmd --add-service=http --permanent
sudo firewall-cmd --add-service=https --permanent
sudo firewall-cmd --reload
Configure Nginx Virtual Host
Create an Nginx configuration file for Grafana. Replace grafana.example.com with your actual domain.
echo 'server {
listen 80;
server_name grafana.example.com;
location / {
proxy_pass http://127.0.0.1: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;
}
# WebSocket support for Grafana Live
location /api/live/ {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}' | sudo tee /etc/nginx/conf.d/grafana.conf
Test the Nginx configuration and reload.
sudo nginx -t
sudo systemctl reload nginx
Obtain Let’s Encrypt SSL Certificate
Run Certbot to obtain and configure the SSL certificate automatically. Replace the domain and email with your own values.
sudo certbot --nginx -d grafana.example.com --non-interactive --agree-tos -m [email protected]
Certbot modifies the Nginx config to redirect HTTP to HTTPS and sets up the certificate paths. Verify the auto-renewal timer is active.
$ sudo certbot renew --dry-run
Congratulations, all simulated renewals succeeded
Update Grafana Configuration for Reverse Proxy
Edit the Grafana configuration to recognize the proxy.
sudo vi /etc/grafana/grafana.ini
Find and update the [server] section with these values.
[server]
domain = grafana.example.com
root_url = https://grafana.example.com/
serve_from_sub_path = false
Restart Grafana to apply the changes.
sudo systemctl restart grafana-server
Open https://grafana.example.com in your browser. You should see the Grafana login page served over HTTPS with a valid certificate. At this point, remove the direct port 3000 access from the firewall since all traffic should go through Nginx.
sudo firewall-cmd --remove-port=3000/tcp --permanent
sudo firewall-cmd --reload
Step 10: SELinux Configuration
Oracle Linux 9 and 10 ship with SELinux in enforcing mode. If Nginx cannot connect to Grafana’s backend port, SELinux is likely blocking it. Allow Nginx to make network connections.
sudo setsebool -P httpd_can_network_connect 1
Verify the boolean is set.
$ getsebool httpd_can_network_connect
httpd_can_network_connect --> on
This allows Nginx to proxy requests to Grafana and Prometheus without setting SELinux to permissive mode.
Conclusion
We now have a full Prometheus and Grafana monitoring stack running on Oracle Linux. Prometheus collects metrics from node_exporter and itself, alerting rules catch common failure conditions, and Grafana provides dashboards for visualization – all served through Nginx with TLS encryption.
For production environments, consider adding MySQL/MariaDB monitoring with Prometheus exporters, configuring Alertmanager for email or Slack notifications, enabling Grafana authentication via LDAP or OAuth, and setting up regular backups of /var/lib/prometheus and /var/lib/grafana.
Related Guides
- Monitor Linux Server using Prometheus and Grafana
- Monitor Apache with Prometheus and Grafana
- Monitor BIND DNS server with Prometheus and Grafana
- Configure Grafana behind Nginx and Apache Proxy
- Monitor Redis Server with Prometheus and Grafana

























































