Introduction
Uptime Kuma is a self-hosted monitoring tool that tracks the availability of websites, APIs, TCP ports, DNS records, and more. It's the modern open-source alternative to services like UptimeRobot, featuring a clean dashboard, SSL certificate monitoring, and multi-channel notifications. This guide teaches you how to deploy and configure it for production infrastructure monitoring.
Why Uptime Kuma Over Commercial Services?
- Privacy: All data stays on your servers, no third-party data sharing
- Cost: Free vs $20-100/month for commercial alternatives
- Customization: Configure any check type, any interval
- Integrations: 90+ notification channels (Slack, Telegram, PagerDuty, webhooks)
- Status Pages: Build public/private status pages for your services
Deploying with Docker
# Simple single-container deployment
docker run -d --name uptime-kuma --restart unless-stopped -p 3001:3001 -v uptime-kuma:/app/data louislam/uptime-kuma:1
# Access at http://your-server:3001
# Create admin account on first visitDocker Compose for production:
# docker-compose.yml
version: '3.8'
services:
uptime-kuma:
image: louislam/uptime-kuma:1
container_name: uptime-kuma
restart: unless-stopped
ports:
- "3001:3001"
volumes:
- ./data:/app/data
environment:
- TZ=Asia/Tehran
healthcheck:
test: ["CMD", "node", "/app/extra/healthcheck.js"]
interval: 30s
timeout: 10s
retries: 3
# Optional: nginx reverse proxy with SSL
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./ssl:/etc/ssl/certs
depends_on:
- uptime-kumaNginx configuration for SSL termination:
# nginx.conf
server {
listen 443 ssl;
server_name status.company.com;
ssl_certificate /etc/ssl/certs/company.crt;
ssl_certificate_key /etc/ssl/certs/company.key;
location / {
proxy_pass http://uptime-kuma:3001;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
# Required for WebSocket (Uptime Kuma uses WS for real-time updates)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}Monitor Types and Configuration
HTTP/HTTPS Monitor:- URL:
https://app.company.com/api/health - Method: GET or POST
- Expected status: 200
- Keywords to check in response:
"status":"ok" - Check interval: 60 seconds
- Timeout: 30 seconds
- Use for: databases (5432), SMTP (25), custom apps
- Host:
db.company.com - Port:
5432 - Interval: 60s
- Check if DNS resolves correctly
- Hostname:
app.company.com - Expected value:
203.0.113.10 - DNS resolver:
8.8.8.8
- Monitors certificate expiry
- URL:
https://app.company.com - Alert when cert expires in < 14 days
- Connect Uptime Kuma to Docker socket to monitor container health
- Container name:
web-app - Checks Docker health status
Setting Up Notifications
# Telegram Notification Setup:
1. Create a bot via @BotFather → get TOKEN
2. Send a message to your bot, then visit:
https://api.telegram.org/bot<TOKEN>/getUpdates
3. Find your chat_id in the response
4. In Uptime Kuma: Settings → Notifications → Add → Telegram
Bot Token: 123456:ABC...
Chat ID: -100123456789 (negative = group)Webhook notification for custom integrations:
# Uptime Kuma sends JSON payload to your webhook URL:
{
"heartbeat": {
"monitorID": 1,
"status": 0, # 0=down, 1=up
"time": "2024-01-15T10:30:00.000Z",
"msg": "Connection refused",
"ping": 0,
"duration": 0
},
"monitor": {
"id": 1,
"name": "Production API",
"url": "https://api.company.com/health",
"type": "http",
"active": true
},
"msg": "Production API is down - Connection refused"
}Status Pages
# Creating a public status page:
1. Uptime Kuma → Status Pages → New Status Page
2. Configure:
- Slug: "status" (accessible at /status/status)
- Title: "Company Services Status"
- Description: "Real-time status of our infrastructure"
- Logo URL: https://company.com/logo.png
3. Add monitors to display (can group them):
Group: "Web Services"
- Production Website
- API Endpoint
Group: "Backend"
- Database
- Cache (Redis)
4. Toggle "Public" to make it accessible without loginUptime Kuma API for Automation
#!/usr/bin/env python3
# uptime_kuma_api.py - Automate monitor management
from uptime_kuma_api import UptimeKumaApi, MonitorType
api = UptimeKumaApi("http://localhost:3001")
api.login("admin", "your-password")
# Add a new HTTP monitor
monitor = api.add_monitor(
type=MonitorType.HTTP,
name="New Microservice",
url="https://microservice.internal/health",
interval=60,
retryInterval=30,
maxretries=3,
notificationIDList=[1, 2], # Notification IDs to use
keyword="healthy", # Check for this keyword in response
timeout=30,
)
print(f"Created monitor: {monitor['monitorID']}")
# List all monitors and their status
monitors = api.get_monitors()
for m in monitors:
status = "UP" if m.get('active') else "PAUSED"
print(f"{m['name']}: {status}")
# Pause a monitor during maintenance
api.pause_monitor(monitor_id=5)
# Resume after maintenance
api.resume_monitor(monitor_id=5)
api.disconnect()Backup and Restore
# Backup: just copy the data directory
docker stop uptime-kuma
tar czf uptime-kuma-backup-$(date +%Y%m%d).tar.gz ./data/
docker start uptime-kuma
# Restore:
docker stop uptime-kuma
tar xzf uptime-kuma-backup-20240115.tar.gz
docker start uptime-kuma
# Automated backup with cron
# /etc/cron.daily/backup-uptime-kuma
#!/bin/bash
cd /opt/uptime-kuma
docker stop uptime-kuma
tar czf /backup/uptime-kuma-$(date +%Y%m%d).tar.gz ./data/
docker start uptime-kuma
find /backup -name "uptime-kuma-*.tar.gz" -mtime +30 -deleteAlerting Best Practices
Configure monitors with appropriate sensitivity:
- Critical services (public website, payment API): interval=30s, maxretries=1
- Internal services: interval=60s, maxretries=3
- Background jobs: interval=300s, maxretries=5
Use heartbeat monitors for cron jobs:
# In your cron job, send a ping to Uptime Kuma after success
*/5 * * * * /opt/scripts/backup.sh && curl -s "https://uptime.company.com/api/push/AbCdEfGh1234?status=up&msg=OK&ping=0"Uptime Kuma transforms reactive firefighting into proactive monitoring. With proper setup, you'll know about outages before your users do, and have historical uptime data to back up your SLA reports.
