Skip to content
Back to Blog
Monitoring

Uptime Kuma: Self-Hosted Status Page and Monitoring

Deploy Uptime Kuma for self-hosted uptime monitoring with HTTP, TCP, DNS, and certificate checks plus public status pages.

Oct 2025
8 min read

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

BASH
# 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 visit

Docker Compose for production:

YAML
# 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-kuma

Nginx configuration for SSL termination:

NGINX
# 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
TCP Port Monitor:
  • Use for: databases (5432), SMTP (25), custom apps
  • Host: db.company.com
  • Port: 5432
  • Interval: 60s
DNS Monitor:
  • Check if DNS resolves correctly
  • Hostname: app.company.com
  • Expected value: 203.0.113.10
  • DNS resolver: 8.8.8.8
SSL Certificate Monitor:
  • Monitors certificate expiry
  • URL: https://app.company.com
  • Alert when cert expires in < 14 days
Docker Container Monitor:
  • Connect Uptime Kuma to Docker socket to monitor container health
  • Container name: web-app
  • Checks Docker health status

Setting Up Notifications

TEXT
# 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:

YAML
# 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

TEXT
# 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 login

Uptime Kuma API for Automation

PYTHON
#!/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

BASH
# 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 -delete

Alerting 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:

BASH
# 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.