Tutorial · Prometheus

How to Monitor a Linux Server with Prometheus and Node Exporter

Install Node Exporter on Linux, add it to Prometheus, verify target health and node metrics, and secure port 9100 before expanding the deployment.

By PerfMonitoring · Published September 11, 2026 · Last verified September 11, 2026 · Editorial Policy

Prometheus does not automatically know how much CPU, memory, disk space, or network traffic a Linux server is using. For host metrics, the standard Prometheus ecosystem component is Node Exporter, which exposes machine metrics over HTTP so Prometheus can scrape them.

The basic path is simple: run Node Exporter on the Linux host, verify its /metrics endpoint locally, add the host as a Prometheus scrape target, then confirm the target is UP and that fresh node_* metrics are queryable.

The production details matter just as much as the scrape configuration. Node Exporter listens on port 9100 by default, and exposing that port to the entire Internet is unnecessary for most deployments. This tutorial therefore starts with local verification and treats network exposure as an explicit security decision.

Last verified: September 11, 2026. The official Node Exporter GitHub releases page marks 1.11.1 as Latest. Prometheus itself currently has active release branches, so this guide does not hard-code one Prometheus server version into the installation commands; use the current official download appropriate to your maintained release line.

What You'll Accomplish

You will:

  1. install Node Exporter 1.11.1 on a Linux server;
  2. run it with a dedicated system account;
  3. verify the /metrics endpoint locally;
  4. restrict network exposure to the Prometheus server where practical;
  5. add the Linux host to prometheus.yml;
  6. validate the Prometheus configuration;
  7. confirm the target is UP; and
  8. query useful node_* metrics.

Prerequisites

You need:

  • a Linux server to monitor;
  • a separate or local Prometheus server;
  • shell access with sudo;
  • network connectivity from Prometheus to the Linux host on the chosen Node Exporter port;
  • permission to edit the Prometheus configuration;
  • the Prometheus promtool binary available with your Prometheus installation.

If Prometheus and Node Exporter run on the same machine, the networking step is simpler. In a normal multi-server deployment, Prometheus needs TCP access to Node Exporter on port 9100 unless you deliberately configure a different listener.

Quick Answer

Download the current official Node Exporter release for your Linux architecture, install the binary as a dedicated system service, and verify curl http://127.0.0.1:9100/metrics returns Prometheus-format metrics. Then add the host to Prometheus under a scrape job such as job_name: node with targets: ["10.0.0.12:9100"]. Run promtool check config prometheus.yml, reload Prometheus, and verify the target is UP in Status → Targets or through the targets API. Query node_exporter_build_info, node_cpu_seconds_total, and node_filesystem_avail_bytes to prove real host metrics are arriving.

Step 1: Download the Current Node Exporter Release

The official releases page marks Node Exporter 1.11.1 as Latest on this article's verification date.

For a Linux AMD64 host:

cd /tmp

curl -fLO \
  https://github.com/prometheus/node_exporter/releases/download/v1.11.1/node_exporter-1.11.1.linux-amd64.tar.gz

Extract it:

tar -xzf node_exporter-1.11.1.linux-amd64.tar.gz
cd node_exporter-1.11.1.linux-amd64

Confirm the binary reports the expected version:

./node_exporter --version

If your host uses ARM64 or another architecture, choose the matching asset from the official release page instead of changing only the filename and assuming the asset exists.

Verify downloads in production

The GitHub release publishes checksums for release assets. In a production automation pipeline, verify the release checksum/signature process your organization trusts before installing binaries as system software.

Do not download monitoring binaries from third-party mirrors simply because an old tutorial links to them.

Step 2: Create a Dedicated System User

Node Exporter normally does not need an interactive login.

Create a system user:

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

Install the binary:

sudo install -m 0755 ./node_exporter /usr/local/bin/node_exporter

Verify:

/usr/local/bin/node_exporter --version

A dedicated account makes service ownership clearer and avoids running the exporter as root without a specific requirement.

Some optional collectors or unusual host data can require additional permissions. Grant those deliberately if you enable them rather than making root the default.

Step 3: Create a systemd Service

Create:

sudo tee /etc/systemd/system/node_exporter.service >/dev/null <<'EOF'
[Unit]
Description=Prometheus Node Exporter
Wants=network-online.target
After=network-online.target

