Installing & running Prometheus
|
This section documents the current Prometheus 3.x line (latest 3.14.0) as published at the Prometheus documentation and the current Grafana 13.x line (latest 13.2.1) as published at the Grafana documentation, which are the references these pages are written and verified against. No specific patch version is pinned. Some capabilities (Grafana Enterprise-only features, Grafana Cloud-hosted services, and long-term-storage systems like Thanos/Cortex/Mimir) are linked, not documented in depth. This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production, since both projects iterate quickly. This section’s bibliography lists the reference material consulted while preparing these pages. |
Prometheus is a single self-contained binary: no external database, no cluster to stand up before it
scrapes its first target. This page covers getting that binary (or its Docker image) running, the
minimal prometheus.yml it needs, the built-in expression browser used to sanity-check what it has
collected, adding node_exporter as a real scrape target, and writing a first alerting rule.
Installing Prometheus
The binary tarball
Prometheus ships as a single statically linked binary plus a default config file, packaged per OS/ architecture on the downloads page. No package manager or root install is required:
tar xvfz prometheus-*.tar.gz
cd prometheus-*/
./prometheus --config.file=prometheus.yml
# https://prometheus.io/docs/prometheus/latest/installation/
The extracted directory contains the prometheus server binary, the promtool binary (used to check
and unit-test config and rule files), a default prometheus.yml, and a console_libraries/
consoles pair used by the (largely superseded) console templates feature. By default the server
listens on port 9090 and writes its time-series database under ./data.
Docker
The official image is published as prom/prometheus on Docker Hub. Bind-mount a config file over the
image’s default one and publish port 9090:
docker run -d --name prometheus -p 9090:9090 \
-v "$PWD/prometheus.yml:/etc/prometheus/prometheus.yml" \
prom/prometheus
# https://prometheus.io/docs/prometheus/latest/installation/
The container’s entrypoint already points --config.file at /etc/prometheus/prometheus.yml, so the
bind-mounted file is picked up on start. For anything beyond a single local instance — persistent
volumes, resource limits, TLS — see
Containers & Kubernetes Monitoring; for the
docker run and bind-mount options themselves, see Running Containers.
A first prometheus.yml
Configuration is a single YAML file, reloadable without a restart via SIGHUP or the /-/reload
HTTP endpoint (when --web.enable-lifecycle is set). The minimal skeleton scrapes Prometheus itself:
global:
scrape_interval: 15s # how often to scrape targets by default
evaluation_interval: 15s # how often to evaluate rules
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"]
# https://prometheus.io/docs/prometheus/latest/getting_started/
Every entry under scrape_configs is a job: a named group of one or more targets scraped with the
same interval, timeout, and metric relabeling rules. static_configs is the simplest way to list
targets by hand; real deployments usually discover them dynamically instead, which is covered in
Service Discovery & Relabeling. For
the config file’s full syntax and every scrape/global option, see
Getting started and validate a file
before pointing the server at it:
promtool check config prometheus.yml
The expression browser
Once the server is running, http://localhost:9090 serves the built-in web UI — the expression
browser. Its Graph tab runs an ad-hoc PromQL query against the local TSDB and renders it as a
table or a chart; a first useful query is the up metric that Prometheus attaches to every scrape:
up
up is 1 when the most recent scrape of that target succeeded and 0 otherwise, labeled with the
target’s job and instance — it is the single most useful metric for "is anything broken" and is
the basis of the alerting rule below. The UI also exposes Status > Targets (per-job scrape health
and the last error, if any), Status > Configuration (the effective, fully-resolved YAML currently
loaded), and Status > Rules (recording and alerting rules with their current state). See
First steps for a guided tour of these pages,
and PromQL: Basics & Selectors for how to
read and write queries like the one above.
Running node_exporter and scraping it
node_exporter exposes host-level metrics — CPU, memory, disk, network — as a /metrics HTTP
endpoint that Prometheus scrapes like any other target. It ships as its own binary, separate from the
Prometheus server, and needs no configuration to start:
tar xvfz node_exporter-*.tar.gz
cd node_exporter-*/
./node_exporter
# listens on :9100/metrics by default
Add it as a second job in prometheus.yml and reload the server:
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"]
- job_name: "node"
static_configs:
- targets: ["localhost:9100"]
# https://prometheus.io/docs/prometheus/latest/getting_started/
After the next scrape interval, up{job="node"} should read 1 in the expression browser, and
metrics such as node_cpu_seconds_total or node_memory_MemAvailable_bytes become queryable.
node_exporter is one of many first-party and community exporters that adapt a system that does
not natively speak Prometheus’s format; the general pattern, and the Pushgateway for short-lived
batch jobs, is covered in
Exporters & the Pushgateway.
A first alerting rule
Alerting rules live in separate YAML files, referenced from prometheus.yml via rule_files, and
are evaluated by the Prometheus server itself on evaluation_interval — not by Alertmanager, which
only receives and routes alerts that already fired. Point at a rules file:
rule_files:
- "alert_rules.yml"
# https://prometheus.io/docs/prometheus/latest/getting_started/
A minimal rule that fires when a target has been unreachable for five straight minutes:
groups:
- name: example
rules:
- alert: InstanceDown
expr: up == 0
for: 5m
labels:
severity: critical
annotations:
summary: "Instance {{ $labels.instance }} down"
description: "{{ $labels.instance }} (job {{ $labels.job }}) has been down for 5 minutes."
for: 5m requires the up == 0 condition to hold continuously across evaluations before the alert
leaves the pending state and becomes firing — it exists specifically to avoid paging on a single
missed scrape. A firing rule shows up under Status > Rules and Alerts in the expression browser
immediately, whether or not Alertmanager is configured to receive it. Validate the rules file the
same way as the main config:
promtool check rules alert_rules.yml
Writing rules well — naming conventions, recording rules for expensive expressions, and multi-window alerting patterns — is covered in Recording & Alerting Rules; routing a firing alert to email/Slack/PagerDuty is Alertmanager's job, not the Prometheus server’s.
Continue with Architecture & Ecosystem for
how the server, exporters, and Alertmanager fit together, and
Data Model & Metric Types for what a
metric like up or node_cpu_seconds_total actually is under the hood.