Self-Hosted Monitoring with Uptime Kuma

When a site goes down, you usually hear about it from users, not from your monitoring. Uptime Kuma is a free, open-source uptime monitoring tool that checks HTTP(s), TCP, Ping, DNS, and more, ships with a polished status page, and supports 90+ notification channels. Because your data lives on your own server and there is no per-monitor fee, it is a solid replacement for commercial monitoring services for small teams and solo webmasters. The setup is simple too — one compose file plus a reverse proxy, and you can have monitoring running in ten minutes, which beats comparing free tiers across SaaS products every time you add a check.

Self-hosted vs commercial monitoring

Commercial services usually bill per monitor and per notification channel; add enough checks and the monthly fee climbs. Free tiers tend to cap history retention and request frequency. Uptime Kuma keeps the data on your own server with no tier restrictions — monitors, history, and notification channels come without extra fees. For budget-conscious small teams that is a real consideration. Self-hosting has a cost too: the monitoring service itself must be maintained, and a single-instance deployment means nobody alerts you if the monitor dies — so in production, add an external probe as a fallback.

Docker Compose deployment

# docker-compose.yml
version: '3.8'
services:
  uptime-kuma:
    image: louislam/uptime-kuma:latest
    container_name: uptime-kuma
    ports:
      - "127.0.0.1:3001:3001"
    volumes:
      - ./uptime-kuma-data:/app/data
    restart: unless-stopped

Reference: Uptime Kuma repository https://github.com/louislam/uptime-kuma

Note that the port is bound only to 127.0.0.1, so nothing is reachable from outside until you put an Nginx reverse proxy with HTTPS in front of it.

Nginx reverse proxy

# /etc/nginx/sites-available/status.example.com
server {
    listen 443 ssl http2;
    server_name status.example.com;

    ssl_certificate /etc/letsencrypt/live/status.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/status.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

For certificate issuance and automatic renewal, see the Let's Encrypt setup article.

One-shot deploy script

#!/bin/bash
# deploy-uptime-kuma.sh

mkdir -p /opt/uptime-kuma && cd /opt/uptime-kuma
nano docker-compose.yml   # paste the YAML above
docker compose up -d
docker compose ps
echo "Access at http://your-server:3001"
echo "Then configure the Nginx reverse proxy for HTTPS"

First-time setup

  1. Open http://your-server:3001 (or your domain).
  2. Create the admin account.
  3. Click Add Monitor and pick a monitor type.
  4. Enter the website URL and check interval.
  5. Configure notifications (Telegram, Email, Slack, etc.).

Notification setup examples

Telegram:

1. Create a bot via @BotFather on Telegram
2. Get the Bot Token and Chat ID
3. Uptime Kuma: Settings → Notifications → Add → Telegram
4. Enter the Bot Token and Chat ID → Test to verify

Email (SMTP):

1. Settings → Notifications → Add → SMTP
2. Enter the SMTP server, port, username, and password
3. Enable TLS
4. Send a test email to verify

Supported monitor types

Type Use case Typical checks
HTTP(s) Web availability Status code, keyword, response time
TCP Port reachability Database, SSH, Redis ports
Ping Host liveness Packet loss, latency
DNS Domain resolution A records, resolution result
Certificate SSL certificate expiry Days until renewal

Security and maintenance

Uptime Kuma may be a monitoring tool, but don't run it in the open. The first steps after setup: change the admin password and disable open registration; put the panel behind a dedicated subdomain with HTTPS through the reverse proxy. Fold the data directory into your backup plan — all monitor config and notification settings live there. Back up before pulling a new image so rollbacks are easy.

Turning on the public status page

Once monitors are configured, enable a "public status page" per monitor group to generate a read-only link you can drop in the site footer or docs. Users check the status page first during incidents instead of contacting support. The page is read-only and doesn't expose the admin UI.

FAQ

Notifications not arriving? First check the token/account in the notification config and send a test via the Test button; then confirm the server can reach Telegram/SMTP domains — some providers need extra allowlisting. Do I lose data after a container restart? As long as the volume mounts ./uptime-kuma-data:/app/data, monitors and history persist; back up that directory before upgrading the image. Can it monitor internal services? Yes — run it on the internal network to monitor internal IPs, or use it as a probe to test public services. How does it relate to Grafana/Prometheus? It's lightweight availability monitoring focused on "up or down," while Prometheus focuses on metric collection and analysis; the two coexist well.

Going further: multiple instances and backups

If your business serves a global audience, deploy an instance per region and cross-check with multiple probes. To upgrade or migrate, tar up the whole uptime-kuma-data directory; to restore, unpack it back to the same path and start the container — monitors and settings come back exactly as they were.

Best practices

  • Intervals and alert fatigue. For business alerts, use a 1-minute interval and trigger only after 2-3 consecutive failures so network jitter doesn't cause false alarms. For fuller guidance, see alert fatigue and on-call practice.
  • Multiple monitoring points. If possible, run an instance on each continent; cross-checking tells you whether the site is down or just a single route is down.
  • Public status page. For user-facing sites, make the status page public to cut down "is it just me?" support questions.
  • Combine with synthetic monitoring. Pair Uptime Kuma with synthetic monitoring to cover scenarios closer to real users.

For the overall monitoring plan, start with the monitoring and alerting guide and browse the monitoring and alerting category.