Uptime monitoring with Uptime Kuma

Uptime Kuma is the self-hosted alternative to UptimeRobot / Pingdom. It’s a single Docker container, has a beautiful UI, and supports every monitor type I actually need.

Deploy

# docker-compose.yml
version: "3.8"
services:
  uptime-kuma:
    image: louislam/uptime-kuma:1
    container_name: uptime-kuma
    restart: unless-stopped
    volumes:
      - uptime_data:/app/data
      - /var/run/docker.sock:/var/run/docker.sock:ro
    ports:
      - "127.0.0.1:3001:3001"  # Bind to localhost only
volumes:
  uptime_data:

Then expose it via Caddy on a private subdomain (e.g. status.internal.example.com) behind your WireGuard VPN.

What to monitor

I add monitors in three categories:

External services (HTTP/HTTPS)

  • https://nuteo.info — main site
  • https://api.nuteo.info/health — API endpoint
  • https://github.com/nuteo — public profile

Internal infrastructure (TCP / DNS)

  • 10.10.10.1:5432 — PostgreSQL
  • 10.10.10.1:6379 — Redis
  • 10.10.10.1:25 — SMTP

Cron jobs (via push)

  • Backup script — POST to /api/push/xxx?status=up&msg=OK when done
  • Cert renewal — certbot renew hook POSTs success/fail

Notifications

Uptime Kuma supports 90+ notification types. I use:

  • Telegram for everything (chat ID + bot token)
  • Email as backup for critical alerts
  • Slack for team-shared monitors

A failed check sends alert after 2 retries (configurable). A recovered service sends a “back up” message — useful when you’re waking up at 3am.

Status page (public)

Uptime Kuma has a built-in status page. I expose a small one publicly:

# Caddy
status.nuteo.info {
  reverse_proxy localhost:3001
  # No auth — public
}

Visitors see: green/yellow/red dots, 90-day uptime, response time graphs. Better than most paid services.