How to Install and Configure Prometheus and Grafana on Ubuntu

Prometheus and Grafana on Ubuntu: Complete Setup

A server can look healthy while its disk fills, memory runs low, or response times slowly increase. This guide shows you how to install and configure Prometheus and Grafana on Ubuntu so you can collect server metrics, spot problems early, and view useful dashboards from one place.

You will set up Prometheus for metrics collection, secure its local web interface, install node_exporter on a monitored server, connect Grafana as the visualization layer, and test the complete monitoring path. The commands use Ubuntu packages where practical and avoid exposing monitoring services directly to the public internet.

How Prometheus and Grafana work together

Prometheus and Grafana solve different parts of the monitoring problem. Prometheus collects time-series data, which means measurements recorded with a value and a time. Grafana reads that data and turns it into charts, tables, and alerts that are easier to understand.

Think of Prometheus as a warehouse and Grafana as the shop window. Prometheus stores measurements such as CPU usage, available memory, disk space, and network traffic. Grafana lets you select those measurements and arrange them into a dashboard for daily checks or incident investigation.

A small setup usually contains three parts:

  • Prometheus: the monitoring server that periodically scrapes metrics from configured targets.
  • node_exporter: a lightweight service that exposes Linux hardware and operating system metrics.
  • Grafana: the web application used to query Prometheus and present the results.

Prometheus normally connects to an exporter over port 9100, while its own web interface commonly uses port 9090. Grafana commonly listens on port 3000. These ports should be reachable only from trusted systems or through a protected access method.

Prepare Ubuntu for monitoring

Use one Ubuntu server as the monitoring server and install Grafana and Prometheus there. Install node_exporter on each Ubuntu machine you want to observe. Before making changes, confirm that you have an account with sudo access and that the machines can communicate over the required private network.

Start by updating the package index and installing the available Prometheus packages:

sudo apt update
sudo apt install -y prometheus prometheus-node-exporter

The package names can vary between Ubuntu releases. If Ubuntu cannot find one of them, check the package repositories enabled on that system and consult the official Prometheus download documentation before choosing a manual installation.

Now check the services:

sudo systemctl enable --now prometheus
sudo systemctl enable --now prometheus-node-exporter
sudo systemctl status prometheus
sudo systemctl status prometheus-node-exporter

On some systems, the exporter service is named node-exporter rather than prometheus-node-exporter. Use systemctl list-unit-files | grep -i exporter if you need to confirm the installed service name.

Verify the exporter locally. A successful response contains lines of metric data rather than a normal web page:

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

Configure Prometheus targets

Prometheus configuration defines which endpoints it should scrape. A scrape is a request for the current metrics exposed by a target. The main configuration file is commonly located at /etc/prometheus/prometheus.yml.

Back up the file before editing it:

sudo cp /etc/prometheus/prometheus.yml /etc/prometheus/prometheus.yml.backup

Open the file with an editor and make sure it contains a local Prometheus target. Add a second job for a remote Ubuntu server, replacing the private address with the address of your monitored machine:

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: prometheus
    static_configs:
      - targets: ['127.0.0.1:9090']

  - job_name: linux-servers
    static_configs:
      - targets: ['192.0.2.25:9100']

The address in this example uses documentation space. Replace it with the real private IP address or internal DNS name of the client server. Do not use a public address unless you have deliberately protected the exporter with suitable network controls.

Validate the configuration before restarting the service:

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

If the check reports an error, fix the YAML indentation or spelling first. YAML uses spaces to show structure, so a misplaced dash or extra space can prevent Prometheus from starting.

Secure access to the Prometheus web interface

Prometheus is an administration and monitoring endpoint, not a public website. Keep it bound to a trusted interface or access it through a secure tunnel. The safest simple option for a private administrator connection is SSH port forwarding.

On your workstation, create a tunnel to the monitoring server:

ssh -N -L 9090:127.0.0.1:9090 admin@monitoring-server

While that connection remains open, visit http://127.0.0.1:9090 in your browser. The browser connects to your own computer, and SSH forwards the request to Prometheus on the server. This is similar to using a private hallway instead of opening the monitoring room onto a public street.

If you use a reverse proxy instead, require HTTPS and authentication, limit access by network or identity, and keep the exporter port unavailable from the public internet. Also review firewall rules so port 9100 is accepted only from the monitoring server.

Install node_exporter on a client server

node_exporter exposes operating system metrics such as CPU time, memory, filesystem space, and network statistics. Install it on every client you want to monitor, but run it as a dedicated unprivileged user rather than as root.

On a client Ubuntu server, install the package:

sudo apt update
sudo apt install -y prometheus-node-exporter
sudo systemctl enable --now prometheus-node-exporter

Check the service and endpoint:

sudo systemctl status prometheus-node-exporter
curl http://127.0.0.1:9100/metrics | head

For example, imagine a web server called web-01 with the private address 10.10.20.15. Prometheus should scrape 10.10.20.15:9100, while users continue to access the web application through its normal HTTPS address. The exporter does not replace application monitoring; it supplies the host-level view that helps explain whether the operating system is under pressure.

If your Ubuntu repositories do not provide the exporter package, use the maintained release and installation instructions from the official Prometheus downloads page. Verify downloaded files before installing them, and create a systemd service that runs the exporter with a dedicated account.

Confirm target health in Prometheus

Return to the Prometheus interface through your protected connection. Open the targets page, usually available under the status menu, and look for the linux-servers job.

