最后更新于:2026年08月

⚠️ 重要声明:本文仅介绍监控告警的工程实现。请仅监控你自己拥有所有权或授权的服务,任何对第三方服务的扫描和可用性探测都可能违反对方的服务条款和当地法律。请在合规前提下合理使用监控工具。

Uptime Kuma 服务可用性监控与告警完全指南
Uptime Kuma:自托管社区最流行的高颜值监控工具

你花了一整个周末部署了 Nextcloud、Jellyfin、Vaultwarden、Home Assistant、用 CF Tunnel 和 FRP 把它们暴露到公网,又用 Caddy + acme.sh 配好了 HTTPS 证书。周一你去上班,结果家里 NAS 的 Docker 被 OOM Killer 杀了,Vaultwarden 挂了整整 12 小时——直到晚上回家你要填密码时才发现。服务跑起来不算完,挂了没人知道才是最可怕的。

「可用性监控 + 及时告警」是自托管运维的最后一块拼图,而 Uptime Kuma 正是 2026 年自托管社区最流行的选择:单容器 5 分钟部署、高颜值 Web UI、10 种监控类型(HTTP / HTTPS Keyword / TCP / Ping / DNS / 证书过期 / Push / gRPC / Steam / 自定义脚本)、50+ 通知渠道开箱即用、公开状态页直接能发给用户看。

本文从选型对比、部署、6 大监控类型、12 种常见通知渠道(Telegram / 飞书 / 企业微信 / Email / Discord / Slack / Webhook / PushPlus / Server酱 / Bark / PagerDuty / Gotify)、高级特性、实战模板、高可用、备份迁移、API 集成、假警报防治全拆解。读完你就能用它监控前面几篇文章里配置的 Caddy / acme.sh / FRP / Cloudflare Tunnel 所有服务。


🧭 第一部分:为什么选 Uptime Kuma?

1.1 自托管监控工具全景对比(2026 年)

PLAINTEXT
┌─────────────────────────────────────────────────────────────────────────┐
│              自托管可用性监控工具全景对比                                  │
├──────────────┬───────────────┬──────────────┬──────────────┬─────────────┤
│ 工具          │ Uptime Kuma 2 │ UptimeRobot │ Prom + Graf │ Zabbix 7    │
├──────────────┼───────────────┼──────────────┼──────────────┼─────────────┤
│ 定位          │ 可用性 + 告警 │ SaaS 可用性  │ 指标 + 面板  │ 全栈运维监控 │
│ 部署复杂度    │ ⭐⭐⭐⭐⭐ 1 容器 │ ⭐⭐⭐⭐⭐ SaaS │ ⭐⭐ 多组件   │ ⭐ 重系统     │
│ 资源占用      │ ~80MB RAM     │ — (SaaS)     │ ~1-4GB RAM   │ ~2-8GB RAM  │
│ 监控类型      │ 10+           │ 5            │ 无限(自己写) │ 无限         │
│ 通知渠道      │ 50+ (插件)    │ ~10          │ 需自己配     │ ~20          │
│ 公开状态页    │ ✅ 内置美观    │ ✅ 有         │ ❌ 需 Grafana│ ⚠️ 需扩展   │
│ 证书过期提醒  │ ✅ 内置        │ ✅ 付费版     │ ⚠️ 黑盒脚本  │ ⚠️ 配模板   │
│ 反代友好      │ ✅ 一行       │ —            │ ✅           │ ✅          │
│ 数据保留      │ 本地 SQLite   │ 云端 30-90d  │ 按存储无限   │ 按数据库    │
├──────────────┼───────────────┼──────────────┼──────────────┼─────────────┤
│ 最佳场景      │ 个人/小团队   │ 纯 SaaS 党   │ 指标/性能监控│ 企业级运维   │
│              │ 快速出结果    │              │ + 可视化     │ 深度监控    │
└──────────────┴───────────────┴──────────────┴──────────────┴─────────────┘

一句话选型:你只想知道「我的服务挂没挂,挂了立刻打电话/发消息给我」——选 Uptime Kuma。你还想看实时 CPU/内存/带宽 7 天曲线再做可视化大盘——Uptime Kuma + Prometheus+Grafana 组合部署(后面讲两者怎么联动)。

1.2 Uptime Kuma 能力矩阵:v2.x 全部特性

PLAINTEXT
┌─────────────────────────────────────────────────────────────────────┐
│           Uptime Kuma 2.x 能力矩阵                                    │
├─────────────────────────────────────────────────────────────────────┤
│  📡 10 种监控类型                                                    │
│  ├─ HTTP(s)          │ GET/POST/PUT/DELETE, 自定义 Header, Body     │
│  ├─ HTTPS Keyword   │ 检查页面是否包含/不包含关键字(防反代 502)     │
│  ├─ TCP Port        │ 任意端口存活(SSH 22 / RDP 3389 / MySQL 3306)│
│  ├─ Ping (ICMP)     │ 主机可达性 + 丢包/抖动监控                     │
│  ├─ DNS 查询        │ A/AAAA/CNAME/MX/TXT, 对比预期结果防污染       │
│  ├─ 证书过期        │ TLS/SSL 提前 N 天告警,自动续期失败提前发现    │
│  ├─ Push Passive    │ 内网/受限网机器主动上报,不接受入站探测        │
│  ├─ gRPC            │ gRPC Health / Reflection 健康检查              │
│  ├─ Steam 游戏服    │ Steam 社区服务器在线 + 玩家数监控              │
│  └─ Docker / Script │ 容器状态 + 任意可执行脚本返回值                 │
│                                                                     │
│  📣 50+ 通知渠道(重点 12 种后面实战)                                │
│  ├─ Telegram / Discord / Slack / Matrix / Mattermost               │
│  ├─ 飞书 / 企业微信 / 钉钉 / PushPlus / Server酱 / Bark            │
│  ├─ Email (SMTP) / Gotify / Ntfy / PagerDuty / Opsgenie            │
│  ├─ Webhook (通用,可接任何 API) / Prometheus Alertmanager          │
│  └─ 支持多渠道同时通知 + 每渠道单独重试策略                          │
│                                                                     │
│  🎛️ 高级运维能力                                                     │
│  ├─ 公开状态页 Status Page(域名白标 + 自定义品牌)                 │
│  ├─ 维护计划 Maintenance(定时屏蔽告警,升级/重启不打扰)            │
│  ├─ 代理探测(用另一台 Kuma / FRP / SOCKS5 异地测可用性)            │
│  ├─ 重试策略(延迟、次数、间隔)                                     │
│  ├─ 心跳检测 Heartbeat(cronjob 脚本正常跑完要 ping Kuma)          │
│  └─ API / Prometheus /metrics 导出(对接 Grafana)                  │
└─────────────────────────────────────────────────────────────────────┘

