Uptime Kuma
Uptime Kuma Monitoring Multi-tenant Self-hosted Uptime HTTP TCP Ping DNS Docker Notification Telegram Slack Status Page Dashboard Real-time
| Monitor Type | Protocol | Check | Interval | เหมาะกับ |
|---|---|---|---|---|
| HTTP(S) | HTTP/HTTPS | Status Code Body | 20s-300s | Website API |
| TCP | TCP | Port Open | 20s-300s | Database Service |
| Ping | ICMP | Response Time | 20s-300s | Server Network |
| DNS | DNS | Record Resolution | 60s-300s | DNS Server |
| Docker | Docker API | Container Running | 20s-300s | Container |
| Push | HTTP Push | Heartbeat Received | Custom | Cron Job Script |
Installation
# === Uptime Kuma Installation ===
# Docker (Recommended)
# docker run -d \
# --name uptime-kuma \
# --restart=always \
# -p 3001:3001 \
# -v uptime-kuma:/app/data \
# louislam/uptime-kuma:latest
# Docker Compose
# version: '3.8'
# services:
# uptime-kuma:
# image: louislam/uptime-kuma:latest
# container_name: uptime-kuma
# restart: always
# ports:
# - "3001:3001"
# volumes:
# - uptime-kuma-data:/app/data
# environment:
# - NODE_ENV=production
#
# volumes:
# uptime-kuma-data:
# Nginx Reverse Proxy
# 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://localhost: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;
# }
# }
# Node.js (Without Docker)
# git clone https://github.com/louislam/uptime-kuma.git
# cd uptime-kuma
# npm run setup
# npm run start-server
from dataclasses import dataclass
@dataclass
class MonitorConfig:
name: str
monitor_type: str
url: str
interval: int
retry: int
notification: str
tags: str
monitors = [
MonitorConfig("Main Website", "HTTP", "https://www.example.com", 30, 3, "Telegram + Slack", "tenant-a, web"),
MonitorConfig("API Server", "HTTP", "https://api.example.com/health", 20, 3, "PagerDuty", "tenant-a, api"),
MonitorConfig("Database", "TCP", "db.example.com:5432", 30, 5, "Slack", "tenant-a, db"),
MonitorConfig("DNS", "DNS", "example.com (A record)", 60, 3, "Email", "tenant-a, infra"),
MonitorConfig("Backup Job", "Push", "Push URL (heartbeat)", 3600, 1, "Telegram", "tenant-a, cron"),
MonitorConfig("Tenant B Web", "HTTP", "https://www.tenant-b.com", 30, 3, "Discord", "tenant-b, web"),
]
print("=== Monitor Configurations ===")
for m in monitors:
print(f" [{m.name}] Type: {m.monitor_type}")
print(f" URL: {m.url}")
print(f" Interval: {m.interval}s | Retry: {m.retry} | Notify: {m.notification}")
print(f" Tags: {m.tags}")
Multi-tenant Architecture
# === Multi-tenant Monitoring Design ===
# Approach 1: Single Instance + Tags
# - Use Tags to separate tenants
# - Create Tag per tenant: tenant-a, tenant-b, tenant-c
# - Assign monitors to tenant tags
# - Status Pages per tenant (built-in feature)
# - Pro: Simple, low resource
# - Con: No data isolation, shared admin
# Approach 2: Instance per Tenant (Docker)
# docker-compose.yml per tenant
# services:
# uptime-kuma-tenant-a:
# image: louislam/uptime-kuma:latest
# ports: ["3001:3001"]
# volumes: [tenant-a-data:/app/data]
# uptime-kuma-tenant-b:
# image: louislam/uptime-kuma:latest
# ports: ["3002:3001"]
# volumes: [tenant-b-data:/app/data]
# Approach 3: Kubernetes per Tenant
# apiVersion: apps/v1
# kind: Deployment
# metadata:
# name: uptime-kuma-{{ tenant }}
# namespace: monitoring
# spec:
# replicas: 1
# template:
# spec:
# containers:
# - name: uptime-kuma
# image: louislam/uptime-kuma:latest
# ports: [{containerPort: 3001}]
# volumeMounts:
# - name: data
# mountPath: /app/data
@dataclass
class TenantApproach:
approach: str
isolation: str
complexity: str
resource: str
max_tenants: str
use_case: str
approaches = [
TenantApproach("Single + Tags", "Low (shared DB)", "ง่าย", "1 instance", "5-10", "Small team internal"),
TenantApproach("Instance per Tenant", "High (separate DB)", "ปานกลาง", "1 container/tenant", "10-50", "MSP small"),
TenantApproach("K8s per Tenant", "High (separate Pod)", "สูง", "1 Pod/tenant", "50-200", "MSP large"),
TenantApproach("API Automation", "High + Automated", "สูง", "Dynamic", "200+", "SaaS platform"),
]
print("\n=== Multi-tenant Approaches ===")
for a in approaches:
print(f" [{a.approach}] Isolation: {a.isolation}")
print(f" Complexity: {a.complexity} | Resource: {a.resource}")
print(f" Max Tenants: {a.max_tenants} | Use Case: {a.use_case}")
Notification and Status Page
# === Notification Configuration ===
# Telegram Bot Setup
# 1. Create bot: @BotFather → /newbot
# 2. Get token: 123456:ABC-DEF
# 3. Get chat_id: curl https://api.telegram.org/bot{TOKEN}/getUpdates
# 4. Add in Uptime Kuma: Notification → Telegram
# Bot Token: 123456:ABC-DEF
# Chat ID: -1001234567890
# Slack Webhook
# 1. Create Slack App → Incoming Webhooks
# 2. Get URL: https://hooks.slack.com/services/T.../B.../xxx
# 3. Add in Uptime Kuma: Notification → Slack
# Status Page API (Automation)
# curl -X POST http://localhost:3001/api/status-page \
# -H "Content-Type: application/json" \
# -H "Authorization: Bearer YOUR_API_KEY" \
# -d '{
# "slug": "tenant-a",
# "title": "Tenant A Status",
# "description": "System status for Tenant A",
# "showPoweredBy": false
# }'
@dataclass
class NotificationChannel:
channel: str
setup: str
latency: str
reliability: str
use_case: str
channels = [
NotificationChannel("Telegram", "Bot Token + Chat ID", "1-3s", "สูงมาก", "Team chat alert"),
NotificationChannel("Slack", "Webhook URL", "1-3s", "สูงมาก", "DevOps channel"),
NotificationChannel("Discord", "Webhook URL", "1-3s", "สูง", "Community team"),
NotificationChannel("Email", "SMTP config", "5-30s", "สูง", "Management report"),
NotificationChannel("LINE Notify", "Access Token", "1-3s", "สูง", "Thai team"),
NotificationChannel("PagerDuty", "Integration Key", "1-2s", "สูงมาก", "On-call rotation"),
NotificationChannel("Webhook", "Custom URL", "1-5s", "ตาม Server", "Custom integration"),
]
print("Notification Channels:")
for c in channels:
print(f" [{c.channel}] Setup: {c.setup}")
print(f" Latency: {c.latency} | Reliability: {c.reliability}")
print(f" Use Case: {c.use_case}")
sla_targets = {
"Website Uptime": "99.9% (8.76h downtime/year)",
"API Uptime": "99.95% (4.38h downtime/year)",
"Database": "99.99% (52.56min downtime/year)",
"Check Interval": "20-30 seconds",
"Alert Response": "< 5 minutes",
"Incident Resolution": "< 1 hour (P1)",
}
print(f"\n\nSLA Targets:")
for k, v in sla_targets.items():
print(f" [{k}]: {v}")
เคล็ดลับ
- Docker: ใช้ Docker ติดตั้ง ง่าย Update ง่าย
- Tags: ใช้ Tags แยก Tenant สำหรับ Single Instance
- Status Page: สร้าง Status Page แยกตาม Tenant
- Backup: Backup /app/data ทุกวัน SQLite ไฟล์เดียว
- Notification: ตั้ง Notification หลายช่องทาง ป้องกันพลาด
Uptime Kuma คืออะไร
Open Source Self-hosted Monitoring HTTP TCP Ping DNS Docker Push Notification Telegram Slack Status Page Dashboard Real-time ฟรี
Multi-tenant Design คืออะไร
หลาย Tenant Infrastructure เดียว แยก Data Shared Database Schema Row Separate Database Tags Instance per Tenant Kubernetes
ตั้งค่า Notification อย่างไร
Telegram Bot Slack Webhook Discord Email SMTP LINE PagerDuty Webhook Down Up Retry Resend Monitor Group แยก Channel
สร้าง Status Page อย่างไร
Built-in UI Title Description Monitor Group Category Custom Domain Uptime Percentage Response Time Incident History Multi-tenant แยก Tenant
สรุป
Uptime Kuma Monitoring Multi-tenant Self-hosted HTTP TCP Ping DNS Docker Notification Telegram Slack Status Page Tags Instance Kubernetes Production
