Guides / Monitoring

How to Install & Set Up Prometheus

Install Prometheus — the CNCF standard for pull-based metrics and alerting — scrape a real target with node_exporter, run your first PromQL queries, and wire up alerting rules.

Updated 20268-step setupDownload Prometheus →

Prerequisites

  • ✓A Linux host
  • ✓Targets that expose metrics on a /metrics endpoint — node_exporter (installed below) is the easiest first one

Why pull instead of push

Prometheus's defining design choice is that it scrapes — it periodically hits each target's HTTP /metrics endpoint and pulls the current values, rather than waiting for targets to push data in. That means any process you want monitored just needs to expose a metrics endpoint (either natively, or via a small exporter sitting in front of it); Prometheus's server handles scheduling, retries, and storage centrally.

Everything Prometheus collects lands in its own on-disk time series database, addressed by metric name plus a set of key/value labels — it's the label set, not a separate table per metric, that lets you slice cpu_usage by host, region, or environment in a single query.

Download and extract Prometheus

terminal
curl -LO https://github.com/prometheus/prometheus/releases/download/v2.53.0/prometheus-2.53.0.linux-amd64.tar.gz
tar xvfz prometheus-2.53.0.linux-amd64.tar.gz
cd prometheus-2.53.0.linux-amd64

Scrape a real target with node_exporter

Scraping Prometheus's own /metrics is a fine smoke test, but a genuinely useful first target is node_exporter, which exposes host-level metrics (CPU, memory, disk, network) for Prometheus to pull.

install and run node_exporter
curl -LO https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz
tar xvfz node_exporter-1.8.2.linux-amd64.tar.gz
./node_exporter-1.8.2.linux-amd64/node_exporter &
prometheus.yml
global:
  scrape_interval: 15s
scrape_configs:
  - job_name: "prometheus"
    static_configs:
      - targets: ["localhost:9090"]
  - job_name: "node"
    static_configs:
      - targets: ["localhost:9100"]

Run and verify

Open http://localhost:9090 and run a query such as 'up' in the expression browser — both jobs should show 1.

terminal
./prometheus --config.file=prometheus.yml

Run it as a systemd service (any distro)

Ctrl-C'ing a foreground process isn't how this survives a reboot. Move the binary and config into place under a dedicated user, then let systemd own the process — this works identically whether the host is RHEL-family or Debian-family, since it's systemd, not a distro package.

install as a service
sudo useradd --no-create-home --shell /usr/sbin/nologin prometheus
sudo mkdir -p /etc/prometheus /var/lib/prometheus
sudo mv prometheus.yml /etc/prometheus/
sudo mv prometheus promtool /usr/local/bin/
sudo chown -R prometheus:prometheus /var/lib/prometheus
/etc/systemd/system/prometheus.service
[Unit]
Description=Prometheus
After=network.target

[Service]
User=prometheus
ExecStart=/usr/local/bin/prometheus \
  --config.file=/etc/prometheus/prometheus.yml \
  --storage.tsdb.path=/var/lib/prometheus

[Install]
WantedBy=multi-user.target
enable and start
sudo systemctl daemon-reload
sudo systemctl enable --now prometheus

Build from source

Prometheus is a standard Go project with a Makefile, so building your own binary is the same handful of commands the release tarballs are themselves built from.

terminal
git clone https://github.com/prometheus/prometheus.git
cd prometheus
make build

A few real PromQL queries

  • •up — 1 for every target Prometheus successfully scraped on its last attempt, 0 for anything down. The first query to run when something's wrong.
  • •rate(node_cpu_seconds_total{mode="idle"}[5m]) — per-second average of a counter over the last 5 minutes; almost every 'how busy is X' question starts with rate() on a counter, never the raw counter value itself.
  • •node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes — a gauge ratio, no rate() needed since gauges are already instantaneous values.

Alerting rules

Prometheus evaluates alerting rules itself and forwards anything that fires to Alertmanager, a separate binary responsible for deduplication, grouping, and routing to email/Slack/PagerDuty — Prometheus never sends notifications directly.

alerts.yml
groups:
  - name: node
    rules:
      - alert: InstanceDown
        expr: up == 0
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "{{ $labels.instance }} has been down for 5+ minutes"
!

Reference the rules file with `rule_files: ["alerts.yml"]` in prometheus.yml, then point Alertmanager's address at `alerting.alertmanagers` in the same file.

Documentation & Knowledge Base

Official DocumentationPrometheus Documentation →Knowledge Base & CommunityPrometheus Community →
Download Prometheus— all versions & official links→

Related Guides

GrafanaInstall guide →VictoriaMetricsInstall guide →Grafana LokiInstall guide →

Need Prometheus deployed and managed for you?

We're OpenStack Dev — we design, deploy, and operate production DevOps infrastructure.

Get in TouchAll Install Guides