⚡ 第二部分:5 分钟部署 + 初始化

2.1 部署前 Checklist

PLAINTEXT
✅  一台能 7x24 小时运行的 Linux 机器 / NAS / VPS(推荐!监控机器不能和被监控机器在一起)
✅  Docker + Docker Compose 环境(99% 用户的选择)
✅  一个反代入口(Nginx Proxy Manager / Caddy / Cloudflare Tunnel / FRP)
✅  持久化存储目录(SQLite 数据库不能丢,要定期备份)
✅  至少 1 个通知渠道(Telegram Bot / 邮件 / 飞书,建议先配好再建 Monitor)

💡 异地部署原则:监控实例绝对不要跑在被监控的同一台机器上。家里 NAS 上跑的服务,监控要放在一台 VPS 上。反过来 VPS 上的服务可以用家里的 NAS 做反向监控。两边同时挂了才收不到告警,概率极低。

2.2 Docker Compose 一键部署

YAML
# ~/uptime-kuma/docker-compose.yml
services:
  uptime-kuma:
    image: louislam/uptime-kuma:2.0.0-beta.15   # 2026.8 最新稳定版
    container_name: uptime-kuma
    restart: unless-stopped
    ports:
      - "127.0.0.1:3001:3001"    # 只监听本机,靠反代入站
    volumes:
      - ./data:/app/data          # 🔴 SQLite DB + 配置,必须备份
      # (可选)要监控 Docker 容器本身时挂载:
      # - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      - TZ=Asia/Shanghai
      # 反向代理相关(CF Tunnel / Caddy / NPM 反代时建议设置)
      - UPTIME_KUMA_PROTOCOL=https
      - UPTIME_KUMA_HOST=status.example.com
      - UPTIME_KUMA_PORT=443
      # (可选)数据库加密(v2.x 新功能,防止 SQLite 被偷了泄露通知 Token)
      # - UPTIME_KUMA_DB_ENCRYPTION_KEY=你的强口令_建议32位以上
    security_opt:
      - no-new-privileges:true
    # (可选)资源限制,防止异常占用
    mem_limit: 512m
    cpus: "1.0"
    healthcheck:
      test: ["CMD", "node", "/app/extra/healthcheck.js"]
      interval: 60s
      timeout: 10s
      retries: 3
      start_period: 30s
    user: "0"   # 官方镜像默认 root,保证写 volume 不踩权限坑
BASH
cd ~/uptime-kuma

# 启动
docker compose up -d
docker compose logs -f    # 看日志,看到 Listening on 3001 就 OK

30 秒 Web 初始化:

  1. 浏览器打开 http://localhost:3001(此时还没反代,先用 SSH 隧道或本机打开)
  2. 创建管理员账号:用户名(不要 admin,建议 ops 或你名字)+ 强密码(至少 16 位)
  3. ✅ 进入仪表盘,初始化完成

2.3 暴露到公网 + HTTPS(三选一,选你前面已经在用的)

方案 A:Cloudflare Tunnel(0 公网 IP,推荐配合第 6 篇文章)

YAML
# cloudflared config.yml 的 ingress 加一条
  - hostname: status.example.com
    service: http://127.0.0.1:3001
  - service: http_status:404
# cloudflared tunnel route dns kuma status.example.com

方案 B:Caddy 反代(第 4 篇文章里的方式)

CADDYFILE
status.example.com {
    reverse_proxy 127.0.0.1:3001
    encode gzip zstd
    header Strict-Transport-Security "max-age=31536000"
    tls ops@example.com
}

方案 C:Nginx Proxy Manager + FRP(NPM 用户)

PLAINTEXT
NPM → Proxy Hosts → Add
  Domain Names: status.example.com
  Scheme: http
  Forward Hostname/IP: 127.0.0.1
  Forward Port: 3001
  Cache Assets: Off(Kuma 是 SPA,不建议缓存)
  Block Common Exploits: On
  WebSocket Support: On(Kuma 前端用 WS 拉数据,必开)
  SSL: 选 Let's Encrypt + Force SSL + HTTP/2 + HSTS

⚠️ 安全必做:暴露公网后,立刻在 Uptime Kuma → Settings → Security 里关掉「Allow new user registration」,否则任何人都能注册账号看你的监控。反代侧如果有条件,建议前面再加一层 Cloudflare Zero Trust Access(见 Cloudflare Tunnel 那篇),只有你 SSO 登录才能看到 Kuma 管理面板。

2.4 备份策略(立即配置)

SQLite 数据库是你所有 Monitor + 通知配置 + 历史数据的命根子,丢了全重来。

BASH
# ~/uptime-kuma/backup.sh —— 放到 crontab 每天凌晨跑
#!/bin/bash
set -euo pipefail
BACKUP_DIR="/root/backups/uptime-kuma"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p "$BACKUP_DIR"

# 1. 复制 SQLite(注意要先 PRAGMA wal_checkpoint,避免半写)
docker exec uptime-kuma node -e "
  const Database = require('better-sqlite3');
  const db = new Database('/app/data/kuma.db');
  db.pragma('wal_checkpoint(TRUNCATE)');
"
cp ~/uptime-kuma/data/kuma.db "$BACKUP_DIR/kuma_$DATE.db"

# 2. 压缩加密(7z 或 gpg,任选其一)
7z a -p"$BACKUP_PASSWORD" -mhe=on "$BACKUP_DIR/kuma_$DATE.7z" "$BACKUP_DIR/kuma_$DATE.db"
rm "$BACKUP_DIR/kuma_$DATE.db"

# 3. 保留最近 14 天
find "$BACKUP_DIR" -name 'kuma_*.7z' -mtime +14 -delete

