How to Install Prometheus on a Dedicated Server: Ubuntu 24.04 Guide

Learn how to install Prometheus on an Ubuntu dedicated server, configure Node Exporter, monitor CPU and memory usage, and secure your monitoring setup.

Introduction

Monitoring a dedicated server is essential for understanding resource utilization, identifying performance bottlenecks, and detecting infrastructure problems before they affect applications. CPU saturation, insufficient memory, disk-space exhaustion, and unexpected network traffic can all affect server availability and application performance.

Prometheus is an open-source monitoring and alerting toolkit that collects time-series metrics from configured targets. It stores the collected data locally, provides a query language called PromQL, and integrates with visualization and alerting tools.

In this tutorial, you will install Prometheus on an Ubuntu 24.04 LTS dedicated server, configure Node Exporter to collect Linux system metrics, create systemd services for both applications, and verify that metrics are being collected successfully.

The tutorial uses native Linux binaries rather than containers so that you can understand the configuration files, service permissions, and storage locations directly.

What you will build

By the end of this guide, your dedicated server will have:

  • Prometheus collecting and storing time-series metrics.
  • Node Exporter exposing Linux hardware and operating-system metrics.
  • systemd managing both services and restarting them when necessary.
  • A working Prometheus web interface for querying server metrics.
  • A basic security configuration that avoids unnecessary public exposure.

Prerequisites

Before starting, make sure you have the following:

Requirement Description
Dedicated server An Ubuntu 24.04 LTS installation
Access SSH access with a sudo-enabled account
Architecture Linux x86-64 (amd64) for the commands in this guide
Network Outbound HTTPS access for downloading release archives
Storage Sufficient free disk space for the operating system and retained metrics
Permissions Ability to create service accounts and edit system configuration

The examples assume that Prometheus and Node Exporter run on the same dedicated server. You can adapt the configuration to monitor additional servers later.

Ports used in this tutorial

Port Component Purpose
9090/TCP Prometheus Web interface and query API
9100/TCP Node Exporter Linux system metrics endpoint
Security Warning Keep these ports restricted to trusted systems. Neither service should be exposed directly to the public internet without appropriate access controls.

Step 1: Update Ubuntu and Install Required Utilities

Connect to your dedicated server over SSH:

Bash
ssh your_username@YOUR_SERVER_IP

Update the package index and install the utilities required to download and verify the release archives:

Bash
sudo apt update
sudo apt install -y ca-certificates curl tar

Check the operating-system version and architecture:

Bash
lsb_release -ds
dpkg --print-architecture

The commands in this guide expect Ubuntu 24.04 LTS and the amd64 architecture. Check available disk space before configuring metric retention:

Bash
df -h

Prometheus storage requirements depend on the number of monitored time series, scrape frequency, and retention period. Review disk capacity before deploying monitoring on a production server.

Step 2: Create Dedicated Service Accounts

Prometheus and Node Exporter should run as unprivileged system users rather than as root. Create the service accounts:

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

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

Create the directories required by Prometheus:

Bash
sudo install -d -o root -g root -m 0755 /etc/prometheus

sudo install -d \
  -o prometheus -g prometheus -m 0750 \
  /var/lib/prometheus

The configuration directory is managed by root, while the Prometheus service account owns its time-series database directory. These permissions help separate administrative configuration changes from the data-writing permissions required by the running service.

Step 3: Download and Install Prometheus

Prometheus distributes precompiled binaries for supported operating systems and architectures. Using the official release archive lets you select a specific version instead of relying on an unspecified package version.

For this tutorial, use Prometheus 3.15.0. Confirm the current release and checksum on the official Prometheus download page before running the commands.

Set the version and download the Linux AMD64 archive:

Bash
cd /tmp

PROM_VERSION="3.15.0"

curl -fLO \
  "https://github.com/prometheus/prometheus/releases/download/v${PROM_VERSION}/prometheus-${PROM_VERSION}.linux-amd64.tar.gz"

Verify the downloaded archive

Obtain the published SHA-256 checksum from the official download page and compare it with the local file:

Bash
sha256sum "prometheus-${PROM_VERSION}.linux-amd64.tar.gz"

Compare the resulting hash with the official value. Do not continue if the values differ.

Extract the archive and enter the extracted directory:

Bash
tar -xzf "prometheus-${PROM_VERSION}.linux-amd64.tar.gz"
cd "prometheus-${PROM_VERSION}.linux-amd64"

Install the executable files:

Bash
sudo install -o root -g root -m 0755 \
  prometheus /usr/local/bin/prometheus

