Grafana: Dashboards & visualization
|
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 stores and evaluates time series; it does not itself build dashboards — the expression browser’s Graph tab is deliberately minimal, meant for ad-hoc queries rather than a shared operational view. Grafana is the visualization layer almost every Prometheus deployment sits behind: it queries Prometheus (and other backends) over HTTP, arranges the results into panels on a dashboard, and lets those dashboards be parameterized and shared. This page covers installing Grafana, connecting it to a Prometheus server, the panel types a dashboard is built from, and template variables that make one dashboard work across many jobs or instances.
Installing Grafana
Grafana ships as a binary package, a Docker image, or an OS package, and always listens on :3000
with a default admin/admin login that it forces you to change on first sign-in. See
Install Grafana for every
installation method and platform in full, including the Windows and macOS installers not shown
here.
Docker
The official image is published as grafana/grafana-oss (open-source edition) on Docker Hub. Publish
port 3000 and bind-mount a volume so dashboards and users survive a container restart:
docker run -d --name grafana -p 3000:3000 \
-v grafana-storage:/var/lib/grafana \
grafana/grafana-oss
# http://localhost:3000, default login admin/admin
# https://grafana.com/docs/grafana/latest/setup-grafana/installation/
Package manager / binary
On Debian/Ubuntu, Grafana’s own APT repository installs and manages the service:
sudo apt-get install -y apt-transport-https software-properties-common
sudo mkdir -p /etc/apt/keyrings/
wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/grafana.gpg > /dev/null
echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" | sudo tee /etc/apt/sources.list.d/grafana.list
sudo apt-get update && sudo apt-get install -y grafana
sudo systemctl enable --now grafana-server
# https://grafana.com/docs/grafana/latest/setup-grafana/installation/
The standalone binary archive (no root, no service manager) works the same way as Prometheus’s own
tarball install described in
Getting Started: extract it and run ./bin/grafana
server from the extracted directory. Whichever method is used, the first sign-in at
http://localhost:3000 prompts for a new admin password before anything else is usable.
Adding the Prometheus data source
A data source tells Grafana where to send queries. Prometheus is a first-class data source type — its query editor understands PromQL directly, including autocomplete against the metrics and labels the target server actually has. See Prometheus data source for every configuration field.
Via the UI
Connections > Data sources > Add data source > Prometheus, then set the Prometheus server URL
(http://localhost:9090 for a local server, or the in-cluster service DNS name when both run in
Kubernetes) and Save & test. Grafana confirms the connection by querying the target’s /api/v1/query
endpoint before saving.
Via provisioning
Clicking through the UI does not survive a redeployed container or a fresh environment. Grafana reads
any YAML file dropped into provisioning/datasources/ at startup and creates or updates data sources
from it — the infrastructure-as-code equivalent of the UI form above:
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
jsonData:
httpMethod: POST
timeInterval: 15s
# https://grafana.com/docs/grafana/latest/datasources/prometheus/
access: proxy routes the browser’s query through the Grafana server rather than calling Prometheus
directly from the client — the setting almost every deployment wants. Mount this file at
/etc/grafana/provisioning/datasources/prometheus.yaml in the Docker image above (or the
Kubernetes-native equivalent, a ConfigMap) and it is present on every container start with no
manual step; dashboards can be provisioned the same way, covered next.
Dashboards and panel types
A dashboard is a grid of panels, each running its own query (or queries) against a data source and rendering the result with a chosen visualization. See Dashboards for creating, organizing, and sharing them, and Panels & visualizations for the full visualization catalog beyond the five below.
| Panel type | When to use it |
|---|---|
Time series |
The default choice for anything with a meaningful time axis — request rate, latency, memory over time. Plots one or more series as lines or bars against wall-clock time; the panel most Prometheus dashboards are built from. |
Stat |
A single current number, optionally with a sparkline and threshold-driven color — "requests per second right now," "error rate this hour." Reduces a query down to one value per series rather than plotting a time axis. |
Gauge |
The same single-value reduction as Stat, drawn as an arc against a min/max range — best when the position within a bounded range matters more than the raw number, such as disk usage approaching 100%. |
Table |
Tabular results — one row per label combination, one column per field — for browsing raw series values or an instant-vector query’s full label set rather than a trend. |
Bar gauge |
Like Gauge but one bar per series instead of one arc for the whole panel — comparing a bounded value (queue depth against a configured max, disk usage) across many instances or jobs at once. |
Panels compose into a dashboard through Grafana’s own editor — drag to resize, add a panel, pick its
visualization and query — but every dashboard is, underneath, one JSON document (the dashboard
model): panels, their queries, layout, and variables as a single serializable object. Building
through the UI and hand-editing (or generating) that JSON are two views of the same thing, and both
remain fully compatible — a dashboard built by hand can be exported to JSON for version control, and
a JSON file authored or generated elsewhere (a provisioning pipeline, a dashboard shared from
Grafana’s public dashboard library) imports and edits in the
UI exactly like one built there from scratch. Provisioning dashboards from files works the same way as
the data source YAML above, via provisioning/dashboards/ pointing at a directory of these JSON
files, so a dashboard ships with its data source rather than being recreated by hand in each
environment.
Template variables
A dashboard hard-coded to one job or instance only ever shows that one target. A template
variable turns part of a panel’s query into a dropdown the viewer picks from, so one dashboard serves
every job, instance, or namespace scraped by Prometheus. See
Variables for every variable type
beyond the query-backed one below.
A query-type variable, backed by Prometheus’s label_values() helper, lists every distinct value a
label takes across a metric (or across the whole TSDB, if the metric argument is omitted):
label_values(up, instance)
Define instance as a dashboard variable with that query, enable Multi-value and Include All if
every target should be selectable at once, and reference it from a panel’s PromQL with $instance
(or ${instance} where the surrounding syntax needs braces):
up{instance=~"$instance"}
=~ is required, not =, because a multi-value selection expands to a regex alternation
("web-1|web-2") rather than a single string — the same regex matcher covered in
PromQL: Basics & Selectors. Variables can
also chain: a job variable’s label_values() query can itself be scoped so a dependent instance
variable only lists instances belonging to the currently selected job, keeping large multi-team
dashboards navigable instead of listing every instance in the cluster at once.
Continue with Grafana Alerting for alerting rules defined and evaluated inside Grafana itself, as distinct from the Prometheus-side rules covered in Recording & Alerting Rules and routed by Alertmanager.
For Grafana dashboards of Apache JMeter load-test metrics next to these server metrics, see Real-time Monitoring with Backend Listener.