Skip to main content

Self-Host Uptime Kuma: Beautiful Server Monitoring 2026

·OSSAlt Team
uptime-kumamonitoringuptimestatus-pageself-hostingdocker2026

TL;DR

Uptime Kuma is the most popular self-hosted uptime monitoring tool — MIT license, ~60K GitHub stars, Node.js. It monitors HTTP/HTTPS, TCP, DNS, ping, databases, Docker containers, and more. Sends alerts via Slack, Discord, Telegram, ntfy, email, PagerDuty, and 90+ other channels. Generates a beautiful public status page. Replace BetterUptime ($20+/month), Freshping, or StatusCake with your own instance.

Key Takeaways

  • Uptime Kuma: MIT, ~60K stars, Node.js + SQLite — complete monitoring in one container
  • 90+ notification channels: Slack, Discord, Telegram, ntfy, PagerDuty, email, SMS, webhooks
  • Status page: Public status page for users (like statuspage.io, free)
  • Monitor types: HTTP, HTTPS, TCP, Ping, DNS, Database, Docker, Steam, Game servers
  • Setup time: 2 minutes with Docker
  • RAM: ~150MB idle — extremely lightweight

Uptime Kuma vs Alternatives

FeatureUptime KumaBetterUptimeUptimeRobotFreshping
LicenseMITProprietaryProprietaryProprietary
CostFree (self-hosted)$20+/monthFree (50 monitors)Free (50 monitors)
Monitor limitUnlimitedBy plan50 (free)50 (free)
Check interval20s minimum30s minimum5 min (free)1 min
Status page
Incident history3 months (free)1 month (free)
On-call scheduling
GitHub Stars~60K

Part 1: Docker Setup

# docker-compose.yml
version: '3.8'

services:
  uptime-kuma:
    image: louislam/uptime-kuma:latest
    container_name: uptime-kuma
    restart: unless-stopped
    ports:
      - "3001:3001"
    volumes:
      - uptime-kuma:/app/data
    environment:
      - TZ=America/Los_Angeles

volumes:
  uptime-kuma:
docker compose up -d

Visit http://your-server:3001 → create admin account → start adding monitors.


Part 2: HTTPS with Caddy

status.yourdomain.com {
    reverse_proxy localhost:3001
}

Part 3: Add Monitors

HTTP/HTTPS Monitor

  1. Add New Monitor
  2. Type: HTTP(s)
  3. Friendly Name: My Website
  4. URL: https://yourdomain.com
  5. Heartbeat Interval: 60 seconds
  6. Retry times: 1
  7. Check status: monitor for specific status code (200) or keywords in response

TCP Port Monitor

Type: TCP Port
Hostname: db.yourdomain.com
Port: 5432

Use for: PostgreSQL, MySQL, Redis, SMTP, anything TCP.

Docker Container Monitor

Type: Docker Container
Container Name: my-app
Docker Host: /var/run/docker.sock

Monitors if the container is running (not just the service inside).

To give Uptime Kuma access to Docker socket:

volumes:
  - /var/run/docker.sock:/var/run/docker.sock:ro

DNS Monitor

Type: DNS
Hostname: yourdomain.com
DNS Resolver Server: 1.1.1.1
Resolved Value: 1.2.3.4   # Expected A record

Alerts if DNS resolution changes — useful for detecting DNS hijacking or propagation issues.

Database Monitors

Type: PostgreSQL
Connection String: postgresql://user:pass@db:5432/myapp

Type: MySQL/MariaDB
Connection String: mysql://user:pass@db:3306/myapp

Type: Redis
Connection String: redis://redis:6379

Certificate Expiry Monitor

Type: Certificate Info
URL: https://yourdomain.com
Days Before Expiry Alert: 30

Get alerted 30 days before your SSL cert expires.


Part 4: Notification Channels

Slack

  1. Add New Notification
  2. Type: Slack
  3. Webhook URL: your Slack incoming webhook URL
  4. Channel: #alerts
Message format:
[UP] My Website is back online! ✅
[DOWN] ❌ My Website is DOWN! Response code: 500

ntfy (Self-Hosted Push)

Type: Ntfy
Server URL: https://ntfy.yourdomain.com
Topic: uptime-alerts
Priority: 5 (for down alerts), 2 (for up alerts)

Telegram

Type: Telegram
Bot Token: your-bot-token (from @BotFather)
Chat ID: your-chat-id

Email

Type: Email (SMTP)
Email To: ops-team@company.com
Host: smtp.yourdomain.com
Port: 587
Username: alerts@yourdomain.com
Password: smtp-password

Webhook (Generic — for n8n, custom scripts)

Type: Webhook
URL: https://n8n.yourdomain.com/webhook/uptime-kuma
Method: POST
Body: {"monitor": "{{name}}", "status": "{{status}}", "msg": "{{msg}}"}

Part 5: Status Page

Create a public status page for your users:

  1. Status Page → New Status Page
  2. Slug: status (accessible at https://status.yourdomain.com/status/status)
  3. Title: My Service Status
  4. Add monitors to display
  5. Set domain: status.yourdomain.com (needs CNAME or A record)

Custom Status Page Domain

status.yourdomain.com {
    reverse_proxy localhost:3001
}

In Uptime Kuma → Status Page → Custom Domain: status.yourdomain.com

Your status page looks like: https://status.yourdomain.com

Incident Management

  1. Status Page → Incidents → Create Incident
  2. Title: Database Performance Degradation
  3. Message: We're investigating increased latency...
  4. Status: Investigating, Monitoring, Resolved

Incidents appear on the status page timeline — keeps users informed during outages.


Part 6: Maintenance Windows

Schedule maintenance to suppress false alerts:

  1. Maintenance → Add Maintenance
  2. Title: Weekly Server Update
  3. Schedule: Recurring — Monday 2am–4am UTC
  4. Affected monitors: all

During maintenance windows, alerts are silenced and status page shows "Under Maintenance" instead of "Down."


Part 7: Monitor Groups

Organize monitors for readability:

Group: Production
  ├── API Server (HTTPS)
  ├── Database (PostgreSQL)
  ├── Redis Cache (TCP)
  └── CDN (HTTPS + keyword check)

Group: Staging
  ├── Staging API
  └── Staging DB

Group: Third-Party Services
  ├── GitHub API
  ├── Stripe API
  └── SendGrid SMTP

Groups appear as collapsible sections in the dashboard.


Quick Monitoring Coverage Checklist

For a typical web app, monitor:

✅ Frontend: HTTPS → 200 + keyword "loaded"
✅ API server: HTTPS → /health → 200 + keyword "ok"
✅ Database: PostgreSQL TCP → port 5432
✅ Redis: Redis → connection success
✅ Domain DNS: A record → expected IP
✅ SSL cert: Certificate info → expires > 30 days
✅ Docker containers: All critical containers
✅ External deps: Stripe, GitHub API, email provider

Maintenance

# Update Uptime Kuma:
docker compose pull
docker compose up -d

# Backup:
docker cp uptime-kuma:/app/data ./uptime-kuma-backup

# Or via volume path:
tar -czf uptime-kuma-backup-$(date +%Y%m%d).tar.gz \
  $(docker volume inspect uptime-kuma --format '{{.Mountpoint}}')

# Logs:
docker compose logs -f uptime-kuma

See all open source monitoring tools at OSSAlt.com/categories/monitoring.

Comments