sudo install -o root -g root -m 0755 \
  promtool /usr/local/bin/promtool

Install the default web-interface assets and example configuration files, then set the appropriate ownership:

Bash
sudo cp -a consoles /etc/prometheus/
sudo cp -a console_libraries /etc/prometheus/
sudo install -o root -g root -m 0644 \
  prometheus.yml /etc/prometheus/prometheus.yml

sudo chown -R root:root /etc/prometheus
sudo chmod 0755 /etc/prometheus
sudo chmod 0644 /etc/prometheus/prometheus.yml

Check the installed version:

Bash
prometheus --version
promtool --version

Both commands should display version information for the installed Prometheus release.

Step 4: Install Node Exporter

Prometheus collects metrics by scraping HTTP endpoints. Node Exporter exposes operating-system and hardware-related metrics that Prometheus can collect from a Linux server.

For this guide, use Node Exporter 1.12.1, subject to verification against the official release downloads.

Bash
cd /tmp

NODE_VERSION="1.12.1"

curl -fLO \
  "https://github.com/prometheus/node_exporter/releases/download/v${NODE_VERSION}/node_exporter-${NODE_VERSION}.linux-amd64.tar.gz"

Verify its SHA-256 checksum against the official published checksum before extracting it:

Bash
sha256sum "node_exporter-${NODE_VERSION}.linux-amd64.tar.gz"

Extract the archive and install the executable:

Bash
tar -xzf "node_exporter-${NODE_VERSION}.linux-amd64.tar.gz"

sudo install -o root -g root -m 0755 \
  "node_exporter-${NODE_VERSION}.linux-amd64/node_exporter" \
  /usr/local/bin/node_exporter

Check the version:

Bash
node_exporter --version

Node Exporter typically listens on TCP port 9100. It exposes metrics through the /metrics endpoint, which Prometheus will scrape at regular intervals.

Step 5: Configure Prometheus

Prometheus uses a YAML configuration file to define global settings, scrape intervals, and monitoring targets.

Open the configuration file:

Bash
sudo nano /etc/prometheus/prometheus.yml

Replace its contents with the following configuration:

YAML
global:
  scrape_interval: 15s
  evaluation_interval: 15s

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

- job_name: "node_exporter"
  static_configs:
  - targets:
    - "127.0.0.1:9100"

Save the file and exit the editor.

Understanding the configuration

  • scrape_interval: 15s tells Prometheus to collect metrics every 15 seconds by default.
  • evaluation_interval: 15s sets how frequently configured recording and alerting rules are evaluated.
  • job_name: "prometheus" monitors the Prometheus service itself.
  • job_name: "node_exporter" identifies the Linux system-metrics target.
  • static_configs defines targets explicitly rather than discovering them automatically.
  • 127.0.0.1 limits these example scrape targets to services on the same machine.
Formatting Note The indentation is important because YAML uses whitespace to represent its structure. Each targets list must be nested under static_configs.

Validate the configuration

Run:

Bash
sudo promtool check config /etc/prometheus/prometheus.yml

The command should report that the configuration file is valid. Resolve any validation errors before starting the service. Validating the configuration at this stage helps prevent avoidable startup failures caused by malformed YAML or unsupported settings.

Step 6: Create the Node Exporter systemd Service

A systemd service allows Node Exporter to start automatically at boot and provides a consistent way to manage its process.

Create the service file:

Bash
sudo nano /etc/systemd/system/node_exporter.service

Add the following configuration:

