Skip to main content

Uptime Kuma: Self-Hosted Server and Website Monitoring

Cloud & DevOps · 19.04.2026 · 4 min read
Illustration for “Uptime Kuma: Self-Hosted Server and Website Monitoring”

Uptime Kuma: Server and Website Monitoring

Uptime Kuma is a self-hosted, open-source alternative to UptimeRobot with a beautiful interface, Telegram notifications, and support for HTTP, TCP, DNS, Docker, and other monitor types.

Installing via Docker

docker run -d   --name uptime-kuma   -p 3001:3001   -v uptime-kuma:/app/data   --restart unless-stopped   louislam/uptime-kuma:latest

Open http://your-server:3001 for the initial setup.

Docker Compose

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

Nginx Reverse Proxy + SSL

server {
    listen 443 ssl;
    server_name status.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/status.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/status.yourdomain.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;
    }
}

Configuring Monitors

  • HTTP(S) — website check, expected status 200, keyword match
  • TCP Port — port availability check (MySQL 3306, SSH 22)
  • DNS — DNS record monitoring
  • Docker Container — container status
  • Ping — ICMP availability check

Telegram Notifications

In the settings, add Notification → Telegram:

Bot Token: 123456:ABCdefGHIjklMNO
Chat ID: -1001234567890  # for a group

# Get the Chat ID:
curl "https://api.telegram.org/bot{TOKEN}/getUpdates"

Status Page (Public Page)

Uptime Kuma supports creating beautiful public Status Pages — show service status to your customers without giving them access to the admin panel.

Integrations: Uptime Kuma supports notifications via Slack, Discord, PagerDuty, Email, SMS (Twilio), and more than 90 other channels.

Real Errors Explained

Three situations cover almost every issue during initial Uptime Kuma setup: volume permissions, a wrong Telegram Chat ID, and a self-signed certificate on an internal service. All three are easy to reproduce and just as easy to fix once you understand the root cause instead of simply restarting the container.

The Database Cannot Be Written

Error: EACCES: permission denied, open '/app/data/kuma.db'

The Uptime Kuma container runs as an unprivileged user inside the image, while the mounted ./uptime-kuma-data directory on the host is owned by root. Fix it with chown -R 1000:1000 ./uptime-kuma-data — you can find the process's actual UID inside the container with docker exec uptime-kuma id.

Telegram Notifications Do Not Arrive

Error: Bad Request: chat not found

The Chat ID is wrong — a common cause is that Telegram uses negative IDs for groups (for example -1001234567890), and supergroups start with -100. If the bot is not a member of the group, or has been blocked by the user in a private chat, you get the exact same error.

Uptime Kuma vs. UptimeRobot vs. Healthchecks.io

CriterionUptime KumaUptimeRobotHealthchecks.io
HostingSelf-hostedSaaSSaaS or self-hosted
CostFree (your own VPS)Free up to 50 monitors, then paidFree up to 20 checks
Checks from multiple regionsNo, a single serverYesYes
Public Status PageYes, built inYesLimited

When Uptime Kuma Is Not a Good Fit

  • You need monitoring from several geographic regions at once — a self-hosted install only checks from a single VPS, and a local network blip triggers a false alarm.
  • Customers need an independent third-party availability report — a self-hosted status page is not considered neutral proof in SLA disputes.
  • You need complex on-call escalation chains — PagerDuty or Opsgenie is the more honest fit here.
  • You are planning several thousand monitors — SQLite by default is not built for that load without extra tuning.
  • You need a long multi-year metrics history for SLA reporting — Uptime Kuma keeps aggregates for a limited period.

Verifying the Result

# The container is up and listening on the port
docker ps | grep uptime-kuma
curl -I http://localhost:3001

# The status API for a specific monitor (public if Status Page is enabled)
curl https://status.yourdomain.com/api/status-page/heartbeat/default

# Container logs when something looks off
docker logs uptime-kuma --tail 50

An empty response from curl -I, or a code other than 200/301, means the nginx reverse proxy could not reach the container — check that proxy_pass points to the right port and that the container is actually running. After the initial check, set up the monitoring server itself using the checklist from the article on configuring a cloud server, and it is convenient to run Uptime Kuma's database backups with rclone.

Was this article helpful?
← Back to Knowledge Base Ask Support