[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/usr/local/bin/node_exporter
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target
EOF

Reload systemd and start the service:

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

Check status:

sudo systemctl status node_exporter --no-pager

Inspect recent logs if it did not start:

sudo journalctl -u node_exporter -n 100 --no-pager

The service unit above is an operational example, not a unit file copied from an official Linux package. It keeps the default Node Exporter command simple so unexpected flags do not become hidden configuration.

Step 4: Verify the Local Metrics Endpoint

The official Prometheus Node Exporter guide uses the /metrics endpoint for verification.

Run on the monitored Linux host:

curl -fsS http://127.0.0.1:9100/metrics | head

You should see Prometheus text exposition with lines beginning with # HELP, # TYPE, and metric samples.

Check Node Exporter-specific metrics:

curl -fsS http://127.0.0.1:9100/metrics | grep '^node_' | head

A particularly useful identity metric is:

curl -fsS http://127.0.0.1:9100/metrics \
  | grep '^node_exporter_build_info'

If local curl fails, do not edit Prometheus yet. Fix the exporter first.

Step 5: Restrict Port 9100 Exposure

Node Exporter exposes host information. In most environments, only Prometheus—or a tightly defined monitoring network—needs to reach it.

Do not open TCP/9100 to 0.0.0.0/0 in a cloud firewall merely to make the target turn green.

A safer network rule is conceptually:

source: Prometheus server/private monitoring subnet
destination: Linux host TCP 9100

The exact firewall syntax depends on your environment.

If Prometheus is local to the same host, you can consider binding Node Exporter to a loopback address. For remote scraping, use private network controls and, when required by your security model, Node Exporter's web configuration/TLS capabilities.

The Node Exporter repository documents an experimental web configuration path for TLS/auth-related endpoint configuration. Recheck current status before standardizing it broadly.

Step 6: Add the Host to Prometheus

On the Prometheus server, edit prometheus.yml.

Add a scrape job:

scrape_configs:
  - job_name: node
    static_configs:
      - targets:
          - "10.0.0.12:9100"

Replace 10.0.0.12 with the address Prometheus can actually reach.

If you already have scrape_configs, add a second list item rather than creating another top-level scrape_configs key.

A common working global configuration is:

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: prometheus
    static_configs:
      - targets:
          - "localhost:9090"

  - job_name: node
    static_configs:
      - targets:
          - "10.0.0.12:9100"

The official Node Exporter guide uses the same localhost:9100 scrape concept for a local example.

Step 7: Validate the Prometheus Configuration

Before reloading/restarting Prometheus:

promtool check config prometheus.yml

Current Prometheus documentation describes promtool check config as the configuration validator. It also checks referenced rule files unless you explicitly use syntax-only behavior.

Do not skip validation in production automation.

If validation succeeds, reload Prometheus using your deployment's supported method. Common options include:

  • a service restart;
  • a process reload when lifecycle reload is enabled;
  • a container/deployment rollout.

Use the method your existing Prometheus deployment already supports rather than adding an unsafe ad-hoc signal handler.

Step 8: Verify the Target Is UP

Open the Prometheus Targets page and find the node job.

The target should be UP.

You can also query the generated up metric:

up{job="node"}

Expected healthy result:

1

A value of 0 means Prometheus knows about the target but the scrape fails.

Why up is useful

Prometheus generates the up series for scrape targets. It is a direct signal about collection health and is often more useful than wondering why a dashboard is empty.

Do not confuse:

  • Node Exporter service is running locally with
  • Prometheus can successfully scrape Node Exporter remotely.

Both need verification.

Step 9: Query Useful Linux Metrics

The official guide identifies node_ metrics including CPU, filesystem, and network data.

Exporter identity

node_exporter_build_info

CPU time

rate(node_cpu_seconds_total{mode="system"}[5m])

Available filesystem bytes

node_filesystem_avail_bytes{mountpoint="/"}

Network receive rate

rate(node_network_receive_bytes_total[5m])

For a user-facing dashboard, you may later aggregate these into CPU utilization percentages or filesystem percentages. Keep this first setup focused on proving the raw host metrics are present.

Step 10: Add Useful Labels When You Scale

Static targets can carry labels:

- job_name: node
  static_configs:
    - targets:
        - "10.0.0.12:9100"
      labels:
        environment: "production"
        role: "web"

Use bounded, operational labels.

Avoid labels such as:

  • request IDs;
  • timestamps;
  • unbounded user values.

Prometheus label cardinality directly affects time-series volume.

For a larger fleet, the official documentation also covers file-based and other service discovery methods. Static configuration is intentionally used here because it makes the first scrape easy to understand.

Verify the Setup

Your Linux host monitoring setup is complete when all of these are true:

  • systemctl status node_exporter shows a healthy service;
  • curl http://127.0.0.1:9100/metrics returns metrics locally;
  • port 9100 is reachable only from the intended monitoring path;
  • promtool check config prometheus.yml succeeds;
  • the Prometheus target is UP;
  • up{job="node"} returns 1;
  • node_exporter_build_info is queryable;
  • fresh node_cpu_seconds_total and filesystem metrics are present.

If the target is UP but a specific metric is missing, investigate the collector/OS support rather than assuming the whole scrape is broken.

Common Problems and Fixes

Problem: Node Exporter works locally but Prometheus target is DOWN

Likely cause: firewall/security-group routing or wrong target address.

Fix: from the Prometheus host, test:

curl -v http://10.0.0.12:9100/metrics

If that cannot connect while local curl succeeds, troubleshoot the network path.

Problem: Connection refused on 9100

Likely cause: Node Exporter is not running, is listening on a different address/port, or host firewall rejects the connection.

Fix: check systemctl, journalctl, and the process listening sockets.

Problem: Prometheus config validation fails

Likely cause: YAML indentation, duplicate top-level structure, or malformed target list.

Fix: run promtool check config after every edit. Do not restart repeatedly hoping the parser accepts it.

Problem: Target is UP but dashboard shows no data

Likely cause: dashboard query filters a different job or instance label.

Fix: inspect actual labels:

node_exporter_build_info

Then align the dashboard with those values.

Problem: Node Exporter exposes too many filesystem/device series

Likely cause: the default collectors legitimately expose host devices/mounts that are not useful to your dashboard.

Fix: filter at query time first. Disable or include/exclude collectors only after understanding the effect; aggressive exporter filtering can remove metrics another team expects.

Problem: CPU query looks strange

Cause: node_cpu_seconds_total is a counter broken down by CPU and mode, not a precomputed host utilization percentage.

Fix: use rate() and the appropriate aggregation. The Grafana tutorial in this project provides a utilization expression.

Best Practices

Keep Node Exporter private

Treat 9100 as a monitoring service endpoint, not a public website.

Use a dedicated service account

Start with least privilege and add documented permissions only for collectors that need them.

Pin and review releases

Node Exporter releases can change collectors and metric behavior. Use a controlled upgrade process.

Validate before reloading Prometheus

Make promtool check config part of change automation.

Alert separately on scrape health

up{job="node"} == 0 represents monitoring reachability. CPU, memory, and disk alerts represent host symptoms. Keep those concepts separate.

Move to service discovery as the fleet grows

Static targets are excellent for learning and small fleets. File-based, cloud, Kubernetes, or other discovery mechanisms reduce manual target maintenance at scale.

When This Setup Makes Sense

Node Exporter is the standard choice for Prometheus-style Linux host metrics.

It is a good fit when:

  • Prometheus is your metrics backend;
  • you need Linux kernel/hardware metrics;
  • the monitoring network can reach host exporters;
  • you are comfortable operating the Prometheus scrape model.

If you need application traces or logs, Node Exporter is not that tool. Use application instrumentation and a log pipeline separately.

FAQ

What port does Node Exporter use?

The standard Node Exporter listener is port 9100.

Should port 9100 be public?

Usually no. Limit it to the Prometheus server or monitoring network unless you have a documented reason and appropriate endpoint security.

Does Node Exporter need root?

The common host-metrics setup can run under a dedicated non-root account. Some optional collectors or environments can require additional access; grant it deliberately.

Why is my Prometheus Node Exporter target DOWN?

First verify /metrics locally on the Linux host, then test it from the Prometheus server. This separates exporter failures from network/firewall failures.

Which Node Exporter version was verified?

1.11.1, marked Latest on the official GitHub releases page on September 11, 2026.

Conclusion

Prometheus Linux monitoring is easiest to troubleshoot when you validate each layer separately: Node Exporter process, local /metrics, network reachability, Prometheus configuration, target health, then actual node_* queries.

Keep port 9100 restricted, validate configuration with promtool, and confirm up{job="node"} == 1 before building dashboards and alerts.

The next logical step is How to Create Prometheus Alerting Rules with Alertmanager.

References

  1. Prometheus Documentation — "Monitoring Linux host metrics with the Node Exporter"https://prometheus.io/docs/guides/node-exporter/ — accessed September 11, 2026.
  2. Prometheus Documentation — "Use file-based service discovery to discover scrape targets"https://prometheus.io/docs/guides/file-sd/ — accessed September 11, 2026.
  3. Prometheus Documentation — "promtool"https://prometheus.io/docs/prometheus/latest/command-line/promtool/ — accessed September 11, 2026.
  4. Prometheus Node Exporter GitHub — "Releases"https://github.com/prometheus/node_exporter/releases — accessed September 11, 2026; version 1.11.1 marked Latest.
  5. Prometheus Node Exporter GitHub — "node_exporter"https://github.com/prometheus/node_exporter — accessed September 11, 2026.