Uptime Kuma Setup: Free Website Monitoring on a VPS

Uptime Kuma is a free, self-hosted monitor. Run louislam/uptime-kuma:2 in Docker on a second VPS, add HTTP and SSL checks, and get alerts on Telegram or email.
Most small businesses find out their website is down from a customer. That's the worst way to find out: the customer already left, and you don't know how long it's been broken. A monitor checks your site every minute and tells you within a minute or two. Uptime Kuma does that for free on your own server, with a clean dashboard, dozens of notification channels and a public status page. Here's how I set it up for clients, including the parts guides usually skip: where to run it, the WebSocket proxy settings, and push monitors for cron jobs and backups.
Key takeaways
- Run the monitor somewhere else. A monitor on the same server as your site goes down with it and can't tell you anything.
- Use the version 2 image (
louislam/uptime-kuma:2). Version 2.0 came out in October 2025; v1 installs need a one-way database migration when upgrading. - Bind it to 127.0.0.1 and put Nginx with HTTPS in front. The dashboard uses WebSockets, so the proxy needs the
Upgradeheaders. - Monitor more than the homepage: a keyword check on a key page, the API health endpoint, SSL expiry, and push monitors for backups and cron jobs.
- Test every notification channel before you trust it.
Where should Uptime Kuma run?
Not on the server it watches. If that server runs out of memory or loses its network, the monitor dies too and you get silence instead of an alert. Good options:
- A small, separate VPS, ideally with a different provider or region from your main server. Uptime Kuma is light; the smallest plan most providers sell is enough for dozens of monitors.
- A server you already have for something else, as long as it's not the one being monitored.
- Two monitors watching each other if you run several servers: each one's Uptime Kuma checks the other.
Install Uptime Kuma with Docker Compose
On a fresh Ubuntu server with Docker installed, create a folder and a compose.yaml:
mkdir -p ~/uptime-kuma && cd ~/uptime-kuma
cat > compose.yaml <<'EOF'
services:
uptime-kuma:
image: louislam/uptime-kuma:2
container_name: uptime-kuma
restart: unless-stopped
ports:
- "127.0.0.1:3001:3001"
volumes:
- ./data:/app/data
EOF
docker compose up -d
docker compose logs -f --tail=50
Note 127.0.0.1:3001. If you publish the port as plain 3001:3001, Docker opens it to the whole internet even when UFW says it's blocked. I explained why in Docker bypasses UFW. The ./data folder holds the SQLite database with all your monitors and history, so it's the one thing to back up.
Put Nginx and HTTPS in front
Point a subdomain such as status.example.com at the monitoring server, then add an Nginx site:
server {
server_name status.example.com;
location / {
proxy_pass http://127.0.0.1:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Then sudo nginx -t && sudo systemctl reload nginx and get a certificate with sudo certbot --nginx -d status.example.com. Without the two WebSocket lines the dashboard loads but stays stuck on a spinner, which is the most common setup problem. Open the site, create the admin account straight away (the first visitor gets to create it), and turn on two-factor authentication in Settings → Security.
Which monitors to add
HTTP(s) with a keyword
A plain HTTP check passes as long as the server answers with a 2xx status. A broken app can still return 200 with an error page. Use the HTTP(s) - Keyword type and pick a word that only appears when the page really works, like your product name in the page footer or the "Add to cart" text. Check every 60 seconds and set retries to 2 or 3 so one slow response doesn't wake you up.
API health endpoint
If you have an API, monitor its health route separately (this site's API has /api/v1/health). The website can be up while the API behind it is down, and the error looks completely different to users.
SSL certificate expiry
In an HTTPS monitor's advanced settings, turn on certificate expiry notification. You'll get warned days before a certificate expires, which catches a broken Certbot renewal long before visitors see a browser warning. If that happens, my Certbot renewal fix guide covers the usual causes.
TCP port and ping
For things that aren't websites, such as a mail server on port 587 or a database that should only be reachable from your app server, a TCP port check tells you whether it's accepting connections.
Push monitors for cron jobs and backups
This is the most underused feature. A push monitor flips the direction: Uptime Kuma gives you a URL and expects it to be called on a schedule. If your nightly backup doesn't call it, you get an alert. Add a curl to the end of the job:
0 2 * * * /opt/scripts/backup.sh && curl -fsS -m 10 "https://status.example.com/api/push/AbC123?status=up&msg=OK" > /dev/null
Because of the &&, the ping only happens when the backup succeeds. Set the monitor's heartbeat interval slightly longer than the job's schedule. Backups that silently stopped months ago are a common discovery during an outage; this catches them the first night. If a cron job never runs at all, see why cron jobs don't run.
Set up notifications that actually reach you
Under Settings → Notifications, add at least one channel and press Test. Popular choices:
- Telegram: create a bot with @BotFather, paste the token and your chat ID. Fast and free; my default.
- Email (SMTP): works with any mail provider. Fine for a second channel, but too easy to miss for urgent alerts.
- Slack, Discord, Microsoft Teams: good when a team shares on-call duty.
- ntfy or Pushover: phone push notifications that can override do-not-disturb.
Use the "Default enabled" and "Apply on all existing monitors" switches so new monitors don't end up with no alerts at all. Two channels are better than one: if the email provider has an outage, Telegram still works.
Add a public status page
Status Pages → New lets you publish a page with the monitors you choose. Point status.yourdomain.com at it and link it from your support page. During an incident it answers "is it just me?" for customers and cuts down support messages. You can post incident notes on it while you work on the fix.
Keep the monitor healthy
- Back up the
datafolder. A nightly copy offsite is enough. My Linux backup guide shows how. - Update with
docker compose pull && docker compose up -d. The:2tag follows the latest 2.x release. Coming from v1, read the official v1 to v2 migration notes and back up first, because the database migration can't be undone. - Prune old data in Settings → Monitor History if the database grows large.
- Watch the watcher: add the Uptime Kuma server itself as a monitor somewhere else, even a free external checker.
When an alert does fire, my website down troubleshooting checklist walks through the first ten minutes.
Frequently asked questions
Is Uptime Kuma free?
Yes. It's open source under the MIT licence and free to self-host. Your only cost is the small server it runs on.
How often should Uptime Kuma check my website?
Every 60 seconds with 2 or 3 retries is a good default for a business website. Shorter intervals add noise without helping much, and longer ones mean you hear about outages later.
Why is the Uptime Kuma dashboard stuck loading behind Nginx?
The dashboard uses WebSockets. Add proxy_http_version 1.1 and the Upgrade and Connection "upgrade" headers to the Nginx location that proxies to port 3001, then reload Nginx.
Can Uptime Kuma monitor cron jobs and backups?
Yes, with push monitors. The job calls a unique URL when it finishes successfully, and Uptime Kuma alerts you if the call doesn't arrive within the heartbeat interval.
Should I run Uptime Kuma on the same server as my website?
No. If that server goes down, the monitor goes down with it and can't send an alert. Run it on a separate server, ideally with a different provider.
Want monitoring set up for you?
I set up Uptime Kuma or another monitor on a separate server, with keyword checks, SSL expiry, backup heartbeats, a status page and tested alerts to your phone. See my server and website monitoring service, my Linux system admin services, or contact me with the sites and servers you want watched.
Written by
MD Rakibul Islam Rakib
Full-stack developer, DevOps engineer and Linux system administrator with 5+ years of production experience. I deploy, harden and fix servers and web apps for clients worldwide, and everything in this article runs on real servers I manage, including this site.
- Uptime Kuma
- website monitoring
- uptime monitoring
- self-hosted monitoring
- Docker Compose
- push monitor
- status page


