Prometheus is an open-source monitoring and alerting toolkit that collects metrics from configured targets at given intervals, evaluates rule expressions, and triggers alerts when conditions are met. Combined with Grafana for visualization, it forms one of the most widely deployed monitoring stacks in production Linux environments.
This guide walks through installing and configuring a complete Prometheus + Grafana monitoring stack on Rocky Linux 10, AlmaLinux 10, or RHEL 10. We cover Prometheus server setup, Node Exporter for system metrics, Grafana installation from the official repository, and connecting Grafana to Prometheus as a data source. For a deeper dive into Node Exporter configuration and custom collectors, see the dedicated Prometheus and Node Exporter guide.
Prerequisites
- A server running Rocky Linux 10, AlmaLinux 10, or RHEL 10
- Root or sudo access
- At least 2 GB RAM and 2 CPU cores
- Ports 9090 (Prometheus), 9100 (Node Exporter), and 3000 (Grafana) available
- Internet access to download packages
Switch to root for the rest of this guide:
sudo -i
Step 1: Install Prometheus on Rocky Linux 10 / AlmaLinux 10
Prometheus is not available in the default RHEL repositories. Download the latest stable release directly from the Prometheus GitHub releases page.
Create Prometheus system user and directories
Create a dedicated prometheus system user with no login shell and no home directory. This user owns all Prometheus files and runs the service.
groupadd --system prometheus
useradd -s /sbin/nologin --system -g prometheus prometheus
Create directories for Prometheus configuration and time-series data storage:
mkdir -p /etc/prometheus /var/lib/prometheus
Download and extract Prometheus
Download Prometheus 3.10.0 (latest stable at the time of writing):
cd /tmp
curl -LO https://github.com/prometheus/prometheus/releases/download/v3.10.0/prometheus-3.10.0.linux-amd64.tar.gz
Extract the archive and move the binaries into place:
tar xvf prometheus-3.10.0.linux-amd64.tar.gz
cd prometheus-3.10.0.linux-amd64
cp prometheus promtool /usr/local/bin/
cp -r consoles console_libraries /etc/prometheus/
Configure Prometheus
Create the main Prometheus configuration file. This basic configuration sets a 15-second scrape interval and defines two targets – Prometheus itself and a Node Exporter instance running on the same host.
vi /etc/prometheus/prometheus.yml
Add the following configuration:
global:
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"]
Set ownership on all Prometheus directories and files:
chown -R prometheus:prometheus /etc/prometheus /var/lib/prometheus
chown prometheus:prometheus /usr/local/bin/{prometheus,promtool}
Create Prometheus systemd service
Create a systemd unit file so Prometheus starts on boot and can be managed with systemctl.
vi /etc/systemd/system/prometheus.service
Add the following service definition:
[Unit]
Description=Prometheus Monitoring System
Documentation=https://prometheus.io/docs/introduction/overview/
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 \
--web.listen-address=0.0.0.0:9090
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target
Reload systemd, enable, and start Prometheus:
systemctl daemon-reload
systemctl enable --now prometheus
Verify Prometheus is running with no errors:
systemctl status prometheus
The service should show active (running) with no error messages in the log output:
● prometheus.service - Prometheus Monitoring System
Loaded: loaded (/etc/systemd/system/prometheus.service; enabled; preset: disabled)
Active: active (running) since Fri 2026-03-21 10:15:32 UTC; 5s ago
Docs: https://prometheus.io/docs/introduction/overview/
Main PID: 12345 (prometheus)
Tasks: 8 (limit: 23129)
Memory: 42.0M
CPU: 1.234s
CGroup: /system.slice/prometheus.service
└─12345 /usr/local/bin/prometheus --config.file=/etc/prometheus/prometheus.yml
Step 2: Install Node Exporter
Node Exporter exposes hardware and OS-level metrics (CPU, memory, disk, network) that Prometheus scrapes. Download the latest release from GitHub.
Create Node Exporter user and install binaries
useradd -s /sbin/nologin --system node_exporter
Download and extract Node Exporter 1.10.2:
cd /tmp
curl -LO https://github.com/prometheus/node_exporter/releases/download/v1.10.2/node_exporter-1.10.2.linux-amd64.tar.gz
tar xvf node_exporter-1.10.2.linux-amd64.tar.gz
cp node_exporter-1.10.2.linux-amd64/node_exporter /usr/local/bin/
chown node_exporter:node_exporter /usr/local/bin/node_exporter
Create Node Exporter systemd service
vi /etc/systemd/system/node_exporter.service
Add the following unit file:
[Unit]
Description=Prometheus Node Exporter
Documentation=https://github.com/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
RestartSec=5s
[Install]
WantedBy=multi-user.target
Enable and start Node Exporter:
systemctl daemon-reload
systemctl enable --now node_exporter
Confirm the service is active:
systemctl status node_exporter
You should see active (running) confirming Node Exporter is serving metrics on port 9100:
● node_exporter.service - Prometheus Node Exporter
Loaded: loaded (/etc/systemd/system/node_exporter.service; enabled; preset: disabled)
Active: active (running) since Fri 2026-03-21 10:16:45 UTC; 3s ago
Docs: https://github.com/prometheus/node_exporter
Main PID: 12400 (node_exporter)
Tasks: 5 (limit: 23129)
Memory: 12.5M
CPU: 0.089s
CGroup: /system.slice/node_exporter.service
└─12400 /usr/local/bin/node_exporter
For advanced Node Exporter configuration including custom collectors and textfile metrics, refer to our dedicated guide covering those topics in depth.
Step 3: Configure Firewall Rules
Open the required ports in firewalld so Prometheus, Node Exporter, and Grafana are accessible over the network.
firewall-cmd --permanent --add-port=9090/tcp
firewall-cmd --permanent --add-port=9100/tcp
firewall-cmd --permanent --add-port=3000/tcp
firewall-cmd --reload
Verify the ports are open:
firewall-cmd --list-ports
The output should list all three ports:
9090/tcp 9100/tcp 3000/tcp
Step 4: Configure SELinux for Prometheus and Grafana
On RHEL-based systems with SELinux enforcing, Prometheus and Node Exporter binaries installed outside standard paths need permission to bind to their network ports and access their data directories.
Allow Prometheus and Node Exporter to bind to their respective ports:
dnf install -y policycoreutils-python-utils
semanage port -a -t http_port_t -p tcp 9090
semanage port -a -t http_port_t -p tcp 9100
If the ports are already defined, use -m (modify) instead of -a (add). Label the Prometheus data directory so SELinux allows write access:
semanage fcontext -a -t prometheus_var_lib_t "/var/lib/prometheus(/.*)?"
restorecon -Rv /var/lib/prometheus
If you encounter SELinux denials after starting the services, check the audit log and generate a custom policy:
ausearch -m avc -ts recent | audit2allow -M prometheus_custom
semodule -i prometheus_custom.pp
Grafana installs from an RPM package, so its SELinux contexts are set automatically during installation.
Step 5: Verify Prometheus Targets
Before installing Grafana, confirm Prometheus is scraping both targets. Open http://your-server-ip:9090 in a browser and navigate to Status > Targets. Both the prometheus and node_exporter jobs should show a State of UP.
You can also verify from the command line:
curl -s http://localhost:9090/api/v1/targets | python3 -m json.tool | grep -A2 '"health"'
Both targets should report health status as “up”:
"health": "up",
--
"health": "up",
Step 6: Install Grafana on Rocky Linux 10 / AlmaLinux 10
Grafana provides an official RPM repository for RHEL-based distributions. This installs the latest stable Grafana OSS release (12.4.x at the time of writing).
Add the Grafana repository
vi /etc/yum.repos.d/grafana.repo
Add the following repository configuration:
[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
Install and start Grafana
Import the GPG key and install Grafana:
wget -q -O gpg.key https://rpm.grafana.com/gpg.key
rpm --import gpg.key
dnf install -y grafana
Enable and start the Grafana service:
systemctl enable --now grafana-server
Confirm Grafana is running:
systemctl status grafana-server
The output should show the service active and listening on port 3000:
● grafana-server.service - Grafana instance
Loaded: loaded (/usr/lib/systemd/system/grafana-server.service; enabled; preset: disabled)
Active: active (running) since Fri 2026-03-21 10:20:15 UTC; 4s ago
Docs: http://docs.grafana.org
Main PID: 12550 (grafana)
Tasks: 11 (limit: 23129)
Memory: 85.0M
CPU: 2.345s
CGroup: /system.slice/grafana-server.service
└─12550 /usr/share/grafana/bin/grafana server --config=/etc/grafana/grafana.ini
Step 7: Configure Grafana Data Source for Prometheus
Open Grafana in your browser at http://your-server-ip:3000. The default login credentials are admin / admin. Grafana prompts you to set a new password on first login – do that before proceeding.
Add Prometheus as a data source
You can add the Prometheus data source through the Grafana UI or via the command line. To configure it from the CLI using Grafana’s provisioning system:
vi /etc/grafana/provisioning/datasources/prometheus.yaml
Add the following data source configuration:
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://localhost:9090
isDefault: true
editable: true
Restart Grafana to pick up the new data source:
systemctl restart grafana-server
Alternatively, add it through the Grafana web interface: go to Connections > Data Sources > Add data source > select Prometheus > set the URL to http://localhost:9090 > click Save & Test. A green “Successfully queried the Prometheus API” message confirms the connection works.
Import a Node Exporter dashboard
Grafana has hundreds of pre-built dashboards. To get immediate visibility into your server metrics, import the popular “Node Exporter Full” dashboard.
In Grafana, go to Dashboards > New > Import. Enter dashboard ID 1860 and click Load. Select the Prometheus data source you just created and click Import. You should immediately see CPU, memory, disk, and network graphs populated with data from Node Exporter.
Step 8: Add Remote Hosts to Prometheus Monitoring
To monitor additional servers, install Node Exporter on each remote host and add them as targets in prometheus.yml. On each remote server, follow the Node Exporter installation steps from Step 2, then update the Prometheus configuration on the monitoring server.
vi /etc/prometheus/prometheus.yml
Add remote hosts under the node_exporter job targets:
- job_name: "node_exporter"
static_configs:
- targets:
- "localhost:9100"
- "192.168.1.10:9100"
- "192.168.1.11:9100"
- "192.168.1.12:9100"
Reload Prometheus to apply the new configuration without restarting the service:
systemctl reload prometheus
Check the Targets page in Prometheus UI to confirm all new hosts show a State of UP. Make sure port 9100 is open in the firewall on each remote host. Beyond basic system metrics, you can monitor MySQL and MariaDB databases with Prometheus using dedicated exporters.
Port Reference
| Service | Port | Protocol |
|---|---|---|
| Prometheus | 9090 | TCP |
| Node Exporter | 9100 | TCP |
| Grafana | 3000 | TCP |
Conclusion
You now have a working Prometheus + Grafana monitoring stack on Rocky Linux 10 / AlmaLinux 10 with Node Exporter collecting system metrics. Prometheus scrapes and stores time-series data while Grafana provides dashboards and alerting on top of it.
For production environments, consider enabling HTTPS on Grafana with a reverse proxy, setting up Prometheus alerting rules with Alertmanager, configuring retention policies for long-term storage, and implementing authentication on the Prometheus endpoint. See the official Prometheus documentation for the full configuration reference.