结论先行:独立开发者与出海 SaaS 监控网站与 API 可用性,自建首选 Uptime Kuma。一条 Docker 命令或简单的 Compose 文件 5 分钟即可交付,支持 HTTP(s)、TCP 端口、Ping、DNS、SSL 证书过期与多种数据库连接探针。新部署务必指定 louislam/uptime-kuma:2 镜像标签锁定现代化 V2 大版本。配合 Telegram Bot 或 Webhook 实现秒级故障推送,自带的公开状态页(Status Page)无需额外购买服务即可向用户展示系统 SLA 运行指标。
做海外产品最怕的场景:因为跨时区时差,凌晨海外关键服务或支付回调接口挂掉,直到早上醒来看见满屏用户退款工单才惊醒。本篇带你用 Docker 快速自建高颜值存活监控与告警中心。
0、写在前面
很多出海团队初期习惯使用免费第三方探活平台:
- UptimeRobot 免费版:限制 50 个监控项,且探针轮询间隔长达 5 分钟,服务挂掉 4 分多钟才被察觉;
- 商业状态页(如 Statuspage):按月订阅价格昂贵,不适合精打细算的独立开发者;
- 云厂商自带云监控:通常只支持监控自家 VPS,无法实现多云跨地域的外部客观拨测。
Uptime Kuma 是近几年开源社区中最受欢迎的自托管探针工具:
- 支持 1 分钟甚至更短的轮询频率;
- 原生支持 HTTP(s)、TCP、Ping、DNS、Docker 容器与各类数据库探活;
- 支持 100 多种即时告警推送(Telegram、Discord、Slack、邮件、Webhook 等);
- 自带开箱即用的白标公开状态页(Status Page)。
1、期望目标
阅读并按本指南实操后,你将达成以下运维标准:
- [ ] 通过 Docker 或 Docker Compose 在 5 分钟内完成 Uptime Kuma V2 生产级部署;
- [ ] 建立持久化数据卷,确保容器重启与镜像升级时历史监控数据不丢失;
- [ ] 配置针对 Web 网站、核心 API 以及后端数据库端口的探针任务;
- [ ] 开启 SSL 证书到期自动检测,提前 14 天提示续期风险;
- [ ] 绑定 Telegram Bot,实现核心故障 60 秒内推送到手机;
- [ ] 制作并发布面向公众的品牌专属状态页(Status Page);
- [ ] 配合 Nginx 或 Caddy 完成反向代理与 HTTPS 安全访问加固。
2、技术架构与探针工作模型
3、Docker Compose 生产级部署
在生产环境中,推荐使用 Docker Compose 进行版本固化、资源配额隔离与本地端口保护。
3.1 创建部署目录
1 2
| mkdir -p ~/uptime-kuma/data cd ~/uptime-kuma
|
3.2 编写生产级 docker-compose.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| version: '3.8'
services: uptime-kuma: image: louislam/uptime-kuma:2 container_name: uptime-kuma restart: unless-stopped ports: - "127.0.0.1:3001:3001" volumes: - ./data:/app/data environment: - TZ=UTC - UPTIME_KUMA_PORT=3001 deploy: resources: limits: cpus: '1.00' memory: 512M reservations: cpus: '0.10' memory: 128M logging: driver: "json-file" options: max-size: "20m" max-file: "3" healthcheck: test: ["CMD", "node", "extra/healthcheck.js"] interval: 30s timeout: 10s retries: 3 start_period: 20s
|
[!TIP]
镜像标签务必使用 :2 而非 :latest。Uptime Kuma 官方在发布 V2 主线版本后,:latest 标签长期停留于旧版 V1 维护分支,明确指定 :2 能确保享受到最新的响应性能与功能。
3.3 启动服务与开机引导
1 2 3 4 5
| docker compose up -d
docker compose logs -f
|
也可以通过 ittinker-scripts 工具库中的通用一键脚本快速拉起基础环境:
1
| curl -fsSL https://raw.githubusercontent.com/ittinker/ittinker-scripts/main/docker-quick-deploy/docker-quick-deploy.sh | bash
|
当看到 Listening on 3001 时,说明底层 SQLite 数据库初始化完毕,服务正常启动。
4、初始化设置与探针配置
在浏览器中输入 http://127.0.0.1:3001(或配置反向代理域名后访问),初次进入时会弹出创建管理员账号的界面。设置高强度管理员密码后登录控制台。
4.1 添加基础 HTTP(s) 站点探针
点击左上角 Add New Monitor(添加新监控项):
- Monitor Type:选择
HTTP(s);
- Friendly Name:填入清晰易懂的名称,如
Blog Main Website;
- URL:输入网站完整路径,例如
https://yourbrand.com;
- Heartbeat Interval:轮询检测间隔,生产环境建议设置为
60 秒;
- Retries:重试次数设为
2 次(连续 2 次探测失败再触发告警,避免偶发网络抖动误报);
- Certificate Expiry Notification:勾选启用。Uptime Kuma 会在域名 SSL 证书剩余有效期不足 14 天时提前预警;
- 点击 Save 保存。
4.2 添加 TCP 端口可用性探针
对于不对外暴露 HTTP 服务的数据库或私有 RPC 端口,使用 TCP 探针检测连通性:
- Monitor Type:选择
TCP Port;
- Friendly Name:
Production PostgreSQL;
- Hostname:
db.yourbrand.com(或公网 IP);
- Port:
5432;
- Heartbeat Interval:
60 秒。
5、告警通知接入实战(Telegram 与 Webhook)
5.1 配置 Telegram 实时告警
- 登录 Uptime Kuma 面板,点击右上角头像进入 Settings -> Notifications;
- 点击 Setup Notification,选择 Telegram;
- 配置参数:
- Telegram Bot Token:填入由
@BotFather 签发的 Token(例如 7123456789:AAF-xxxxxxxxxxxxxxxxxxxx);
- Chat ID:填入你的 Telegram 个人或群组 ID(例如
123456789);
- 勾选 Default enabled(作为所有新建探针的默认告警渠道);
- 点击 Test 按钮,若 Telegram 收到测试通知,点击 Save 保存。
5.2 配置自定义 Webhook(用于集成企业机器人)
若团队使用飞书、钉钉或 Discord,可选择 Webhook 通知方式:
- Post URL:填入群机器人的 Webhook 回调地址;
- Request Body:保留默认 JSON 载荷;
- 当探针触发
DOWN 或 UP 状态跃迁时,Uptime Kuma 将自动发送结构化通知:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| { "heartbeat": { "monitorID": 1, "status": 0, "time": "2026-11-11 12:00:00", "msg": "Connection timeout", "ping": 3000 }, "monitor": { "name": "Blog Main Website", "url": "https://yourbrand.com" }, "msg": "[Blog Main Website] is Down" }
|
6、创建公开状态页(Status Page)
状态页是出海商业产品建立用户信任的关键组件。
- 点击左上角 Status Pages(状态页),选择 New Status Page;
- Name:输入产品状态名称(如
YourBrand Service Status);
- Slug:设置路径(例如
status,对应 URL 为 https://status.yourbrand.com/status);
- 在页面编辑区,从左侧勾选需要对外公示的公共服务分组(例如
Web Application、API Gateway、Payment Service);
- 点击 Save 并设为公开,即可生成干净专业的 SLA 状态公布页面。
7、反向代理加固与 WebSocket 长连接保障
Uptime Kuma 的 Web 前端与后台之间强依赖 Socket.io(WebSocket)进行毫秒级实时心跳同步。如果反向代理没有正确配置 WebSocket 协议升级标头,用户访问时会频繁遇到“Cannot connect to socket server”红字弹窗与不停重连的问题。
7.1 Caddy 生产反向代理配置
编辑 /etc/caddy/Caddyfile:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| status.yourbrand.com { encode gzip zstd
# 安全头加固 header { Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" X-Content-Type-Options "nosniff" X-Frame-Options "SAMEORIGIN" }
# Caddy 原生默认透传 WebSocket,只需指定后端 reverse_proxy 127.0.0.1:3001 { header_up X-Real-IP {remote_host} header_up X-Forwarded-For {remote_host} header_up X-Forwarded-Proto {scheme} } }
|
重新加载 Caddy 即可自动签发 SSL 证书:
1
| sudo systemctl reload caddy
|
7.2 Nginx 生产反向代理配置(含完整 WebSocket 协议头)
编辑 /etc/nginx/sites-available/uptime-kuma.conf:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| server { listen 80; server_name status.yourbrand.com; return 301 https://$host$request_uri; }
server { listen 443 ssl http2; server_name status.yourbrand.com;
ssl_certificate /etc/letsencrypt/live/status.yourbrand.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/status.yourbrand.com/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5;
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;
proxy_read_timeout 86400s; proxy_send_timeout 86400s; proxy_buffering off; } }
|
启用配置并检查语法:
1 2 3
| sudo ln -sf /etc/nginx/sites-available/uptime-kuma.conf /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx
|
8、高阶运维:SQLite WAL 调优与自动化备份
8.1 解决 SQLITE_BUSY: database is locked
当监控目标超过 50 个且探测频率较高时,默认 SQLite 配置可能因高频并发写入触发数据库锁死。进入容器开启 WAL (Write-Ahead Logging) 模式与自动整理:
1 2 3 4 5 6 7 8
| docker exec -it uptime-kuma sqlite3 /app/data/kuma.db "PRAGMA journal_mode;"
docker exec -it uptime-kuma sqlite3 /app/data/kuma.db "PRAGMA journal_mode=WAL;"
docker exec -it uptime-kuma sqlite3 /app/data/kuma.db "PRAGMA cache_size=-64000;"
|
8.2 自动化 SQLite 数据快照脚本
使用脚本每天对 kuma.db 制作安全备份并推送到归档目录:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #!/usr/bin/env bash
set -euo pipefail
BACKUP_DIR="$HOME/uptime-kuma/backups" mkdir -p "$BACKUP_DIR"
DATE_STR=$(date +%Y%m%d_%H%M%S) TARGET_DB="$HOME/uptime-kuma/data/kuma.db" BACKUP_FILE="$BACKUP_DIR/kuma-$DATE_STR.sqlite"
sqlite3 "$TARGET_DB" "VACUUM INTO '$BACKUP_FILE';" gzip "$BACKUP_FILE"
find "$BACKUP_DIR" -type f -name "kuma-*.sqlite.gz" -mtime +14 -delete echo "[OK] Uptime Kuma snapshot saved: $BACKUP_FILE.gz"
|
赋予执行权限并配置定时任务:
1 2
| chmod +x ~/uptime-kuma/backup.sh (crontab -l 2>/dev/null; echo "0 4 * * * /bin/bash $HOME/uptime-kuma/backup.sh >> $HOME/uptime-kuma/backup.log 2>&1") | crontab -
|
9、常见故障排错速查表
| 故障现象 |
根因定位 |
解决方案与命令 |
| 页面反复提示 Socket Disconnected |
Nginx 反代缺少 Upgrade 与 Connection 标头 |
检查并补齐 proxy_set_header Upgrade $http_upgrade; |
| 监控 Cloudflare 保护站点频繁报 521/403 |
被 Cloudflare WAF 或 Bot Management 拦截 |
在探针的高级选项中自定义合法 User-Agent,并在 CF 后台加白探针 IP |
| 容器启动后占用 CPU 100% 僵死 |
SQLite 数据库损坏或历史时序数据体积过大 |
检查 ls -lh data/kuma.db*,必要时通过 .dump 导出重建 |
| 证书到期预警未发送 |
未勾选证书监控,或探针仅配置为 TCP 类型 |
切换为 HTTP(s) 类型,并勾选 Certificate Expiry |
完成上述配置后,你的海外业务便拥有一套 7×24 小时高敏锐度的客观探针监控体系。