You want to know your site is down before your customers tell you. Uptime Kuma is a free, self-hosted website uptime monitoring tool with a clean dashboard: it checks your sites as often as every 20 seconds and alerts you through dozens of channels.
Before you start
- A small Linux VPS with Docker installed. Ideally not the same server you monitor; if that server dies, its monitor dies with it.
- A subdomain for the dashboard, e.g.
status.example.com, pointing to the monitoring VPS.
Install Uptime Kuma with Docker Compose
Create /opt/uptime-kuma/docker-compose.yml:
services:
uptime-kuma:
image: louislam/uptime-kuma:1
container_name: uptime-kuma
restart: unless-stopped
ports:
- "127.0.0.1:3001:3001"
volumes:
- ./data:/app/dataBinding to 127.0.0.1 keeps the app off the public internet; a reverse proxy will serve it over HTTPS. Start it:
cd /opt/uptime-kuma && docker compose up -dPut it behind HTTPS
With Nginx and Certbot installed, create a site that proxies to port 3001. Uptime Kuma uses WebSockets, so include the upgrade headers:
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;
}
}Reload Nginx and run certbot --nginx -d status.example.com. Open the URL and create the admin account straight away; until you do, anyone reaching the page can claim it.
Add monitors
Click Add New Monitor and pick a type:
| Type | Use it for |
|---|---|
| HTTP(s) | Website responds with a 2xx status |
| HTTP(s) - Keyword | Page contains a word (catches "database error" pages that still return 200) |
| TCP Port | SMTP, MySQL, SSH or any port is reachable |
| Ping | Server answers ICMP |
| DNS | A record resolves to the expected value |
| Docker Container | A container on the same host is running |
Sensible defaults: interval 60 seconds, retries 2 to 3 before alerting (avoids alerts for a single blip). For HTTPS monitors tick Certificate Expiry Notification to get warned before SSL certificates expire.
Set up notifications
Go to Settings → Notifications → Setup Notification. Popular options:
- Telegram: create a bot with @BotFather, paste the bot token and your chat ID.
- Email (SMTP): use a real mailbox's SMTP details.
- Discord / Slack: paste a channel webhook URL.
Click Test, then enable Default enabled so new monitors use it automatically.
Publish a status page
Status Pages → New Status Page lets you show selected monitors publicly, for example to your clients. Add incidents and maintenance windows so visitors see planned work.
Back up and update
- Everything lives in
/opt/uptime-kuma/data; back up that folder. - Update with
docker compose pull && docker compose up -d.
Troubleshooting
- Dashboard loads but stays on "connecting": the reverse proxy is missing WebSocket upgrade headers.
- Monitor flaps between up and down: raise retries or the timeout, and check the target with
curl -Ifrom the monitoring server. - Site is blocked as a bot: firewalls or Cloudflare may challenge the monitor. Allow the monitoring server's IP.
Uptime monitoring FAQ
How often should I check my website?
Every 60 seconds suits most sites. Shorter intervals add load without much benefit.
Should the monitor run on the same server?
No. Use a separate VPS, ideally in another location, so it can report when the main server is unreachable.
Is there a hosted alternative?
Yes, services such as UptimeRobot or Better Stack offer free tiers if you prefer not to self-host.
