Why Prometheus and Grafana Belong on Your Server
Most system administrators discover the gap in their monitoring setup at the worst possible moment – a service goes down at 2 a.m., and there is no historical data to explain why CPU usage spiked or when memory started climbing. Prometheus and Grafana solve exactly that problem. Prometheus is a time-series database and scraping engine that pulls metrics from your services at defined intervals, while Grafana is a visualization layer that turns those raw numbers into readable dashboards. Together, they form a self-hosted monitoring stack that gives you full ownership of your infrastructure data.
The appeal of running this stack yourself goes beyond privacy. Cloud-based monitoring tools charge per metric, per host, or per retention window – costs that compound quickly once you scale past a handful of servers. Self-hosting removes those billing variables entirely and lets you retain metrics for as long as your disk allows.
This guide walks through installing Prometheus and Grafana on a Linux server, configuring Node Exporter to collect system metrics, and wiring everything together into a working dashboard.

Installing Prometheus and Node Exporter
Start by creating a dedicated system user for Prometheus so it runs without root privileges. On Ubuntu or Debian, run sudo useradd –no-create-home –shell /bin/false prometheus. Then create the directories Prometheus needs: sudo mkdir /etc/prometheus and sudo mkdir /var/lib/prometheus. Set ownership on both directories with sudo chown prometheus:prometheus /etc/prometheus and sudo chown prometheus:prometheus /var/lib/prometheus. This separation of permissions keeps the process sandboxed from the rest of your system.
Download the latest Prometheus release from the official GitHub releases page at github.com/prometheus/prometheus/releases. At the time of writing, the current stable version is in the 2.x series. Extract the archive with tar xvf prometheus-.tar.gz, then copy the binaries: sudo cp prometheus-/prometheus /usr/local/bin/ and sudo cp prometheus-/promtool /usr/local/bin/. Copy the default configuration directories as well: sudo cp -r prometheus-/consoles /etc/prometheus and sudo cp -r prometheus-*/console_libraries /etc/prometheus. Set ownership on those copied files to your prometheus user before moving on.
Node Exporter is a separate binary that exposes hardware and OS-level metrics – CPU, memory, disk, network – in a format Prometheus can scrape. Download it from github.com/prometheus/node_exporter/releases, extract it, and copy the binary to /usr/local/bin/node_exporter. Create another system user named node_exporter using the same useradd command pattern as before. Node Exporter runs on port 9100 by default, and you can verify it is working by visiting http://your-server-ip:9100/metrics in a browser once you start the service.

Configuring Prometheus and Setting Up Grafana
Prometheus needs a configuration file to know what to scrape and how often. Create /etc/prometheus/prometheus.yml and add the following structure. The global block sets the default scrape interval – 15 seconds is a reasonable starting point for most setups. Under scrape_configs, define two jobs: one named prometheus that scrapes Prometheus itself at localhost:9090, and one named node that scrapes Node Exporter at localhost:9100. The YAML must be indented correctly or Prometheus will refuse to start, so run promtool check config /etc/prometheus/prometheus.yml before doing anything else. Set file ownership to the prometheus user after saving.
Create a systemd service file at /etc/systemd/system/prometheus.service with the following content: set User and Group to prometheus, and set ExecStart to /usr/local/bin/prometheus –config.file=/etc/prometheus/prometheus.yml –storage.tsdb.path=/var/lib/prometheus/ –web.console.templates=/etc/prometheus/consoles –web.console.libraries=/etc/prometheus/console_libraries. Do the same for Node Exporter with its own service file pointing to the node_exporter binary. Run sudo systemctl daemon-reload, then enable and start both services. Prometheus will now be accessible at port 9090, where you can run basic PromQL queries directly in the built-in expression browser. If you plan to expose these dashboards to the internet, putting them behind a reverse proxy – such as Caddy with HTTPS – is strongly recommended before opening any ports.
Grafana installation on Debian-based systems is straightforward through the official APT repository. Add the GPG key with wget -q -O – https://packages.grafana.com/gpg.key | sudo apt-key add –, add the repository to your sources list, then run sudo apt update && sudo apt install grafana. Enable and start the grafana-server service. Grafana runs on port 3000 by default, and the initial login credentials are admin for both username and password – change this immediately after first login. Once inside, go to Configuration > Data Sources, add Prometheus, and point the URL to http://localhost:9090. Click Save and Test. If the connection succeeds, Grafana is now reading live data from your Prometheus instance.
Building Your First Dashboard
With data flowing, the fastest way to get a useful dashboard is to import a pre-built one from Grafana’s public dashboard library. Dashboard ID 1860 is the Node Exporter Full dashboard – it covers CPU usage, load averages, memory consumption, disk I/O, and network throughput in a single view. Go to Dashboards > Import, enter the ID, select your Prometheus data source when prompted, and click Import. You will have a fully populated infrastructure dashboard within seconds, no manual panel configuration required. From there, you can duplicate panels, adjust time ranges, and create custom alerts based on thresholds that actually matter to your workload.

Alerts in Grafana are configured through the Alerting menu, where you define conditions – for example, triggering a notification when available memory drops below 10% for more than five minutes. Grafana can route alerts through email, Slack, PagerDuty, or a webhook, depending on what contact points you configure. The alerting engine evaluates conditions at intervals you set, and alert state history is stored directly in Grafana’s own database. One limitation worth knowing upfront: Grafana’s built-in alerting evaluates only queries against data sources, not the health of Prometheus itself – if your Prometheus instance goes down, Grafana goes silent rather than alarmed, which makes monitoring the monitor a separate and genuinely necessary task.