A healthy target should show an up state. If it is down, work through this checklist:

  1. Confirm node_exporter is running with sudo systemctl status prometheus-node-exporter.
  2. Test the endpoint from the monitoring server with curl http://client-address:9100/metrics.
  3. Check that the client firewall allows port 9100 from the monitoring server only.
  4. Confirm the target address and port in prometheus.yml.
  5. Review recent service logs with sudo journalctl -u prometheus --since '15 minutes ago'.

For instance, if the endpoint works on the client but not from the monitoring server, the likely problem is routing or a firewall rule. If the endpoint works remotely but Prometheus still reports an error, inspect the YAML and reload the service after correcting it.

Install Grafana on Ubuntu

Grafana is the visualization layer for your monitoring stack. Install it from the official Grafana APT repository so package updates can be managed through Ubuntu’s normal package tools.

First install the tools needed to add the repository:

sudo apt-get install -y apt-transport-https wget gnupg
sudo mkdir -p /etc/apt/keyrings
sudo wget -O /etc/apt/keyrings/grafana.asc https://apt.grafana.com/gpg-full.key
sudo chmod 644 /etc/apt/keyrings/grafana.asc
echo "deb [signed-by=/etc/apt/keyrings/grafana.asc] https://apt.grafana.com stable main" | sudo tee /etc/apt/sources.list.d/grafana.list
sudo apt-get update
sudo apt-get install -y grafana

Enable and start Grafana:

sudo systemctl enable --now grafana-server
sudo systemctl status grafana-server

Grafana listens on port 3000 by default. Protect this port with a firewall, private network rule, VPN, or an HTTPS reverse proxy with authentication. Do not assume that changing the default port provides meaningful security.

Connect Grafana to Prometheus

Open Grafana at http://monitoring-server:3000 from an approved network, or use an SSH tunnel similar to the Prometheus example. Sign in with the credentials supplied by the installed Grafana package, then immediately set a strong unique password if the first-login screen asks you to do so.

To add Prometheus as a data source, use the Grafana navigation menu and choose the data sources area. Select Prometheus and enter the URL that Grafana can reach. If both services run on the same server, use:

http://127.0.0.1:9090

Click the option to save and test the connection. A successful test confirms that Grafana can query Prometheus; it does not prove that every monitored target is healthy, so check the target page separately.

Now create a dashboard or import one from a trusted source. Imported dashboards can save time, but inspect their queries and variables before relying on them. Dashboard layouts may change, and a dashboard designed for one exporter setup may not match another.

Build a useful Grafana dashboard

Start with a small dashboard rather than adding every available metric. Add panels for CPU utilization, memory available, filesystem usage, network traffic, and target status. Choose a time range that matches the question: a recent view helps with a live incident, while a longer range helps reveal gradual changes.

Consider a simple example. If a file server has plenty of CPU capacity but its filesystem panel trends toward full, adding more CPU charts will not solve the problem. The dashboard should direct attention to storage cleanup, capacity planning, or log rotation instead.

Use clear panel names and units. A panel titled Root filesystem used is more useful than one labeled Panel 4. Add descriptions where a metric could be misunderstood, and keep a short written record of what action each important panel should trigger.

Common mistakes and practical checks

Most failed installations come from a small configuration or access problem. These checks prevent the most common issues:

  • Using the wrong address: Grafana should reach Prometheus from the Grafana server, not necessarily from your laptop. Test connectivity from the correct machine.
  • Opening every port publicly: Allow port 9100 only from Prometheus and protect ports 9090 and 3000 with access controls.
  • Skipping configuration validation: Run promtool check config before restarting Prometheus.
  • Running services in a terminal: Use systemd so services start after a reboot and restart after a failure.
  • Trusting a dashboard without checking queries: Confirm that panels use the data source and labels present in your environment.
  • Ignoring disk retention: Prometheus stores data locally. Monitor the filesystem holding its data and choose retention settings that fit available space.

A practical final check is to reboot a test client during a maintenance window, then confirm that node_exporter returns after startup, Prometheus marks the target healthy again, and Grafana displays new samples. This tests the entire path rather than only the installation commands.

Prometheus and Grafana FAQ

What is the difference between Prometheus and Grafana?

Prometheus collects and stores time-series metrics, while Grafana queries those metrics and displays them in dashboards. You can run Prometheus without Grafana, but Grafana makes the data easier to explore and share.

How do I monitor another Ubuntu server?

Install node_exporter on the other server, start its service, allow port 9100 only from the Prometheus server, and add the server address to the appropriate scrape job. Then check the target status and query a metric before building panels.

Why is my Prometheus target down?

Check the exporter service, test the metrics URL from the monitoring server, and inspect firewall and routing rules. Also verify that the target address in the configuration includes the correct port and that Prometheus was restarted after the change.

Can I expose Prometheus or Grafana to the internet?

Do not expose either service without strong access controls, HTTPS, and careful network restrictions. A private network, VPN, SSH tunnel, or authenticated reverse proxy is usually a safer starting point.

Finish the setup and plan the next check

You now have a basic monitoring path: node_exporter exposes Linux metrics, Prometheus collects them, and Grafana presents them in dashboards. The most important operational step is not adding more charts; it is deciding which signals require action and who will respond.

Before calling the setup complete, test one client from the monitoring server, confirm the target is healthy, secure the three web services, and check that Prometheus storage has enough room. Your next step should be to add one dashboard for the systems that matter most, then document the access path and the first response for each warning.

Read also: Configure Squid Proxy on Ubuntu 20.04

Related guides