Docker Compose quickstart¶
A one-command demo stack: the exporter, Prometheus (with starter alert rules), and Grafana (with the datasource and dashboards auto-provisioned).
Run it¶
# One BMC (build the image locally):
IDRAC1_HOST=10.0.0.10 IDRAC1_USERNAME=monitor IDRAC1_PASSWORD='secret' docker compose up -d
# Two BMCs — the stack runs in scrape-all mode and shows both on the dashboards.
# Host 2 reuses host 1's credentials unless you set IDRAC2_USERNAME/IDRAC2_PASSWORD:
IDRAC1_HOST=10.0.0.10 IDRAC2_HOST=10.0.0.11 \
IDRAC1_USERNAME=monitor IDRAC1_PASSWORD='secret' docker compose up -d
Or copy .env.example to .env, fill it in, and just docker compose up -d (compose reads
.env natively; it is gitignored).
| Service | URL | Notes |
|---|---|---|
| Grafana | http://localhost:3000 | admin / admin (or GF_SECURITY_ADMIN_PASSWORD) |
| Prometheus | http://localhost:9090 | scrape + alert rules |
| Exporter | http://localhost:9348/metrics | needs a reachable BMC |
To run the published image instead of building locally:
IDRAC1_PASSWORD='secret' docker compose -f docker-compose.ghcr.yml up -d
# pin a version: IDRAC_TAG=2.6.1 docker compose -f docker-compose.ghcr.yml up -d
How it is wired¶
config.yamlis the source of truth. It leavesdefault_targetempty and lists the BMCs underhosts:with env-expanded keys (${IDRAC1_HOST},${IDRAC2_HOST}) and their${IDRAC*_USERNAME}/${IDRAC*_PASSWORD}credentials, expanded at load time. The compose file passes those variables in..envis nice;config.yamlis the way.- Because
default_targetis empty, a bareidrac_exporter:9348/metricsruns scrape-all: the exporter collects every host underhosts:in one response, each series labeledinstance="<bmc>"andsystem="<bmc>", plus a per-hostidrac_upgauge (0for an unreachable BMC — one bad host never fails the scrape). Prometheus scrapes that single URL withhonor_labels: trueso those labels survive. - Prefer per-target scraping? Set a single host in
default_target, or use the multi-target relabel pattern (commented inprometheus.ymland the README), one entry per BMC. - BMC Redfish scrapes are slow, so
scrape_interval/scrape_timeoutdefault to 60s/55s — tune them for your hardware.
The system label¶
All dashboards use a single system template variable to identify the target host.
How it is populated depends on the export path:
- Scrape-all quickstart (default): the exporter injects
instance="<bmc>"andsystem="<bmc>"on every series of a bare/metrics, andprometheus.ymlscrapes it withhonor_labels: trueso those labels are kept as-is:
- job_name: idrac
honor_labels: true
static_configs:
- targets: ["idrac_exporter:9348"]
- Multi-target fleet (scrape path): set
systemper BMC via a relabel rule that copies the?target=parameter:
- source_labels: [__param_target]
target_label: system
- OTLP/snapshot push path: the exporter injects
systemitself — no Prometheus relabel needed. The label key is configurable viaotlp.identity_label(defaultsystem), so the same dashboards work for both paths without modification.
Notes¶
- The exporter container runs as a non-root user (uid 10001).
- Grafana provisioning lives in
grafana/provisioning/; the bundled dashboards (including the PDU dashboard) are auto-provisioned and mounted read-only — see Dashboards. - A reachable BMC is required for metrics to appear. Without one, the stack still starts and provisions cleanly (datasource green, all dashboards loaded, alert rules parsed), but BMC-dependent panels will be empty and the exporter target will show as down in Prometheus.