One-click observability stack: Prometheus + node-exporter + cAdvisor + Grafana in a single host-networked Nomad job. Gives you host and per-container metrics (filling the cgroup-v2 per-alloc gap), with Grafana pre-wired to Prometheus.
Source β Project β β 66.2k
Save as values.hcl, edit, then run:
# The name of the Nomad job.
job_name = "monitoring"
# The Nomad namespace to deploy into.
namespace = "default"
# The datacenters to deploy to.
datacenters = ["*"]
# Prometheus image. Pin a tag in production.
prometheus_image = "prom/prometheus:latest"
# Grafana image.
grafana_image = "grafana/grafana:latest"
# Prometheus node-exporter image (host-level metrics).
node_exporter_image = "prom/node-exporter:latest"
# cAdvisor image (per-container metrics).
cadvisor_image = "gcr.io/cadvisor/cadvisor:latest"
# Host port for the Prometheus UI/API.
prometheus_port = 9090
# Host port for Grafana. Default 3001 to avoid clashing with the nomploy panel on :3000.
grafana_port = 3001
# Host port node-exporter listens on.
node_exporter_port = 9100
# Host port cAdvisor listens on. Default 8082 to avoid the common 8080 clash.
cadvisor_port = 8082
# Global Prometheus scrape interval.
scrape_interval = "15s"
# Prometheus TSDB retention (e.g. 15d, 30d, 90d).
retention = "15d"
# Optional extra scrape target for Nomad's own metrics, as host:port (e.g. "127.0.0.1:4646"). Requires Nomad telemetry with prometheus_metrics enabled. Empty = don't scrape Nomad.
nomad_metrics_url = ""
# Docker named volume for Prometheus TSDB (/prometheus). A fresh volume inherits the image's dir ownership (uid 65534) so Prometheus can write it.
prometheus_data_volume = "monitoring_prometheus_data"
# Run cAdvisor for per-container metrics. Set false if you only want host metrics, or if cAdvisor won't start on your kernel β Prometheus + node-exporter + Grafana still come up.
enable_cadvisor = true
# Initial Grafana admin username.
grafana_admin_user = "admin"
# Initial Grafana admin password. CHANGE THIS.
grafana_admin_password = "admin"
# Public URL Grafana is served at (set when fronting it with a domain). Empty = use host:port.
grafana_root_url = ""
# Docker named volume for /var/lib/grafana (SQLite DB, plugins; uid 472).
grafana_data_volume = "monitoring_grafana_data"
# Placement constraints β pin the job to one node so the Prometheus/Grafana local volumes stay put (single all-in-one alloc). Note: metrics reflect the node the alloc lands on. On a nomploy cluster: attribute = "$${meta.nomploy_control_plane}", operator = "=", value = "true".
constraints = []
# Resources for the Prometheus task.
prometheus_resources = {
cpu = 500
memory = 512
}
# Resources for the Grafana task.
grafana_resources = {
cpu = 500
memory = 512
}
# Resources for each exporter task (node-exporter, cAdvisor).
exporter_resources = {
cpu = 100
memory = 128
}
| Name | Type | Default | Description |
|---|---|---|---|
| job_name | string | "monitoring" | The name of the Nomad job. |
| namespace | string | "default" | The Nomad namespace to deploy into. |
| datacenters | list | ["*"] | The datacenters to deploy to. |
| prometheus_image | string | "prom/prometheus:latest" | Prometheus image. Pin a tag in production. |
| grafana_image | string | "grafana/grafana:latest" | Grafana image. |
| node_exporter_image | string | "prom/node-exporter:latest" | Prometheus node-exporter image (host-level metrics). |
| cadvisor_image | string | "gcr.io/cadvisor/cadvisor:latest" | cAdvisor image (per-container metrics). |
| prometheus_port | number | 9090 | Host port for the Prometheus UI/API. |
| grafana_port | number | 3001 | Host port for Grafana. Default 3001 to avoid clashing with the nomploy panel on :3000. |
| node_exporter_port | number | 9100 | Host port node-exporter listens on. |
| cadvisor_port | number | 8082 | Host port cAdvisor listens on. Default 8082 to avoid the common 8080 clash. |
| scrape_interval | string | "15s" | Global Prometheus scrape interval. |
| retention | string | "15d" | Prometheus TSDB retention (e.g. 15d, 30d, 90d). |
| nomad_metrics_url | string | "" | Optional extra scrape target for Nomad's own metrics, as host:port (e.g. "127.0.0.1:4646"). Requires Nomad telemetry with prometheus_metrics enabled. Empty = don't scrape Nomad. |
| prometheus_data_volume | string | "monitoring_prometheus_data" | Docker named volume for Prometheus TSDB (/prometheus). A fresh volume inherits the image's dir ownership (uid 65534) so Prometheus can write it. |
| enable_cadvisor | bool | true | Run cAdvisor for per-container metrics. Set false if you only want host metrics, or if cAdvisor won't start on your kernel β Prometheus + node-exporter + Grafana still come up. |
| grafana_admin_user | string | "admin" | Initial Grafana admin username. |
| grafana_admin_password key | string | "admin" | Initial Grafana admin password. CHANGE THIS. |
| grafana_root_url | string | "" | Public URL Grafana is served at (set when fronting it with a domain). Empty = use host:port. |
| grafana_data_volume | string | "monitoring_grafana_data" | Docker named volume for /var/lib/grafana (SQLite DB, plugins; uid 472). |
| constraints | list | [] | Placement constraints β pin the job to one node so the Prometheus/Grafana local volumes stay put (single all-in-one alloc). Note: metrics reflect the node the alloc lands on. On a nomploy cluster: attribute = "$${meta.nomploy_control_plane}", operator = "=", value = "true". |
| prometheus_resources | object | {
cpu = 500
memory = 512
} | Resources for the Prometheus task. |
| grafana_resources | object | {
cpu = 500
memory = 512
} | Resources for the Grafana task. |
| exporter_resources | object | {
cpu = 100
memory = 128
} | Resources for each exporter task (node-exporter, cAdvisor). |
No variables match.
One-click observability: Prometheus + node-exporter + cAdvisor + Grafana in a single host-networked Nomad job. You get host metrics (CPU/mem/disk/net) and per-container metrics β which is what fills the gap where Nomad's own per-alloc stats read all-zero on cgroup v2. Grafana comes pre-wired to Prometheus, so it works the moment it's up.
Everything shares the host network, so Prometheus scrapes the exporters on 127.0.0.1
and Grafana talks to Prometheus on 127.0.0.1. The whole stack runs unprivileged.
nomad-pack registry add nomploy github.com/Nomploy/nomad-packs
nomad-pack run monitoring --registry nomploy
In nomploy: create a Compose service, type Nomad Pack, pack monitoring, custom
registry github.com/Nomploy/nomad-packs, then Deploy.
http://<node-ip>:3001 (login admin / admin; Prometheus datasource
already provisioned). Import a dashboard to start: 1860 (Node Exporter Full),
14282 (cAdvisor).http://<node-ip>:9090. Check Status β Targets to confirm the
node, cadvisor (and optional nomad) scrapes are UP.:9100) and cAdvisor (:8082) β the scrape sources.| Variable | Default | Notes |
|---|---|---|
grafana_port / prometheus_port |
3001 / 9090 |
Grafana avoids the panel's :3000. |
node_exporter_port / cadvisor_port |
9100 / 8082 |
cAdvisor avoids the common :8080 clash. |
enable_cadvisor |
true |
Set false for host-only metrics, or if cAdvisor won't start. |
retention |
15d |
Prometheus TSDB retention. |
scrape_interval |
15s |
Global scrape interval. |
nomad_metrics_url |
"" |
Optional Nomad scrape target, e.g. 127.0.0.1:4646 (needs Nomad prometheus telemetry). |
grafana_admin_password |
admin |
Change this. |
*_data_volume |
monitoring_*_data |
Prometheus TSDB + Grafana state. Back up. |
constraints |
[] |
Pin to a node β metrics are for the node the alloc lands on. |
Per-task resources: prometheus_resources, grafana_resources, exporter_resources.
count is fixed to 1 with local volumes, so the metrics you see are
for the one node this alloc runs on. Pin it with constraints. To watch every node,
run node-exporter/cAdvisor per node and add them as scrape targets β a future
multi-node variant.--privileged. A few metrics
(e.g. perf events) need --device=/dev/kmsg/privileged; add them if you need those.nomad_metrics_url and enable Nomad's Prometheus telemetry
(telemetry { prometheus_metrics = true, publish_allocation_metrics = true }).