How to Install Grafana and Prometheus on your VPS: Complete Guide 2024
A comprehensive guide for developers who want complete control and real-time monitoring of their VPS - from system metrics to container performance and everything in between.
Why use Grafana and Prometheus on your VPS
Ever wondered what's really going on inside your VPS? Grafana and Prometheus are your go-to tools for keeping tabs on your server's performance. They're a fantastic combo for indie hackers like us - they're free, open-source, and they get the job done without the overhead of enterprise solutions.
Here's what makes them a great option:
See everything in real-time: Monitor your server metrics as they happen
Pretty dashboards: Grafana turns numbers into useful charts
Zero cost: It's open-source, so no surprise bills or vendor lock-in
Large community: Tons of pre-made dashboards and help when you need it
The best part? You don't need to be a Linux wizard to set this up. If you can follow simple instructions and aren't afraid of the command line, you're good to go. Let's dive in and get your VPS properly monitored.
What you’ll need before we start
Before we dive in, let's make sure you've got the basics sorted. Nothing fancy - just Docker and a user account that can run sudo commands.
Here's your quick checklist:
A user with sudo
Docker installed and running
If you've got these three things, you're ready to go. Not sure if you have everything? Run these commands to check:
# Verify sudo access
$ sudo whoami
# Check Docker installation
$ docker --version
Setting up Prometheus & Grafana
Let's get these tools installed and running. We'll use Docker Compose to keep things clean and simple. I'll walk you through it step by step.
First, create a compose.yaml
file:
services:
prometheus:
image: prom/prometheus
ports:
- '9090:9090'
volumes:
- ./prometheus:/etc/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
restart: always
grafana:
image: grafana/grafana
ports:
- '3000:3000'
depends_on:
- prometheus
restart: always
node_exporter:
image: quay.io/prometheus/node-exporter:latest
container_name: node_exporter
command:
- '--path.rootfs=/host'
ports:
- '9100:9100'
restart: unless-stopped
volumes:
- '/:/host:ro,rslave'
This sets up three containers:
Prometheus - collects and stores your metrics
Grafana - visualises those metrics into dashboards
Node Exporter - grabs system stats like CPU and memory usage
Next, create a configuration file for Prometheus. Make a new directory called prometheus
and create a prometheus.yaml
file inside it:
global:
scrape_interval: 10s
scrape_configs:
- job_name: node
static_configs:
- targets: ['node_exporter:9100']
This tells Prometheus two things:
Collect new metrics every 10 seconds
Look for those metrics at
node_exporter:9100
(that's the Node Exporter container we defined earlier)
That's all we need for now. Prometheus will store these metrics, and we'll use Grafana to visualise them in the next step.
Accessing your monitoring stack over SSH
Time to start your monitoring stack and connect to it securely. I'll show you how to do this without exposing any of the services to the public internet.
First, start up your containers:
$ docker compose up -d
Now, we could just open these ports on our VPS firewall, but that's not the most secure approach. We’d rather keep the ports locked down, and instead connect to them over SSH, using something called port forwarding.
If you haven’t already setup a firewall on your VPS, check out my article on how to secure your VPS. The only ports that should be exposed are 22 for SSH and 80/443 for HTTP/HTTPS if you’re running a web server.
Open two terminal windows on your local machine and run these commands (replace user@12.34.45.67
with your VPS details):
# Terminal 1 - Grafana tunnel
$ ssh -N -L 3000:127.0.0.1:3000 user@12.34.45.67
# Terminal 2 - Prometheus tunnel
$ ssh -N -L 9090:127.0.0.1:9090 user@12.34.45.67
This creates secure tunnels from your computer to your VPS. Now you can access everything through your browser on your local machine at:
Grafana: http://localhost:3000
Prometheus: http://localhost:9090
Let's make sure everything's working. Open Prometheus at http://localhost:9090
in your browser, click Status > Targets. You should see your node exporter listed as "UP" - that means Prometheus is successfully collecting your system metrics.
Looking good? Let's set up Grafana next.
Connecting Grafana to your data
Let's get Grafana talking to Prometheus. First thing's first - log into Grafana:
Open
http://localhost:3000
in your browserUse these default credentials:
Username:
admin
Password:
admin
Set a new, strong password when prompted - especially important if you ever plan to expose this to the internet
Now, let's point Grafana to your Prometheus data:
Click Connections > Data sources in the left sidebar
Hit Add data source
Choose Prometheus from the list
For the URL, enter
http://prometheus:9090
Scroll down and click Save & test
You should see a green success message. If you do, congrats! Grafana can now see all your metrics. If not, double-check that URL - the most common gotcha is using localhost
instead of prometheus
as the hostname.
Creating your first dashboard
Rather than building a dashboard from scratch (which takes time), let's grab a pre-made one that works perfectly with our Node Exporter.
Here’s how:
Click Dashboards in the left sidebar
Hit New > Import in the top right
Enter
1860
- this is the ID for the dashboard template Node Exporter FullClick Load
Give your dashboard a name if you want, or keep the default
Select your Prometheus data source from the dropdown at the bottom
Click Import
You should now see a complete dashboard showing all sorts of system metrics: CPU usage, memory, disk space, network traffic, basically everything you would ever need to monitor host-level resources.
Adding Docker metrics to your dashboard
Since we're running everything in Docker anyway, let's monitor our containers too. We'll tell Docker to expose its metrics and get Prometheus to collect them.
First, let's configure Docker to make its metrics available:
# Create or edit the Docker daemon config
$ sudo vim /etc/docker/daemon.json
# Add this configuration
{
"metrics-addr": "0.0.0.0:9323"
}
# Restart Docker to apply changes
$ sudo systemctl daemon-reload
Quick test to make sure it's working:
$ curl localhost:9323/metrics
You should see a bunch of metrics like builder_builds_failed_total
and others.
Here comes the tricky part - if you're using UFW with ufw-docker
(as I recommend to do in my Docker article), we need to allow Prometheus talk to Docker. We'll do it safely such that inbound traffic to Docker is only allowed by internal IPs:
# Allow Docker's internal network to access the metrics
$ sudo ufw allow from 172.16.0.0/12 to any port 9323
$ sudo ufw reload
💡 Quick networking note: 172.16.0.0/12 is Docker's internal network range. We're only allowing connections from inside this network, so it cannot be accessed from the public internet.
Now let's tell Prometheus about these new metrics. Edit your Prometheus config:
$ vim prometheus/prometheus.yaml
Add this under scrape_configs
:
- job_name: docker
static_configs:
- targets: ['host.docker.internal:9323']
We also need to modify our compose.yaml
file to tell Prometheus about this special Docker host:
$ vim compose.yaml
# add the following as a direct child under the prometheus service
extra_hosts:
- "host.docker.internal:host-gateway"
Restart Prometheus to pick up the changes:
$ docker compose restart prometheus
To verify everything's working, check http://localhost:9090/targets
- you should see a Docker target marked as "UP".
Creating a custom dashboard
Let's make a simple dashboard to monitor your Docker containers. We'll build this one from scratch.
Here's how:
Go to Dashboards and click New > New dashboard
Click the big + Add visualization button
Pick Prometheus as your data source
Change the visualization type from Time series to Stat in the top right
In the query box at the bottom, paste this:
engine_daemon_container_states_containers
Under Options, find the Legend section and set it to Custom with value
{{state}}
Hit Run queries
You should now see a clean visualisation showing how many containers you have running, paused, or stopped. Neat, right?
💡 Want to explore more Docker metrics? Head to Prometheus at
http://localhost:9090/graph
and try this query:{job="docker"}
. This shows you every Docker metric available to interact with!
Give your dashboard a name, hit save, and you're done! Feel free to experiment - add more panels, try different visualisations, or even add exporters for metrics from other systems. That's the good part about Grafana and Prometheus - you can customise everything to show exactly what you want to see.
And that’s a wrap
You've just set up a proper monitoring system for your VPS - pat yourself on the back! Yes, it took a bit more work than clicking an install button, but now you've got something super flexible up and running.
Here's what you've accomplished:
Got Prometheus, Grafana, and Node Exporter running using Docker Compose
Set up Docker to expose its own metrics
Configured your firewall safely to allow internal collection of Docker metrics
Got Prometheus collecting metrics from both your system and Docker
Set up two dashboards:
A pre-made one for host-level metrics
A custom one for Docker stats
💡 Pro tip: If you’re feeling adventurous, look into Prometheus alerting. You can set up alerts for things like high CPU usage, low disk space, when containers crash, and much more.
Your VPS is no longer a black box - you can now see exactly what's going on inside it. Happy self-hosting!