Skip to main content
Version: Unreleased

Node Exporter Sidecar

The prom/node-exporter sidecar collects host-level metrics — CPU, memory, disk, and network — from the physical machine running your FRAFOS Monitor stack. These metrics are exposed at :9100/metrics and scraped by Prometheus for dashboards and alerting.

What you get

This sidecar measures the underlying host resources, not the application itself. While Monitor dashboards show SBC-level data (calls, registrations, SIP transactions), node-exporter shows whether the host has enough CPU, RAM, or disk to keep those services running.

What it monitors

ResourceKey MetricsExample Use Cases
CPUnode_cpu_seconds_total, node_load1/5/15Spikes, sustained load, capacity
Memorynode_memory_MemTotal_bytes, node_memory_MemAvailable_bytesOOM risk, cache pressure
Disknode_filesystem_avail_bytes, node_filesystem_size_bytesFS fills, partition sizing
Networknode_network_receive_bytes_total, node_network_transmit_bytes_totalTraffic, drops, interface-level debugging

Deployment model: one per physical host

Deploy exactly one node-exporter sidecar per physical host — regardless of how many SBC/CCM/monitoring containers are running on that machine.

Your setupSidecars needed
SBC + CCM + Monitor all on one physical host1 sidecar
SBC on Host A, CCM on Host B, Monitor on Host A2 sidecars (one per physical host)
10 SBCs on a single physical host1 sidecar

Each sidecar only knows about its own physical host. Prometheus must discover and scrape each endpoint independently. There is no clustering, aggregation, or shared state between sidecars.

Architecture

Physical host requirement

node-exporter measures the resources of the physical host (CPU, RAM, disk, network interfaces). It must be deployed on the physical server — not inside a Docker container that runs on top of it.

If your VOIP cluster spans 2 physical hosts, you must deploy 2 sidecars — one per physical host, each monitoring its own underlying hardware.

Deployment topology

The diagram below shows a two-physical-host deployment. Each physical server runs its own node-exporter sidecar that Prometheus scrapes on port 9100. Containers (SBC, CCM, Monitor) on the same host share that host's sidecar — there is one sidecar per physical host, not per container.

note

One sidecar per physical host — whether that host runs 1 SBC or 10 SBCs, it needs only one node-exporter. Prometheus scrapes each host on port 9100 independently.

Metrics data flow

Docker Compose

note

The container mount /:/hostfs:ro,rslave and privileged: true are required. The privileged flag gives access to kernel-level counters; rslave propagation makes sub-mounts (e.g. /var/lib/docker/overlay) visible inside the container.

docker-compose.yml
node-exporter:
image: prom/node-exporter:v1.11.1
container_name: node-exporter
network_mode: host # or bridge + ports: "9100:9100"
privileged: true
command: ["--path.rootfs=/hostfs"]
volumes:
- /:/hostfs:ro,rslave
profiles:
- monitoring

Host networking (production)

Use network_mode: host to bind :9100 directly on the host's IP. No port mapping needed.

Bridge networking (development)

Replace network_mode: host with a port mapping for access from localhost:

# instead of: network_mode: host
ports:
- "9100:9100"
networks:
- monitoring

Host mount propagation

The bind mount /:/hostfs:ro (Docker) or hostPath (K8s HostToContainer) exposes the host's entire filesystem tree to the container. For sub-mounts (e.g. /data, /var/lib/docker/overlay) to be visible, the host root mount must have shared propagation.

systemd-based Linux

sudo mount --make-rshared /

Validation

Verify the sidecar is healthy with a single command:

The Compose YAML also works with Podman via podman-compose. Bring up the single sidecar and verify:

# From the Compose project root:
podman-compose up -d node-exporter
sleep 5 && curl -s http://localhost:9100/metrics | head -5

Expected output:

# HELP node_load1 1m load average.
# TYPE node_load1 gauge
node_load1 0.91

A healthy deployment returns HTTP 200 with metric data and no errors in logs.

Prometheus scrape config

The node-exporter targets are not manually configured in prometheus.yml. Instead, Prometheus discovers all monitored hosts automatically via HTTP Service Discovery (http_sd_config) pointing to the Monitor application — the same application that manages the list of monitored SBC/CCM endpoints.

How it works

  1. The Monitor application maintains a registry of all monitored physical hosts — this is the single source of truth.
  2. Prometheus is configured to poll the Monitor's service-discovery endpoint on a regular interval (e.g., every 30 seconds).
  3. The Monitor returns the list of hosts running node-exporter sidecars along with their scrape targets.
  4. Prometheus auto-configures scrape jobs for each discovered host — no prometheus.yml changes needed.

When a new physical host is added as a monitored node in the Monitor app, its node-exporter endpoint is automatically discovered. When it's removed, the scrape target is cleaned up automatically.

Prometheus configuration

The prometheus.yml file bundled with the server deployment uses HTTP service discovery to query the Monitor:

global:
scrape_interval: 15s
evaluation_interval: 15s

scrape_configs:
# Discover all monitored hosts (including node-exporter targets) via the Monitor
- job_name: "monitored-hosts"
http_sd_configs:
- url: "http://server:5000/api/prometheus/targets"
refresh_interval: 30s

The Monitor application is responsible for:

  • Maintaining the list of monitored hosts
  • Returning node-exporter scrape targets for each host
  • Providing labels (host-name, env, region, etc.) for Prometheus metric correlation

Deployment reference

For a detailed reference configuration, see the Prometheus configuration file that is included with the server deployment. The prometheus service definition in the Docker Compose files mounts this configuration into the Prometheus container.

Troubleshooting

Issues with the sidecar are covered in the Node Exporter Sidecar Troubleshooting guide.