If you run websites, services, or APIs, having a public status page is essential. Customers and staff want to know if your services are up, and you need monitoring that can alert you quickly when something goes down. The good news is that you don’t need expensive commercial services like Statuspage or Pingdom. Or Uptime Robot – which is not only no longer free but is jacking up prices 425%.
With a $1 VPS and an open-source tool called Uptime Kuma, you can have a professional-looking status page in minutes.
What is Uptime Kuma?
Uptime Kuma is a self-hosted monitoring tool that lets you monitor websites, servers, and network services (HTTP, TCP, ping, DNS, etc.). You can send alerts via email, Telegram, Slack, Discord, and many other integrations, and host a public-facing status page with uptime history.
What Do You Need?
A basic VPS with 1GB RAM and 10GB storage is more than enough for Uptime Kuma. Many of the providers featured on LowEndBox offer these low-cost plans. We even have a page full of $1 per month offers!
Don’t feel like doing the setup and maintenance yourself? Run Uptime Kuma on PikaPods from $1.70/month!
Step 1: Get Your VPS Ready
This guide assumes you have a fresh Debian 12 VPS. Mine is going to be called kuma.lowend.party and I’ll use it to monitor LowEndBox and LowEndTalk.
Starting with a fresh install, login as root and install Docker:
apt update && apt -y upgrade
apt -y install docker.io docker-compose
systemctl enable --now docker
Step 2: Install Uptime Kuma
Create a directory:
mkdir /opt/uptime-kuma && cd /opt/uptime-kuma
Create a docker-compose.yml file:
version: '3'
services:
uptime-kuma:
image: louislam/uptime-kuma:1
container_name: uptime-kuma
ports:
- "3001:3001"
volumes:
- ./data:/app/data
restart: always
Start it up:
docker-compose up -d
Step 3: Configure a Status Page
Open your browser and visit:
http://kuma.your-domain.com:3001
You’ll be prompted to create an admin account.
Once you’ve logged in, click Status Pages in the upper right.
Click “New Status Page”
On the “Add New Status Page” page, fill out Name and Slug, then Next.
Now click “Add one” in the middle of the page to create a new monitor.
The form is easy to fill out for a basic HTTPS monitor. Just add the URL and a friendly name.
After a while, you’ll see it populating with data:
Now you can go back to your Status Page and click Add a Monitor. Since there’s only one in this case, there’s only one to select.
And that’s it! Now you can share that URL. Here’s how it looks in Incognito mode, demonstrating that I’m not logged in:
Step 4: Make it Look Professional
Right now, you’re presenting on port 3001. We want to present something like https://uptime.your-domain.com without the port.
We’ll finish by proxying port 3001 and creating a Let’s Encrypt certificate so the connection is secure.
Let’s install Nginx and certbot:
apt -y install nginx certbot python3-certbot-nginx
systemctl enable --now nginx
Make sure you have DNS all set. In this example, I’ll use uptime.lowend.party.
Edit
/etc/nginx/sites-available/uptime.lowend.party
and create as follows:
server { listen 80; server_name uptime.lowend.party; location / { proxy_pass http://127.0.0.1:3001; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
Now enable the configuration:
ln -s /etc/nginx/sites-available/uptime.lowend.party /etc/nginx/sites-enabled/ nginx -t systemctl reload nginx
Next, add HTTPS via Let’s Encrypt:
certbot --nginx -d uptime.lowend.party
Follow the prompts. Your Nginx config will be automatically updated.
And now uptime.lowend.party works! No need for the port.
And https://uptime.lowend.party/status/lowendempire works as well as a public page:
There’s only one problem remaining. Uptime Kuma is still running on port 3001 on the public IP, which means that it’s a bit more exposed than I’d like it to be.
Let’s go back and edit /opt/uptime-kuma/docker-compose.yml. You only need to change one line (indicated with the <– comment below):
version: '3'
services:
uptime-kuma:
image: louislam/uptime-kuma:1
container_name: uptime-kuma
ports:
- "127.0.0.1:3001:3001" # <-- bind only to localhost
volumes:
- ./data:/app/data
restart: always
Then:
docker-compose down docker-compose up -d
Now uptime.lowend.party works, but uptime.lowend.party:3001 doesn’t, which is what we want.
Enjoy!
Leave a Reply