# 4. (可选)同步到异机备份:rclone / syncthing / scp
# rclone copy "$BACKUP_DIR/" b2:my-backups/uptime-kuma/

echo "[OK] Uptime Kuma backup: kuma_$DATE.7z"
BASH
# 加到 crontab,每天 4:00 备份
chmod +x ~/uptime-kuma/backup.sh
(crontab -l ; echo "0 4 * * * /root/uptime-kuma/backup.sh >> /var/log/kuma-backup.log 2>&1") | crontab -

🔍 第三部分:6 大核心监控类型实战

3.1 HTTP(s) + Keyword:最常用的 Web 服务健康检查

适用场景:博客、Nextcloud、Vaultwarden、Home Assistant、API……所有 Web 服务。

PLAINTEXT
添加监控步骤:
  Add New Monitor
  ├─ Monitor Type: HTTP(s)
  ├─ Friendly Name: Vaultwarden 密码库
  ├─ URL: https://pass.example.com
  │
  ├─ Heartbeat Interval: 60 秒(建议 60-120,别太狠被对方 Ban)
  ├─ Retry: 2 次(1 次波动不报,减少假警报)
  ├─ Heartbeat Retry Interval: 30 秒
  │
  ├─ 【重要】Advanced HTTP Options(点进去)
  │   ├─ Method: GET(Web UI 用 GET;API 可以用 POST 带 Body)
  │   ├─ Headers:
  │   │     User-Agent: UptimeKuma/2.0 (+https://status.example.com)
  │   │     Accept: */*
  │   ├─ Expected Status Codes: 200-299,301,302
  │   │     (默认 200-299,要加 301/302 不然 301 跳转当失败)
  │   ├─ Proxy: (可选) 走异地 SOCKS5 代理探测,测全球可用性
  │   └─ Request Body: (POST/PUT API 时填 JSON/Form)
  │
  ├─ 【强烈推荐】Keyword(s) / Response Contains Keyword
  │   场景:反代挂了会返回 Cloudflare/Caddy 的 502 页面,HTTP 状态码还是 200。
  │   解决方案:检查页面实际内容。
  │   例:Vaultwarden 登录页一定有"Bitwarden"字样
  │        Response Contains Keyword: Bitwarden Password Manager
  │   也可以用"Not Contains"检测是否出现「Error」「维护中」等错误关键字
  │
  ├─ Upside-Down Mode: ❌ Off(正常:OK=UP,失败=DOWN;开启后反过来)
  ├─ Max. Redirects: 10
  ├─ Accept Invalid SSL: ❌ Off(用了自签才开)
  │
  └─ Notifications: 选你配好的 Telegram / 飞书 Bot(下面章节讲)

POST API 健康检查样例(比如你有个自建的登录接口要做端到端校验):

PLAINTEXT
Method: POST
Headers: Content-Type: application/json
Body:
  {"username":"healthcheck","password":"healthcheck_test"}
Expected Status Codes: 200
Response Contains Keyword: "ok":true
Request Timeout: 20s

3.2 TCP Port:端口存活 + 非 HTTP 服务(SSH/RDP/MySQL/Redis)

适用场景:SSH 22、RDP 3389、SMB 445、MySQL 3306、数据库、游戏服务器、FRP 客户端监听端口等所有非 HTTP 但开 TCP 端口的服务。

PLAINTEXT
Add Monitor → Type: TCP Port
  Name: VPS SSH 存活
  Hostname: 203.0.113.42
  Port: 22
  Interval: 120s
  Retry: 2

  Name: 家里 MySQL (FRP 暴露)
  Hostname: db.example.com
  Port: 3306
  Interval: 60s

💡 用 TCP 监控 + 异地代理 = 监控 Cloudflare Tunnel / FRP 入口是否通畅。之前文章里 FRP 暴露了 RDP,你就可以用 Uptime Kuma 监控那个 FRP 入口的 TCP 端口,FRP 客户端一掉线立刻告警。

3.3 证书过期监控:防 acme.sh 续期失败

第 5 篇文章讲了 acme.sh 自动化,但总会有意外(DNS Token 失效、域名过期、限额用完),续期失败不会立刻炸,90 天后证书到期才炸,那天你所有 HTTPS 服务全挂,用户浏览器报红。

PLAINTEXT
Add Monitor → Type: Certificate Expiry
  Name: example.com 通配证书 (acme.sh)
  Hostname: *.example.com
  Port: 443
  Interval: 3600s  (每 1 小时查一次,够了)
  Expiry Notification: 30 天(第一次提醒)→ 14 天 → 7 天 → 3 天 → 1 天 → 到期当日

配合 Uptime Kuma 的 Cert Expiry 全局仪表盘,你所有域名的剩余有效期一张表全看清,再也不会出现证书到期忘了续。

3.4 DNS 监控:防止 DNS 污染 / 解析错误

你的域名被本地运营商 DNS 污染解析到了黑洞 IP,正常用户打不开但你自己用 CF 公共 DNS 访问一切正常——这种事直到有用户投诉才发现。

PLAINTEXT
Add Monitor → Type: DNS
  Name: example.com 解析一致性
  Resolver Server: (可选,指定公共 DNS 对比)
    1.1.1.1 (CF), 8.8.8.8 (Google), 223.5.5.5 (阿里) 三个都测一遍
  RR Type: A
  Domain: example.com
  Expected Value: 104.21.8.42   (你预期的真实 IP,CF 的就填 CF 的 Anycast)

  再配一条:
  Resolver: 当地运营商 DNS(比如电信 202.96.128.86)
  Domain: example.com
  Expected Value: 和上面一致,不等就告警
  作用:第一时间发现运营商本地污染

3.5 Ping (ICMP):主机可达 + 延迟/丢包趋势

适用:VPS、家里 NAS、路由器、网关。

PLAINTEXT
Type: Ping
  Name: Home Router
  Hostname: home-nas.ddns.example.com
  Interval: 30s
  Packet Size: 56
  Number of Packets: 3 (平均 RTT 更准)
  Warning Threshold RTT: 200ms  (高于就黄)
  Critical Threshold RTT: 500ms (高于就红 + 告警)
  Packet Loss Warning: 10%
  Packet Loss Critical: 40%

Kuma 会自动生成 RTT 抖动 + 丢包率曲线,晚高峰你家宽带卡不卡、路由抖不抖一目了然。

3.6 Push (被动监控):内网/受限环境用「心跳」

有些场景你没法主动探测:

Push 模式是反过来:被监控的机器定期 curl 一下 Kuma 生成的唯一 URL,Kuma 如果在约定时间内没收到就告警(相当于「心跳」)。

PLAINTEXT
Step 1: Kuma 创建 Push Monitor
  Add Monitor → Type: Push
  Name: 家里 NAS 每日 BorgBackup 任务心跳
  Interval: 86400 (24 小时)
  Retry: 0 (心跳 24h 没到就报,不需要重试)
  → Create 后会拿到一个 Push URL:
    https://status.example.com/api/push/abcd1234?status=up&msg=OK&ping=

Step 2: 在被监控机器的备份脚本末尾加一行
  (例:borg-backup.sh 跑完所有步骤后)
  curl -fsS --max-time 10 "https://status.example.com/api/push/abcd1234?status=up&msg=$(date +%F)_OK&ping=" || true
  # 如果脚本中间出错,就不会跑到这一行,Kuma 24h 内没收到 UP,立刻告警
  # 也可以在脚本 trap 里失败时 push status=down

监控系统资源(被动上报 CPU/内存/磁盘):用 Push 模式 + 一个 5 分钟 crontab:

BASH
# /etc/cron.d/kuma-heartbeat
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
*/5 * * * * root (
  LOAD=$(awk '{print $1}' /proc/loadavg)
  DISK=$(df -h / | awk 'NR==2 {print $5}' | tr -d '%')
  MSG="load=${LOAD},disk_root=${DISK}%"
  PING=$(ping -c 1 -W 1 8.8.8.8 | awk -F'time=' '/time=/ {split($2,a," "); print a[1]}')
  curl -fsS --max-time 10 \
    "https://status.example.com/api/push/xxxxx?status=up&msg=${MSG}&ping=${PING:-0}"
) >/dev/null 2>&1 || true

📣 第四部分:12 种通知渠道配置实战

建议你至少配 2 个完全不同链路的通知渠道(比如 Telegram + Email),一个挂了另一个还能收到。

4.1 Telegram Bot(最推荐,秒到达、免费、富文本)

Step 1:拿 Bot Token(2 分钟)

PLAINTEXT
打开 https://t.me/BotFather
  → /newbot
  → 输入名(例:MyKumaAlertBot)
  → 输入 username(必须 _bot 结尾,例:my_kuma_2026_bot)
  → BotFather 返回:
     Use this token to access the HTTP API:
     7123456789:AAGxxxxxxxxxxxxxxxxxxxxxxxxxxxx
     🟢 保存这个 Token
  → (可选)给 Bot 改头像/描述,让消息好看点
  → 还要 /setprivacy → 选你 Bot → Disable(否则 Bot 看不到群里消息)

Step 2:拿 Chat ID

PLAINTEXT
方法 A(个人通知):自己发任意消息给 @userinfobot,拿到的 Id 就是 Chat ID(一串数字)
方法 B(群通知):把 Bot 拉进群,随便 @bot 发一条消息,然后浏览器访问:
  https://api.telegram.org/bot<你的Token>/getUpdates
  从 JSON 里找 "chat":{"id":-100xxxxxxx} 那行,-100 开头的就是群 ID

Step 3:Kuma 里添加

PLAINTEXT
Settings → Notifications → Setup Notification
  Notification Type: Telegram
  Friendly Name: Telegram 运维群
  Bot Token: 7123456789:AAGxxxxxxxxx
  Chat ID: -100xxxxxxxxx (或你自己的个人 ID)
  Parse Mode: MarkdownV2 (强烈推荐,消息可以加粗、链接、代码块)
  Disable Notifications: ❌
  Protect Content: ❌
  → Test 按钮 → 你 TG 收到【[Uptime Kuma] Testing】就算成功

4.2 飞书(Lark)自建应用 —— 国内团队首选

Step 1:创建飞书机器人

PLAINTEXT
飞书开放平台 → https://open.feishu.cn
  → 开发者后台 → 创建企业自建应用
    名字:Uptime Kuma 监控
    图标:随便传一张
  → 添加应用能力 → 机器人
  → 权限管理 → 开通「以应用身份发送消息到群组」im:message
  → 版本管理与发布 → 创建版本(0.0.1,仅自己企业可用)→ 发布
  → 凭证与基础信息里拿到:
    App ID:     cli_xxxxxxxxxxxxx
    App Secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Step 2:把 Bot 拉进群,拿群 Chat ID

PLAINTEXT
飞书 PC 端 → 目标群 → 设置 → 群设置 → 群机器人 → 添加
  → 加你刚创建的「Uptime Kuma 监控」机器人
  → 群里 @机器人 随便发条消息
  → 浏览器打开:
    https://open.feishu.cn/open-apis/im/v1/chats?page_size=20
    Header 里加 Authorization: Bearer <tenant_access_token,先 POST 拿 token>
  → JSON 里找你的群 chat_id,形如 "oc_xxxxxxxxxxxxxxxxxxxxxxxx"

Step 3:Kuma 配置

PLAINTEXT
Notification Type: Feishu / Lark
  Friendly Name: 飞书运维群
  App ID: cli_xxxxxxxxxxxxx
  App Secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  Chat ID / Open Chat ID: oc_xxxxxxxxxxxxxxxxxxxxxxxx
  → Test

4.3 企业微信(国内公司标配)

PLAINTEXT
企业微信管理后台 → 应用管理 → 自建 → 创建应用
  名称:Uptime Kuma 监控
  可见范围:运维组
  → 拿到 AgentId 和 Secret
  → 我的企业 → 企业 ID (CorpID)

Kuma Notification:
  Type: WeCom (Work WeChat)
  Corp ID: wwxxxxxxxxxxxx
  Corp Secret: xxxxxxxxxxxxxxxxxxxxxx
  Agent ID: 1000002
  To User: @all (或指定账号 | 分隔)
  → Test

4.4 Email (SMTP) —— 兜底必配

PLAINTEXT
Notification Type: Email (SMTP)
  Hostname: smtp.qq.com          (例: QQ企业邮 / 163 / Gmail)
  Port: 465                      (用 SSL, 不要 25)
  Security: SSL/TLS
  Username: alert@example.com
  Password: 邮箱独立密码/授权码    (QQ邮箱是「授权码」不是登录密码)
  From Address: alert@example.com
  To Address: you@example.com; ops2@example.com (; 分隔多个)
  Ignore TLS Error: ❌ 不忽略
  Subject: 【监控告警】{{ monitorJSON["name"] }} 变为 {{ heartbeatJSON["status"] }}
  → Test

4.5 PushPlus / Server酱(国内个人,微信接收)

PushPlus:微信公众号接收,免费用户每天 100 条。

PLAINTEXT
Type: PushPlus
  Token: https://www.pushplus.plus 登录后复制的 Token
  Topic: (可选) 一对多推送用
  Template: html
  → Test → 微信 PushPlus 服务号收到消息

Server酱 Turbo(方糖出品):老品牌,除了微信还能推 TG / Email / Bark。

PLAINTEXT
Type: ServerChan
  SendKey: SCTxxxxxxxxxxxxxxxxxxxx   (sct.ftqq.com 申请)
  → Test

4.6 Bark(iPhone 专属推送,零延迟)

iPhone 装 Bark App 打开拿 URL,形如 https://api.day.app/xxxxxx/:

PLAINTEXT
Type: Bark
  Server URL: https://api.day.app/xxxxxx/
  Sound: alarm.caf
  IsArchive: ✅
  → Test

4.7 Discord / Slack / Matrix / Mattermost / Gotify / Ntfy

配置都很像,基本就是「拿 Webhook URL 粘进去」:

PLAINTEXT
Discord:
  Type: Discord
  Discord Webhook URL: https://discord.com/api/webhooks/xx/yy  (服务器设置→集成→Webhook→新建)
  → Test

Slack:
  Type: Slack
  Slack Webhook URL: https://hooks.slack.com/services/...
  → Test

Gotify: (自托管消息推送)
  Type: Gotify
  Server URL: https://gotify.example.com
  Application Token: Axxxxxxx
  Priority: 8

Ntfy: (无需注册,topic 共享密钥)
  Type: Ntfy
  Server: https://ntfy.sh   (或自托管)
  Topic: my-ops-secret-topic-xxx (长随机,别人不知道就收不到)
  Priority: 4

4.8 Webhook(万能)—— 对接任何系统

所有前面没覆盖的渠道,通通可以「Kuma → Webhook → 中间脚本 → 目标渠道」。

PLAINTEXT
Type: Webhook
  Friendly Name: 自建网关 (钉钉/钉钉机器人/自定义…)
  Request Method: POST
  URL: https://your-gateway.example.com/kuma-webhook
  Content Type: JSON
  Headers:
    X-Webhook-Secret: your_shared_secret
  Body: 默认模板 Kuma 已经给了 JSON,包含所有信息
  → Test

示例:Webhook 接收端 Node/Express 快速钉钉转信(参考写个 30 行服务):

JAVASCRIPT
// kuma-gateway.js
const express = require('express');
const axios = require('axios');
const app = express();
app.use(express.json());

app.post('/kuma-webhook', (req, res) => {
  const { monitorJSON, heartbeatJSON, msg } = req.body;
  const color = heartbeatJSON?.status === 'DOWN' ? '#e74c3c' : '#27ae60';
  const text = `### 【${heartbeatJSON?.status || 'TEST'}】${monitorJSON?.name || '测试'}\n` +
               `**消息**: ${msg}\n` +
               `**时间**: ${new Date().toLocaleString('zh-CN',{tz:'Asia/Shanghai'})}`;
  axios.post('https://oapi.dingtalk.com/robot/send?access_token=xxx',
    { msgtype: 'markdown', markdown: { title: monitorJSON?.name, text } }
  );
  res.send('ok');
});
app.listen(9000);

🎛️ 第五部分:高级特性 —— 状态页、维护计划、代理探测

5.1 高颜值公开状态页 Status Page

做出来直接给用户看,比 QQ 群里问「服务是不是挂了?」专业 100 倍。

PLAINTEXT
Settings → Status Pages → New Status Page
  Slug: public         (URL 就变成 https://status.example.com/status/public)
  Title: 某某服务状态
  Custom Domain: (可选) status.example.com,解析一条 CNAME 到 Kuma 再配 Host Header
  Theme: Dark
  Powered By: ❌ 隐藏(个人用关了专业点)
  Show Tags: ✅
  Incident Title: 当前无异常 🟢

→ 进入 Status Page 编辑
  → Add Group: 核心服务
    拖 Monitor 进去:Vaultwarden、Nextcloud、Home Assistant
  → Add Group: 基础设施
    拖 Monitor 进去:VPS SSH、FRP 入口、CF Tunnel 入口、Home Router
  → Incidents:真实发生故障时写"事件报告",告诉用户已发现/处理中/已恢复
  → Design: 传 Logo,改 Brand Color,打造成官方品牌化的状态页

效果:打开 https://status.example.com/status/public,用户能看到每个服务当前状态、30 天可用性柱状图、最近 24h 平均响应时间曲线、历史故障公告。和大厂 StatusPage.io 的体验几乎一样,而且完全自托管。

5.2 Maintenance(维护计划)—— 升级重启不乱告警

PLAINTEXT
Settings → Maintenance → Add
  Title: 每周三凌晨系统升级
  Start: 选周三 03:00
  Duration: 1h
  Repeat: Weekly
  Affected Monitors: 选所有会被重启影响的 Monitor
  Notifications: ✔️ (可选择维护开始前 5 分钟发一条"即将进入维护"的预告)

  再来一条:
  Title: acme.sh 每月证书续期
  Start: 每月 1 号 04:30
  Duration: 15m
  Repeat: Monthly
  Affected: 只选 Caddy / 证书相关可能短暂 502 的 HTTP Monitor

维护窗口内所有失败不会触发告警,状态页会显示「Scheduled Maintenance in Progress」黄条而不是红色 Down,非常专业。

5.3 代理探测:异地多节点,防止监控机单边误判

前面说过:Uptime Kuma 跑在日本 VPS,监控家里 NAS 的 CF Tunnel。如果日本到 CF 的 HK 节点那段路由断了,而国内用户实际访问没事,Kuma 就会发假警报。

解决方案:同时用多个代理节点(比如日本 + 美国 + 你家里另一台机器上的 SOCKS5)探测同一个服务,至少 2/3 失败才告警,准确率飙升。

PLAINTEXT
先搭一个 SOCKS5 / HTTP Proxy 节点(任选其一):
  · 家里路由器上跑 dante-server 开 SOCKS5
  · 另一个 VPS 上 3proxy
  · 用 FRP 的内网 SOCKS 功能
  · 用 CF WARP 当出口代理

然后在 Monitor 里:
  Advanced → Proxy Options
    → Use Proxy ✔️
    Protocol: SOCKS5 / HTTP
    Host: proxy-home.example.com
    Port: 1080
    Auth: (可选) user/pass

  同样的监控建 3 条:
    Vaultwarden (JP) → 日本 Kuma 直连
    Vaultwarden (US) → 美国 Kuma SOCKS → 洛杉矶代理
    Vaultwarden (Home) → 日本 Kuma SOCKS → 家里代理出口
  → 三条都 DOWN 你才人工介入,基本消除假警报

🏗️ 第六部分:实战监控模板 —— 为前面几篇文章的服务定制

这是本篇文章的杀手级章节——给前面五篇配置的每一种服务,直接配好对应的监控模板,全部复制改域名就能用。

6.1 监控 Caddy 反向代理(第 3 篇)

YAML
# 模板 A: Caddy 反代入口健康
  Type: HTTPS Keyword
  URL: https://caddy-status.example.com/health
  Status Code: 200
  Contains: OK
  Interval: 30s
  说明: 在 Caddyfile 加一个 /health 固定返回 200 OK:
        caddy-status.example.com {
            handle /health { respond "OK" 200 }
            reverse_proxy /* localhost:xxx
        }

# 模板 B: 被反代的每个子站点
  URL: https://blog.example.com          200 + Contains "我的博客名"
  URL: https://cloud.example.com         200 + Contains "Nextcloud"
  URL: https://home.example.com          200 + Contains "Home Assistant"

6.2 监控 acme.sh 证书续期(第 4 篇)

YAML
# 模板 C: 所有域名的证书
  Type: Certificate Expiry
  Hostname: blog.example.com     Port 443   30d warn
  Hostname: *.example.com        Port 443   30d warn
  Hostname: cf-vip.example.com   Port 443   30d warn
  Interval: 1h

  再加一条 Push 监控 acme.sh 脚本自身的执行:
  Type: Push
  Name: acme.sh --cron 正常执行心跳
  Interval: 86400s (1天)
  然后在 acme.sh 的 --post-hook / crontab 末尾 curl Kuma Push URL

6.3 监控 FRP(第 5 篇)

YAML
# 模板 D: frps 服务端存活(有 VPS)
  Type: TCP Port
  Hostname: frps.example.com
  Port: 7000      (frps bindPort)
  Interval: 60s

# 模板 E: FRP Dashboard HTTP
  Type: HTTP
  URL: http://frps.example.com:7500/
  Status: 200
  Auth: Basic → admin / 你设置的密码

# 模板 F: 每个 FRP 代理的端口
  TCP frp-web:80 / TCP frp-ssh:60022 / TCP frp-rdp:63389 各一条

6.4 监控 Cloudflare Tunnel(第 6 篇)

YAML
# 模板 G: 每个 Tunnel 的 Public Hostname
  Type: HTTPS Keyword
  URL: https://app.example.com  Contains "ExpectedKeyword"  Interval 60s

# 模板 H: WARP 私有网络里的内网主机(用异地 Kuma + Push)
  方式 A: 内网主机每 5 分钟 Push 心跳 → Kuma Push Monitor
  方式 B: Kuma 也接进 Zero Trust WARP,直接打内网 IP Ping/TCP

# 模板 I: Tunnel 本身健康(用 cloudflared 自带 /ready)
  Type: HTTP
  URL: http://127.0.0.1:20001/ready    (cloudflared 开启 metrics/ready 端口)
  Status: 200
  Interval: 30s

6.5 监控 SSH 隧道(第 2 篇)

YAML
# 模板 J: autossh 反向隧道的入口端口(在 VPS 上本地测)
  Type: TCP Port
  Hostname: 127.0.0.1
  Port: 2222    (autossh -R 2222:localhost:22 的监听端口)
  Interval: 60s
  作用: autossh 断开 → 端口消失 → Kuma 立刻报 → 你就知道 SSH 隧道挂了

6.6 监控监控自己:让另一个实例反向监控 Uptime Kuma

「谁来监控监控者?」用两台 Kuma 互探。

PLAINTEXT
VPS 上的 Kuma A:
  加一条 Monitor → HTTP → https://kuma-home.example.com → 200
NAS 上的 Kuma B:
  加一条 Monitor → HTTP → https://kuma-vps.example.com → 200
两台分别用不同的 Telegram Bot Token。
→ 两台同时挂的概率 ≈ 0。

🔒 第七部分:Uptime Kuma 安全加固 + 2FA

7.1 必做的 5 项安全设置

PLAINTEXT
① Settings → Security:
   Allow new user registration: ❌ 关
   Default User Role: View Only(你给同事开账号只看 Status Page)
   Disable Frame Embedding: ✔️ On (防 clickjacking)
   Content-Security-Policy: 推荐默认严格配置

② Settings → About → Check Update:
   自动提示新版本,Uptime Kuma 发版非常勤快,有漏洞修复要及时更。

③ 登录 2FA (必须开):
   头像 → Account → Two Factor Authentication → Setup
   用 Google Authenticator / Authy / 1Password / Bitwarden 扫码
   存好 Recovery Code(2FA 设备丢了用这个回)

④ 反代侧开启 Cloudflare Access / Caddy 基本认证 / mTLS:
   详见 Cloudflare Tunnel 篇的 SSO 章节。
   管理面板不对外裸奔,加一道统一 SSO。

⑤ Volume 权限收紧 + 数据库加密(v2.x):
   chown -R 1000:1000 ~/uptime-kuma/data   (非 root 能读就行)
   compose 环境变量里加 UPTIME_KUMA_DB_ENCRYPTION_KEY=<32字节随机>
   → kuma.db 文件被偷了也打不开

7.2 通知渠道安全:最小 Token 权限

PLAINTEXT
⚠️  Telegram Bot Token:
   不要把 Token 写进 GitHub / 群聊 / 截图。Kuma 数据库已经存了一份,别处不要再留。

⚠️  Webhook Secret:
   每条 Webhook 都用 Header + Secret 签名校验,接收端验证再处理。
   否则别人猜到 URL 就能伪造告警刷屏。

⚠️  企业微信/飞书应用 Secret:
   权限只开「发消息」,不要开通讯录、文档等额外权限。
   最小权限原则。

🧩 第八部分:多副本高可用 + 数据同步

8.1 主备 + 单向复制(零停机)

PLAINTEXT
┌──────────────┐   SQLite / 备份推送    ┌──────────────┐
│  主 Kuma      │ ─────────────────────→ │  备 Kuma B   │
│  (VPS Tokyo)  │   定时 rsync + reload  │  (Home NAS)  │
│  100% 流量     │                        │  冷备 0 流量  │
└──────────────┘                        └──────┬───────┘
                                                │ 手动切
                                                ▼
                                         用户访问备机

实现(30 行脚本,每 10 分钟同步 DB 到备机):

BASH
# 主机上的 kuma-sync.sh
#!/bin/bash
set -e
SECONDARY="nas.example.com"
K_PATH="/opt/uptime-kuma/data"

# 1. Checkpoint WAL(避免半写)
docker exec uptime-kuma node -e "
  const db = require('better-sqlite3')('/app/data/kuma.db');
  db.pragma('wal_checkpoint(TRUNCATE)');
"

# 2. Rsync over SSH
rsync -avz --delete \
  --exclude="*.shm" --exclude="*.wal" \
  "$K_PATH/kuma.db" \
  "$SECONDARY":/opt/uptime-kuma/data/

# 3. 备机 reload container (让 SQLite 重新读)
ssh "$SECONDARY" 'docker restart uptime-kuma' 2>&1 | logger -t kuma-sync
PLAINTEXT
主机 crontab: */10 * * * * /opt/uptime-kuma/kuma-sync.sh

8.2 双活 + 不同 Monitor 分流

如果你要「两台都跑 24/7」,让 A 监控亚洲服务、B 监控美洲服务、互探对方,比主备资源利用率更高。配合前面说的多代理探测,两台同时失败才是真失败。


🧪 第九部分:API / Prometheus / Grafana 集成

9.1 /metrics 端点 + Grafana 仪表盘

Uptime Kuma 2.x 自带 Prometheus 指标暴露,和 VPS 级监控(node_exporter)放一起就是 360° 大盘。

PLAINTEXT
Uptime Kuma → Settings → API → Enable Prometheus Endpoint ✔️
   → 会给你一个带 Token 的 URL:
     https://status.example.com/metrics?token=xxxxxxxxx
   → Prometheus scrape_configs:
        - job_name: uptime_kuma
          metrics_path: /metrics
          params: { token: ["xxxxxxxxx"] }
          static_configs: [{ targets: ["status.example.com:443"] }]
          scheme: https

导入 Grafana:Grafana Labs 搜 Dashboard ID 18928(Uptime Kuma 官方社区推荐),一键导入即可看到:

9.2 用 API 批量创建 / 更新 Monitor

50+ 条 Monitor UI 一条一条点太费时,用 API 批量导入:

BASH
# Step 1: Kuma → Settings → API → 拿 API Key (形如 uk_xxx)
APIKEY=uk_xxxxxxxxxxxxxxxxxxxxxxxx
BASE=https://status.example.com

# Step 2: 批量添加的 CSV
cat monitors.csv << 'EOF'
name,type,url,keyword,tags
Vaultwarden (生产),keyword,https://pass.example.com,Bitwarden Password Manager,"core,vault"
Nextcloud,keyword,https://cloud.example.com,Nextcloud,"core,file"
Home Router,ping,192.168.1.1,,infra
EOF

# Step 3: 循环创建
tail -n +2 monitors.csv | while IFS=, read -r name type url keyword tags; do
  echo "Adding: $name"
  payload=$(jq -n \
    --arg name "$name" \
    --arg type "${type^^}" \
    --arg url "$url" \
    --arg kw "$keyword" \
    --arg tags "$tags" '
    {
      name: $name,
      type: $type,
      url:  $url,
      interval: 60,
      retry: 2,
      upsideDown: false,
      headers: [{ name:"User-Agent", value:"UptimeKuma/2.0 API" }],
      keyword: $kw,
      tags: ($tags | split(",") | map({name: ., color:"#3498db"}))
    }')
  curl -sS -X POST "$BASE/api/monitors" \
    -H "Authorization: Bearer $APIKEY" \
    -H "Content-Type: application/json" \
    -d "$payload" | jq .msg
done

🧯 第十部分:假警报防治策略 + 常见故障排查

10.1 假警报的 6 大成因 + 对策

PLAINTEXT
┌───────────────────────────────────────────────────────────────────┐
│  假警报原因 TOP6 + 对策                                             │
├──────────────────────────┬────────────────────────────────────────┤
│  ① Kuma 本机房出口抽风    │ → 用 2+ 异地代理同时测,多数 DOWN 才报 │
│                          │ → 建「美国 / 日本 / 国内」三条        │
├──────────────────────────┼────────────────────────────────────────┤
│  ② 单次网络抖动误判      │ → Retry = 2,Retry Interval = 20-30s  │
│                          │ → HTTP 超时适当调大到 10-20s           │
├──────────────────────────┼────────────────────────────────────────┤
│  ③ 反代升级时 502        │ → 用 Maintenance 定时窗口             │
│                          │ → 手工升级前先开 Maintenance          │
├──────────────────────────┼────────────────────────────────────────┤
│  ④ CF / CDN 命中挑战页   │ → HTTP 头加固定 User-Agent / 白名单 UA│
│                          │ → CF 把 Kuma 出口 IP 加入 WAF 绕过     │
├──────────────────────────┼────────────────────────────────────────┤
│  ⑤ 301/302 跳转算失败    │ → Expected Status Codes 加 301,302    │
│                          │ → Max Redirects = 10                  │
├──────────────────────────┼────────────────────────────────────────┤
│  ⑥ 被监控方临时限流 429  │ → Interval 调稀到 ≥60s                 │
│                          │ → User-Agent 明确标记,加白名单        │
└──────────────────────────┴────────────────────────────────────────┘

10.2 常见排错手册

问题排查步骤
Test 通知成功,但真实 DOWN 时没消息① Monitor 里 Notifications 没勾选对应渠道 ② Kuma 容器时间不对(date 检查) ③ 全局 Notification Group 设置了「X 秒不重复」而你触发太密
Ping 永远 100% 失败① Docker 默认 drop ICMP ?启动时加 --cap-add=NET_RAW (v2 官方镜像已处理) ② 对端禁 ICMP,改 TCP Port Monitor
通知消息间隔越来越长(延迟到达)① 看 Notifications → Queue 堆积数 ② 某条错误的 Webhook 一直 5xx,整个通知队列被阻塞 → 暂停该通知 ③ 升级最新版,v2.0 有按渠道独立队列的改进
证书过期监控不准① 不是 443 端口要填对自定义 Port ② Cloudflare 回源时 CF 证书与你源站不同,要选「Check Server Certificate: Yes + Chain」
容器占用 CPU 一直高① Interval <15s 的 Monitor 太多,整体调稀到 60s+ ② 开了 SQLite 加密会多吃 ~20% CPU,权衡要不要 ③ 看看日志 (docker compose logs) 是否循环报错某个代理

🔁 第十一部分:与既有工具链联动(生态整合)

11.1 Uptime Kuma ↔ Prometheus + Grafana + Alertmanager(三件套)

PLAINTEXT
你的所有服务 ─┬─→ Uptime Kuma (黑盒可用性 + 状态页 + 轻告警)
             │         ① 50+ 通知秒级
             │         ② 用户能看公开状态页
             │
             └─→ node_exporter + Prometheus (白盒指标)
                       ↓
                   Grafana (漂亮指标图)
                       ↓
                   Alertmanager (高级分组/静默/路由)

两者不是竞争关系,是互补。黑盒 + 白盒都有才是完整运维。

11.2 和 FRP / CF Tunnel / Caddy 的联动清单

PLAINTEXT
✅  FRP:
   · TCP 监控 frps bindPort + 每个 frpc 代理
   · HTTP 监控 Dashboard + 每个 frp http 域名(Keyword 检查源站不是 503)

✅  Cloudflare Tunnel:
   · HTTPS 监控每个 Public Hostname(用 Keyword)
   · Push 监控 WARP 里的内网机器
   · API 定期检查 Tunnel 的 Connections 数量(脚本 + Push 心跳)

✅  Caddy:
   · 加 /health 固定返回 200
   · HTTPS Keyword 监控每个子域名
   · Certificate Expiry 监控每个使用中的证书(含 ECC 双证书)

✅  acme.sh:
   · Cert Expiry 兜底
   · Post Hook + Push 心跳确认 cron 正常跑完(续期没炸)
   · 备份脚本结束 Push 到 Kuma

📚 第十二部分:命令速查表 + 学习路径

12.1 Shell / Docker 速查

BASH
# 部署 & 运维
cd ~/uptime-kuma
docker compose up -d              # 启动
docker compose logs -f --tail=50  # 实时日志
docker compose pull && docker compose up -d   # 升级版本
docker exec -it uptime-kuma bash             # 进容器

# 数据
docker exec uptime-kuma node -e "
  const db=require('better-sqlite3')('/app/data/kuma.db');
  console.log('Monitors:', db.prepare('SELECT COUNT(*) c FROM monitor').get().c);
  console.log('Heartbeats 24h:', db.prepare(
    'SELECT COUNT(*) c FROM heartbeat WHERE time>strftime(\"%s\",\"now\",\"-1 day\")*1000'
  ).get().c);
"

# API 批量导出(迁移前检查)
curl -sSH "Authorization: Bearer $APIKEY" \
  "$BASE/api/monitors" | jq '.[] | {id,name,type,url,interval}'

# 离线备份(除了定时脚本,手动跑一份)
./backup.sh && ls -lh ~/backups/uptime-kuma/

12.2 学习路径(4 级)

PLAINTEXT
🟢 入门(1 小时)
  用 Docker Compose 部署 + 建 1 条 HTTP Monitor + Telegram Bot 测试 → 真实挂一次看告警

🟡 进阶(1 天)
  建好本文第六部分所有模板(Caddy / FRP / CF Tunnel / SSH / Cert)
  + 配 2 种通知渠道 + 公开状态页

🟠 熟练(1 周)
  + 异地多节点代理 + Maintenance 维护计划
  + Push 监控所有备份 / cron 任务
  + 2FA / CF Access 面板安全加固
  + 7z 加密 + 异地备份

🔴 生产(长期)
  + 主备双实例同步
  + Prometheus + Grafana 大盘
  + API + IaC (Ansible/Terraform) 批量管理 Monitor
  + 年度容灾演练:真的停 Kuma 主,切备机

12.3 参考资料 + 关联阅读


✅ 总结

Uptime Kuma 是那种「装完一次就再也回不去」的工具——之前要靠用户抱怨「网站打不开」才知道服务挂了,现在任何服务变成 DOWN 的 30 秒内,你的 Telegram / 飞书 / 微信就会收到通知。配合维护计划、异地多节点探测、公开状态页,运维体验直接从刀耕火种跳到现代自动化。

对于我们前面 6 篇搭建的服务链(SSH Tunnel / Caddy / acme.sh / FRP / Cloudflare Tunnel),直接照第六部分的模板 6.1~6.5 每条建好,整个自托管栈就有了最后一块安全网。

下一步建议:

  1. 立刻部署一台 VPS 上的 Uptime Kuma(15 分钟)
  2. 配好 Telegram + Email 双通知渠道(再用 15 分钟)
  3. 把第六部分的 6 个监控模板全建好,先把最关键的 3-5 个服务加进去(1 小时)
  4. 过 1 周收到第一次真实告警,你就会想为什么没有早点装它。

关注 易邦科学上网,及时获取最近更新:

X : https://x.com/rozmiarek760575

版权声明

作者: 易邦

链接: https://blog.e8k.net/posts/uptime-kuma-monitoring-alerting-guide/

许可证: 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。