For a long time, I treated monitoring like one of those advanced homelab topics that belonged to a later version of me.
The imagined sequence was always the same. First I would build the infrastructure. Then I would stabilize it. Then I would organize it. Then, somewhere further down the road, I would earn the right to care about dashboards, exporters, and metrics.
That way of thinking delayed visibility far longer than it should have.
What finally changed for me was realizing that monitoring is not a decorative layer you add after a setup becomes serious. It is one of the things that makes a setup feel serious in the first place. A good monitoring stack changes your relationship with the machines. You stop logging in just to ask whether something feels wrong. You start seeing the answer before the question turns stressful.
That is exactly why Prometheus, Grafana, and Node Exporter clicked for me.
The stack is easier to understand than its reputation suggests:
- Node Exporter exposes Linux host metrics.
- Prometheus scrapes and stores those metrics.
- Grafana turns them into dashboards you can actually read.
Once I stopped imagining a giant observability project and started thinking in those three sentences, the whole thing became much calmer.
- Why monitoring changed the way I run a homelab
- What Prometheus, Grafana, and Node Exporter each do
- Where I would run this stack in a small homelab
- How to get Node Exporter exposing metrics
- How to point Prometheus at those hosts
- How to connect Grafana and build the first useful dashboard
For the technical baseline below, I use Prometheus's official documentation and separate documented platform behavior from my own placement and operating recommendations.
The stack makes sense once each component has one job
The official Prometheus Node Exporter guide describes Node Exporter as the exporter that exposes hardware- and kernel-related metrics from Unix-like systems. That is the host-level visibility piece. It gives Prometheus something concrete to scrape from each machine, usually over port 9100.
Prometheus itself is the collector and time-series database. The official configuration documentation frames it very clearly: Prometheus uses a configuration file to define scrape jobs and their targets. In other words, it decides what to poll, how often to poll it, and where the resulting metrics live.
Grafana is the reading layer. The official Grafana documentation also keeps this refreshingly plain: Grafana includes built-in support for Prometheus, so once the data source is configured, you can build dashboards and query the metrics without needing a separate plugin just for that core connection.
That division of labor is why the trio feels so durable:
- exporters expose;
- Prometheus collects;
- Grafana explains.
When that clicked for me, the stack stopped feeling like "monitoring tooling" and started feeling like a very understandable flow of responsibility.
In a small homelab, I would keep the layout boring on purpose
If you are just starting, I would avoid designing this like an observability platform and instead keep it intentionally plain.
My preferred small-homelab mental model looks like this:
- One Debian VM or LXC dedicated to monitoring tools.
- Prometheus running there.
- Grafana running there too, at least initially.
- Node Exporter installed on the Linux hosts you want to watch.
That is enough.
Could you separate Grafana and Prometheus? Yes. Could you add other exporters, long-term retention, remote storage, alert routing, and provisioning-as-code later? Absolutely. But the first version should answer a simpler question:
"Can I see the health of my infrastructure from one place without guessing?"
If the answer becomes yes, the first version has already done its job.
For Proxmox-heavy homelabs, I particularly like keeping the monitoring VM separate from the main host it observes when possible. Even if the whole environment is still local, a little separation makes the visibility feel more trustworthy. If the host is struggling, I do not want the only monitoring view to disappear with it.
Step 1: get Node Exporter running on the hosts you care about
This is the cleanest place to begin because it gives immediate feedback.
The official Node Exporter guide demonstrates a very portable flow: download the release for your platform, extract it, run the binary, and confirm that metrics are exposed on port 9100. That guide also shows the first useful validation step:
curl http://localhost:9100/metrics
If you can hit the /metrics endpoint, you have crossed the most important early threshold. The host is now exposing useful telemetry in a format Prometheus understands.
The official guide also points out that Node Exporter metrics are usually prefixed with node_, which makes them easy to recognize once you start querying them.
In a real homelab, I usually care about starting with just a few machines:
- the monitoring VM itself;
- the main Proxmox host or hosts;
- a NAS or backup machine;
- one Docker or application VM if it carries important services.
That is enough to make the dashboard feel meaningful.
If you prefer distro packages or service units, that is fine too, but I still like the official guide’s simple binary-first mental model because it makes the exporter feel less mysterious. However you install it, the outcome should be the same:
- the service is up;
- port
9100is reachable from Prometheus; - the
/metricsendpoint returns data.
Step 2: teach Prometheus what to scrape
This is where the stack becomes real.
The official Prometheus documentation shows the core pattern plainly: define a scrape_interval, then define one or more scrape_configs with targets. Even a small configuration is enough to make the whole system useful.
For a first homelab setup, I would keep the configuration close to this shape:
global:
scrape_interval: 15s
scrape_configs:
- job_name: prometheus
static_configs:
- targets:
- localhost:9090
- job_name: node
static_configs:
- targets:
- monitor01.lan:9100
- proxmox01.lan:9100
- nas01.lan:9100
- app01.lan:9100
This is not fancy, and that is one reason I like it.
You can read it without squinting:
- Prometheus also watches itself.
- It scrapes a handful of hosts.
- Every host exposes Node Exporter on the same port.
That kind of legibility matters. A lot of bad monitoring setups are technically powerful but emotionally annoying. If the configuration already feels abstract at the beginning, it becomes harder to trust later.
The official Prometheus configuration documentation also notes that Prometheus can reload its configuration at runtime. That becomes useful once your host list starts changing, but early on I would not overcomplicate discovery. Static targets are perfectly respectable in a small homelab.
Step 3: start Prometheus and make sure it is actually scraping
The official Prometheus getting started documentation shows the basic pattern: run Prometheus with a --config.file argument that points at your prometheus.yml.
Once it is up, the first thing I care about is not dashboard beauty. It is target health.
Before touching Grafana, I want to see that Prometheus can reach the exporters. If a target is down, that is better discovered here than later through a blank panel that looks like a visualization problem but is really just a scrape problem.
This is the stage where the stack starts teaching useful discipline:
- name hosts consistently;
- keep DNS or host resolution tidy;
- avoid pretending "up enough" means healthy;
- make each exporter testable before layering more tooling on top.
That same operational mindset is part of why early post-install cleanup on Proxmox matters so much. Clear monitoring does not replace infrastructure discipline. It rewards it.
Step 4: install Grafana on the monitoring box
Grafana is the part most people imagine first because it is visual, but I think it becomes much easier once Prometheus is already working.
The current Grafana documentation for Debian and Ubuntu describes three supported installation paths: the APT repository, a .deb package, or a standalone binary tarball. For a normal Debian-based homelab VM, I would keep it simple and use the official APT repository path.
The rough flow looks like this:
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
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 grafana
From there, start the Grafana server using your preferred service management flow and confirm that the web UI loads.
I like this stage because it is where the stack stops being abstract. You go from "I know metrics exist" to "I now have a place to read them."
Step 5: add Prometheus as a Grafana data source
The official Grafana Prometheus data source documentation makes one important point very clearly: Prometheus support is built in, so you do not need an extra plugin just to connect Grafana to Prometheus.
That matters because the first setup should feel direct, not plugin-driven.
The essential move is simple:
- Add a new connection in Grafana.
- Choose
Prometheus. - Set the Prometheus server URL.
- Click
Save & test.
If Prometheus is running on the same monitoring VM as Grafana, the URL is often:
http://localhost:9090
If it lives elsewhere, use the real hostname or IP with port 9090.
Grafana’s documentation also makes a practical warning that is easy to overlook: when Grafana and Prometheus run in separate containers, localhost only refers to the local namespace of each container. That is one of those tiny details that saves unnecessary confusion. It is exactly the kind of nuance monitoring teaches you to respect early.
Step 6: build the first dashboard around questions, not around ambition
This is where I think many homelab dashboards go wrong.
People often begin with a blank page and feel pressure to produce something impressive. The result is usually either clutter or imitation. Panels multiply faster than understanding.
I would start with the smallest dashboard that answers useful daily questions.
For me, the first panels would usually be:
- CPU usage by host;
- memory usage by host;
- filesystem usage on important volumes;
- network throughput;
- system load;
- uptime or host reachability.
That is enough to make the dashboard feel alive.
If you want to go a step further, add panels for temperatures and fans only after you have verified that those readings are actually being exposed cleanly. I wrote more specifically about that path in monitoring Proxmox host thermals, because thermal visibility often needs extra sensor work beyond a plain Node Exporter baseline.
If it answers the daily health questions clearly, it is already doing more useful work than a huge dashboard full of panels you do not actually trust or revisit.
Conclusion
Prometheus, Grafana, and Node Exporter finally made homelab monitoring feel approachable to me because they replaced the vague idea of "observability" with a simple chain I could understand. Hosts expose metrics. Prometheus scrapes them. Grafana makes them readable.
That is enough to start.
You do not need a giant stack. You do not need twenty exporters on day one. You do not need a beautiful NOC wall. You just need one place that tells the truth about what your machines are doing before the truth becomes inconvenient.
That is the version of monitoring I trust most now. Not the impressive version. The useful one.