INI
[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 --web.listen-address=127.0.0.1:9100
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

Save the file.

The --web.listen-address=127.0.0.1:9100 argument binds Node Exporter to the loopback interface. This is appropriate because Prometheus is running on the same server. If you later move Prometheus to another machine, you will need to change the listening address and allow only the monitoring server to reach port 9100 through your firewall.

Load the service definition, enable the service at boot, and start it:

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

Check its status:

Bash
sudo systemctl status node_exporter --no-pager

Look for Active: active (running). Test the metrics endpoint locally:

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

The response should contain Prometheus-formatted metrics, including HELP and TYPE metadata lines. Output may vary with the installed Node Exporter version and enabled collectors.

Step 7: Create the Prometheus systemd Service

Create a systemd unit for Prometheus:

Bash
sudo nano /etc/systemd/system/prometheus.service

Add the following configuration:

INI
[Unit]
Description=Prometheus Monitoring System
Wants=network-online.target
After=network-online.target

[Service]
User=prometheus
Group=prometheus
Type=simple

ExecStart=/usr/local/bin/prometheus \
  --config.file=/etc/prometheus/prometheus.yml \
  --storage.tsdb.path=/var/lib/prometheus \
  --storage.tsdb.retention.time=15d \
  --web.listen-address=127.0.0.1:9090

Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

Save the file.

This service configuration sets the following options:

  • --config.file: Specifies the Prometheus YAML configuration.
  • --storage.tsdb.path: Sets the local time-series database directory.
  • --storage.tsdb.retention.time=15d: Sets a 15-day time-based retention period.
  • --web.listen-address: Binds the HTTP interface to localhost.
  • Restart=on-failure: Restarts the process after an unsuccessful exit.

The 15-day retention period is an example, not a universal recommendation. Adjust it based on your monitoring requirements and available disk space. Time-based retention does not replace capacity planning.

Enable and start Prometheus:

Bash
sudo systemctl daemon-reload
sudo systemctl enable --now prometheus
sudo systemctl status prometheus --no-pager

If the service is running, continue to the verification steps.

Step 8: Verify Prometheus and Node Exporter

At this point, both services should be running, and Prometheus should be configured to scrape the two local targets.

Check service logs

Inspect the recent logs for both services:

Bash
sudo journalctl -u prometheus -n 50 --no-pager
sudo journalctl -u node_exporter -n 50 --no-pager

Look for configuration errors, permission problems, address conflicts, or repeated service restarts.

Check the Prometheus readiness endpoint

Run:

Bash
curl -i http://127.0.0.1:9090/-/ready

A successful readiness check returns an HTTP success response. Check that Prometheus can report its health:

Bash
curl -fsS http://127.0.0.1:9090/-/healthy

Query the target status API

Run:

Bash
curl -fsS 'http://127.0.0.1:9090/api/v1/targets'

The response contains target details, including scrape health and any reported scrape errors. You can also check the up metric directly:

Bash
curl -fsS 'http://127.0.0.1:9090/api/v1/query?query=up'

For a healthy target, the up metric has a value of 1. A value of 0 indicates that Prometheus knows about the target but the most recent scrape failed. A missing result may indicate that the target has not yet been discovered or scraped, or that the query returned no matching series.

Step 9: Access the Prometheus Web Interface

Because the service is bound to 127.0.0.1, its web interface is not directly accessible through the dedicated server's public IP address. You can access it securely through an SSH tunnel from your local computer.

Open a terminal on your local computer and run:

Bash
ssh -L 9090:127.0.0.1:9090 your_username@YOUR_SERVER_IP

Keep this SSH connection open. Open the following URL in your local browser: http://127.0.0.1:9090. You should see the Prometheus web interface.

Run a test query

Open the query interface and enter up. Execute the query. The result should include the Prometheus and Node Exporter targets, each with a value of 1 after successful scrapes. You can now use PromQL to query the collected metrics.

Step 10: Monitor Dedicated Server Resources with PromQL

Node Exporter provides metrics for CPU activity, memory, filesystems, network interfaces, and other Linux system components. The following examples help you begin investigating server performance.

CPU utilization

Use this query to estimate the percentage of CPU time spent in non-idle modes across the server:

PromQL
100 * (
  1 - avg by (instance) (
    rate(node_cpu_seconds_total{mode="idle"}[5m])
  )
)

Available memory

Calculate the percentage of memory currently available to applications and the operating system:

PromQL
100 *
node_memory_MemAvailable_bytes
/
node_memory_MemTotal_bytes

This uses Linux's MemAvailable estimate rather than simply treating all non-free memory as unavailable. Linux uses otherwise-unused memory for caches, so the MemFree value alone is not a reliable measure of memory pressure.

Available filesystem space

Query available bytes for mounted filesystems:

PromQL
node_filesystem_avail_bytes{
  fstype!~"tmpfs|devtmpfs|overlay|squashfs"
}

To calculate available space as a percentage of filesystem size:

PromQL
100 *
node_filesystem_avail_bytes{
  fstype!~"tmpfs|devtmpfs|overlay|squashfs"
}
/
node_filesystem_size_bytes{
  fstype!~"tmpfs|devtmpfs|overlay|squashfs"
}

Network and Disk Throughput

Calculate the approximate incoming traffic rate for each network interface (multiply by eight to convert bytes to bits):

PromQL
8 * rate(node_network_receive_bytes_total[5m])

Query the approximate disk read rate:

PromQL
rate(node_disk_read_bytes_total[5m])

Step 11: Monitor Additional Dedicated Servers

After validating the local setup, you can configure Prometheus to collect metrics from other Linux dedicated servers. Install Node Exporter on each additional server and configure it to listen on an address reachable from the Prometheus server. Do not expose the metrics endpoint to unrestricted public traffic.

For example, if a monitored server uses the private address 10.20.0.12, add a separate job to /etc/prometheus/prometheus.yml on the monitoring server:

YAML
- job_name: "remote_linux_servers"
  static_configs:
  - targets:
    - "10.20.0.12:9100"

Replace the sample address with the actual private IP address of the monitored server. Validate the updated configuration and restart Prometheus:

Bash
sudo promtool check config /etc/prometheus/prometheus.yml
sudo systemctl restart prometheus

Step 12: Secure and Maintain the Installation

A working monitoring setup should be maintained as carefully as the applications it monitors.

  • Restrict access: The default example binds both services to localhost, avoiding public exposure. If remote access is necessary, use an authenticated HTTPS reverse proxy, a private management network, or a VPN. Apply firewall rules that limit access to approved clients.
  • Review service status regularly: Check both services using systemctl is-active and review recent logs via journalctl when investigating errors.
  • Monitor disk usage: Prometheus stores its time-series data locally. Measure consumption using sudo du -sh /var/lib/prometheus.
  • Update binaries carefully: Review release notes, download the correct archive, verify checksums, back up configs/data, replace binaries during maintenance windows, and validate configs after upgrades.

Troubleshooting Common Prometheus Installation Problems

Problem Likely cause What to check
Prometheus fails to start Invalid YAML, incorrect paths, or permissions Run promtool check config and inspect journalctl
Node Exporter target is down Service stopped or incorrect target address Check systemctl status node_exporter and test port 9100 locally
Prometheus web interface is unreachable SSH tunnel is missing or the service is not running Check service status and verify the SSH tunnel
No node_ metrics appear Node Exporter is not being scraped successfully Test /metrics and review the target's scrape error
Disk usage increases unexpectedly High series cardinality, high ingestion volume, or long retention Inspect series growth, retention, and storage consumption
Remote target cannot be scraped Routing, firewall, binding, or authentication problem Verify connectivity from the monitoring server and review access rules

Conclusion

Prometheus provides a practical foundation for monitoring dedicated server infrastructure. By combining Prometheus with Node Exporter, system administrators can collect Linux performance metrics, investigate CPU and memory utilization, observe disk and network activity, and query historical measurements using PromQL. For production environments, secure the monitoring endpoints, plan storage capacity, maintain verified software updates, and monitor the health of the monitoring services themselves.

Frequently Asked Questions

What is Prometheus used for on a dedicated server?

Prometheus collects and stores time-series metrics from configured endpoints. On a dedicated server, it can be used to monitor operating-system resources, application metrics, service availability, and infrastructure performance.

Is Node Exporter required to install Prometheus?

No. Prometheus can scrape any compatible metrics endpoint, including its own. Node Exporter is commonly added when you want Linux operating-system and hardware-related metrics such as CPU activity, memory availability, disk statistics, and network traffic.

Which ports does Prometheus use?

Prometheus commonly uses TCP port 9090 for its web interface and HTTP API. Node Exporter commonly uses TCP port 9100 for Linux system metrics. Both ports should be restricted to trusted systems.

How much disk space does Prometheus require?

There is no single fixed requirement. Storage consumption depends on the number of active time series, scrape intervals, retention period, and metric characteristics. Measure actual usage under representative workloads and provide sufficient storage headroom.

Can Prometheus monitor multiple dedicated servers?

Yes. Prometheus can scrape multiple targets defined in its configuration or discovered through supported service-discovery mechanisms. Each monitored Linux server generally runs Node Exporter or another appropriate metrics exporter.

Does Prometheus include dashboards?

Prometheus includes a web interface for querying and exploring metrics. For more advanced dashboards and visualization, it is commonly integrated with Grafana.

Is Prometheus suitable for production monitoring?

Yes, provided it is deployed and maintained appropriately. Production installations should account for storage capacity, access controls, retention policies, backups where required, software updates, and monitoring of Prometheus itself.

How can I confirm that Prometheus is collecting metrics?

Open the Prometheus query interface and execute up. A value of 1 indicates that the corresponding target was successfully scraped. You can also inspect the Targets page to view each target's status and scrape errors.

Need Reliable Hardware for Your Infrastructure?

Monitoring is crucial, but it starts with a strong foundation. Whether you are running high-traffic databases, massive AI models, or complex containerized environments, Fit Servers provides the dedicated bare-metal performance required to keep your infrastructure fast, secure, and always online.

Explore Dedicated Servers today!