Uptime Kuma — self-hosted uptime monitoring and status pages
Uptime Kuma is the open-source answer to UptimeRobot / StatusCake / Pingdom — a self-hosted monitoring tool with a clean web UI, HTTP/TCP/ping/keyword checks, push notifications to 90+ services, and built-in status pages. Runs comfortably on a 1 GB VPS. This article covers the setup and the patterns for monitoring a multi-VPS fleet.
Install with Docker
# /opt/uptime-kuma/docker-compose.yml
services:
uptime-kuma:
image: louislam/uptime-kuma:1
container_name: uptime-kuma
restart: unless-stopped
volumes:
- /opt/uptime-kuma/data:/app/data
ports:
- "127.0.0.1:3001:3001"
cd /opt/uptime-kuma
docker compose up -d
Reverse proxy as usual:
# Caddy
status.example.com {
reverse_proxy localhost:3001
}
First-run: visit the URL, create an admin account.
What it monitors
- HTTP/HTTPS — full URL, response code check, optional keyword check on body.
- TCP — port-open check.
- Ping — ICMP reachability.
- DNS — confirms a specific record returns a specific value.
- Push — for monitoring things behind firewalls, your job pings Uptime Kuma with curl on success; missing pings trigger alerts (cron monitoring).
- Steam, Docker container health, MQTT, gRPC — niche, useful when needed.
Alerting
Dashboard → Settings → Notifications. Supported integrations include email (SMTP), Discord, Slack, Telegram, Pushover, Gotify, ntfy, Twilio SMS, generic webhook, and many more. Configure once per channel, attach to monitors individually.
Pragmatic alert pattern for a small fleet:
- Primary: ntfy or Pushover to your phone for everything down > 2 minutes.
- Secondary: Discord channel for the team.
- Email as backup if push notifications fail.
Status page
Settings → Status Pages → New. Drag monitors into the page, customize title/logo/announcements. Public-facing URL like https://status.example.com/status/main shows current and historical status, no login required.
For customer-facing status, this is genuinely good — better looking than rolling your own, no per-month fee.
Cron monitoring (push)
For jobs that run on a schedule (nightly backups, cron tasks), the "monitor that pings the monitor" pattern catches silent failures:
# Create a Push monitor in Uptime Kuma
# Settings → Notifications, set up your channel
# Add Monitor → Type: Push → Interval: 60s × 1.5 (check window)
# In your cron job
0 3 * * * /usr/local/bin/backup.sh && curl -fsS -m 10 https://status.example.com/api/push/<your-token>
If the backup script fails OR if the curl ping doesn't arrive within the window, Uptime Kuma fires the configured alert. Replaces "did my backup run last night" guesswork.
Monitor placement
Self-monitoring (Uptime Kuma watching the VPS it runs on) is circular — if the VPS goes down, the monitor can't tell you. Two options:
- Run Uptime Kuma on a separate small VPS from the one(s) you're monitoring. Cheap insurance.
- Pair self-hosted Uptime Kuma with a free external monitor (UptimeRobot free tier) that watches whether your status page is reachable. Catches the catastrophic case.
Backups
Uptime Kuma's data is in /app/data (mounted as /opt/uptime-kuma/data). SQLite database plus uploaded icons. Small (typically <100 MB). Restic it nightly.
Upgrade
cd /opt/uptime-kuma
docker compose pull
docker compose up -d
Read release notes between major versions; minor versions are usually drop-in upgrades with no migration steps.
Also Read
Powered by WHMCompleteSolution