Collecting Host Metrics with node_exporter

Install node_exporter on your server to expose CPU, memory, disk, and network metrics for Prometheus to scrape.

When you want to know how busy your VPS really is, how much disk is left, or whether memory is about to run out, SSHing in to run top over and over doesn't scale. nodeexporter is the Prometheus project's official collector for Linux hosts. It reads hardware and kernel metrics (CPU, memory, disk, filesystem, network, load average, and more) and exposes them over HTTP in the text format Prometheus understands. It is read-only, touches nothing on your system, and uses almost no resources, which makes it the natural first building block for host monitoring.

This guide targets Ubuntu / Debian and walks you through it from scratch.

1. Download and install the binary

nodeexporter ships as a single static binary with no dependencies, so you just download and unpack it. Grab the build for your architecture (usually linux-amd64) from the official Releases page:

# Replace the version with the latest release from the project's page
VER=1.8.2
cd /tmp
curl -fsSLO https://github.com/prometheus/node_exporter/releases/download/v${VER}/node_exporter-${VER}.linux-amd64.tar.gz
tar xzf node_exporter-${VER}.linux-amd64.tar.gz
sudo cp node_exporter-${VER}.linux-amd64/node_exporter /usr/local/bin/

Run it under a dedicated, no-login system account to shrink the attack surface:

sudo useradd --no-create-home --shell /usr/sbin/nologin node_exporter

2. Run it as a systemd service

Create /etc/systemd/system/nodeexporter.service:

[Unit]
Description=Prometheus node_exporter
After=network.target

[Service]
User=node_exporter
Group=node_exporter
ExecStart=/usr/local/bin/node_exporter --web.listen-address=127.0.0.1:9100
Restart=on-failure

[Install]
WantedBy=multi-user.target

Enable and start it:

sudo systemctl daemon-reload
sudo systemctl enable --now node_exporter

Confirm it is listening on port 9100 and serving metrics:

curl -s localhost:9100/metrics | head

If you see lines like nodecpusecondstotal and nodememory, you're up and running.

3. Add it as a Prometheus scrape target

In your Prometheus prometheus.yml, register this machine as a scrape target:

scrape_configs:
  - job_name: node
    static_configs:
      - targets:
          - "10.0.0.5:9100"   # your server's private IP
        labels:
          instance: web-1

Reload Prometheus (kill -HUP or hit /-/reload), then open the Targets page and check that the target shows as UP.

4. Security: never expose 9100 to the internet

The /metrics endpoint leaks your hostname, kernel version, mount points, network interfaces, and more, so it should not be reachable from the public internet. Apply either or both of these:

  • Bind to a private address: as shown above, use --web.listen-address=<private-ip>:9100, or 127.0.0.1 when Prometheus runs on the same host.
  • Restrict with a firewall: allow only your Prometheus server's IP.
sudo ufw allow from 10.0.0.10 to any port 9100 proto tcp

5. What the common metrics mean

  • nodecpusecondstotal: cumulative seconds per CPU per mode; wrap it in rate() for utilization.
  • nodememoryMemAvailablebytes: memory actually available, a truer figure than MemFree.
  • nodefilesystemavailbytes: free filesystem space; pair with size to get usage percent.
  • nodeload1 / nodeload5 / nodeload15: system load averages.
  • nodenetworkreceivebytestotal / transmit: bytes in and out per interface; use rate() for throughput.
  • nodediskiotimesecondstotal: time the disk spent busy, handy for spotting I/O bottlenecks.

Summary

Getting nodeexporter going takes three steps: download the binary, run it as a systemd service listening on 9100, and add a scrape target in Prometheus. Keep that port on a private network or behind a firewall so you don't leak host details. Once it's flowing, you have continuous time-series data for CPU, memory, disk, and network, which makes wiring up Grafana dashboards or alerts a straightforward next step.