How to Self-Host Uptime Kuma: Uptime Monitor and Status Page 2026
TL;DR
Uptime Kuma (MIT, ~60K GitHub stars, Node.js) is the most popular self-hosted uptime monitoring tool — a drop-in replacement for Uptime Robot or Freshping. It monitors HTTP endpoints, TCP ports, DNS records, Docker containers, and more, then sends alerts via Slack, Discord, Telegram, email, and 90+ other notification channels. The built-in status page feature lets you publish a public status page for your users. Uptime Robot costs $7/month for 50 monitors; Uptime Kuma is free with unlimited monitors.
Key Takeaways
- Uptime Kuma: MIT, ~60K stars — most popular self-hosted uptime monitor
- Monitor types: HTTP(S), TCP, Ping, DNS, Docker, Push (heartbeat), Keyword, JSON Query
- 90+ notifications: Slack, Discord, Telegram, PagerDuty, email, ntfy, Mattermost, and more
- Status pages: Public or password-protected status pages for your services
- Dashboard: Beautiful real-time dashboard with response time graphs
- Certificate monitoring: Alerts when SSL certs are about to expire
Uptime Kuma vs Alternatives
| Feature | Uptime Kuma | Uptime Robot Free | Freshping Free |
|---|---|---|---|
| License | MIT | Proprietary | Proprietary |
| Cost | Free (hosting) | Free (50 monitors) | Free (50 monitors) |
| Monitor interval | 20s min | 5 min | 1 min |
| Monitor types | 12+ | HTTP, TCP, Ping | HTTP, TCP |
| Notifications | 90+ | Email, SMS, Slack | Email, Slack |
| Status pages | Unlimited | 1 | 1 |
| SMS alerts | Via Twilio | Yes ($) | No |
| Data retention | Unlimited | 2 months | 30 days |
| Self-hosted | Yes | No | No |
Part 1: Docker Setup
# docker-compose.yml
services:
uptime-kuma:
image: louislam/uptime-kuma:latest
container_name: uptime-kuma
restart: unless-stopped
ports:
- "3001:3001"
volumes:
- uptime_kuma_data:/app/data
- /var/run/docker.sock:/var/run/docker.sock:ro # For Docker container monitoring
volumes:
uptime_kuma_data:
docker compose up -d
Visit http://your-server:3001 → create admin account.
Part 2: HTTPS with Caddy
status.yourdomain.com {
reverse_proxy localhost:3001
}
Part 3: Adding Monitors
Click + Add New Monitor:
HTTP(S) Monitor
Most common — checks that a URL returns a success response:
Monitor Type: HTTP(S)
Name: Nextcloud
URL: https://cloud.yourdomain.com
Heartbeat Interval: 60 seconds
Retries: 3
Keyword: "Nextcloud" # Optional: ensure page contains this text
TCP Port Monitor
Check that a port is open (databases, SSH, custom services):
Monitor Type: TCP Port
Name: PostgreSQL
Host: db.yourdomain.com
Port: 5432
Docker Container Monitor
Ensure a container is running:
Monitor Type: Docker Container
Name: Vaultwarden
Container Name/ID: vaultwarden
Docker Host: /var/run/docker.sock
DNS Monitor
Check DNS resolution:
Monitor Type: DNS
Name: Main Domain DNS
Hostname: yourdomain.com
Resolver Server: 1.1.1.1
DNS Record Type: A
Push Monitor (Heartbeat)
For scheduled jobs — they ping Uptime Kuma to confirm they ran:
Monitor Type: Push
Name: Daily Backup Job
The push URL: https://status.yourdomain.com/api/push/your-unique-token
In your backup script:
# Ping Uptime Kuma after successful backup:
curl "https://status.yourdomain.com/api/push/your-unique-token?status=up&msg=OK"
If the heartbeat isn't received, Uptime Kuma alerts.
Part 4: Notifications
Configure alerts → Settings → Notifications → Add Notification:
Slack
Notification Type: Slack
Name: Slack Alerts
Webhook URL: https://hooks.slack.com/services/YOUR/WEBHOOK
Channel: #alerts
Username: Uptime Kuma
Discord
Notification Type: Discord
Webhook URL: https://discord.com/api/webhooks/YOUR/WEBHOOK
Email (SMTP)
Notification Type: Email
From: noreply@yourdomain.com
SMTP Host: smtp.yourdomain.com
SMTP Port: 587
Username: noreply@yourdomain.com
Password: your-password
To: ops@yourdomain.com
ntfy (Self-Hosted Push)
Notification Type: ntfy
Server URL: https://ntfy.yourdomain.com
Topic: uptime-alerts
PagerDuty
Notification Type: PagerDuty
Integration Key: your-integration-key
Priority: high
After setting up a notification channel, assign it to monitors — individual monitors can have different alert channels.
Part 5: Status Pages
Create a public status page for your users:
- Status Pages → + New Status Page
- Name: "Service Status"
- Slug:
status→ URL:https://status.yourdomain.com/status/status - Add monitors to display
- Group monitors into sections:
- "API Services" → api.yourdomain.com, auth.yourdomain.com
- "User Facing" → app.yourdomain.com, www.yourdomain.com
- Publish — share the URL with users
Custom domain for status page:
# Separate status domain:
mystatus.yourdomain.com {
reverse_proxy localhost:3001
rewrite * /status/mystatus{uri}
}
Password protection:
- Toggle "Enable Password" on the status page settings
Part 6: Certificate Expiry Monitoring
Uptime Kuma checks SSL cert expiry on HTTP monitors automatically:
- Alerts at: 14 days before expiry (default)
- Customize in monitor settings: TLS/SSL → Ignore TLS/SSL error (for self-signed)
For dedicated cert monitoring:
- Monitor Type: HTTP(S)
- URL: your site
- Under Advanced → Upside Down Mode: No
- Kuma reports cert expiry date in the dashboard
Part 7: Proxy/API Integration
Use the REST API to manage monitors programmatically:
# Get all monitors (requires session cookie or API key):
curl -X GET https://status.yourdomain.com/metrics \
--cookie "session=your-session-id"
# Uptime Kuma exposes Prometheus metrics at:
https://status.yourdomain.com/metrics
# Scrape in Prometheus:
scrape_configs:
- job_name: "uptime_kuma"
metrics_path: /metrics
static_configs:
- targets: ["status.yourdomain.com"]
basic_auth:
username: admin
password: your-password
Part 8: Maintenance Mode
Pause monitoring during planned maintenance:
- Select monitor(s)
- Pause → monitoring halts, no alerts during the pause window
Or schedule maintenance windows:
- Maintenance → New Maintenance
- Title: "Scheduled DB maintenance"
- Time window: Saturday 02:00-04:00 UTC
- Assign monitors — they won't alert during this window
Maintenance
# Update Uptime Kuma:
docker compose pull
docker compose up -d
# Logs:
docker compose logs -f uptime-kuma
# Backup data (SQLite + config):
tar -czf uptime-kuma-backup-$(date +%Y%m%d).tar.gz \
$(docker volume inspect uptime_kuma_uptime_kuma_data --format '{{.Mountpoint}}')
# Export all monitors as JSON:
# Settings → Backup → Export
See all open source monitoring and observability tools at OSSAlt.com/categories/monitoring.