Skip to content

UptimeFlare:不用自己备服务器的网站监控与状态页 ​

服务半夜挂了,往往要等到用户在群里发消息才知道。这类问题的标准解法是一台 7x24 的监控机:自己租服务器跑 Uptime Kuma,或者依赖 SaaS 监控的免费档。UptimeFlare 走了另一条路——探活任务由 Cloudflare Workers 的定时触发器每分钟在全球边缘节点上执行,状态页是构建后托管在 Cloudflare Pages 的一组静态文件加一份 D1 数据库读数,两者都落在 Cloudflare 免费额度内。整个部署不需要本地安装任何东西:从模板生成自己的仓库、填一个 API Token、编辑仓库根目录的 uptime.config.ts,GitHub Actions 会把监控 Worker、状态页和数据库一次性建好。

按 README 的说法,这套方案可以承载 50 个每分钟检查的监控目标,探测可来自 310 多个 Cloudflare 城市节点,并保留 90 天可用性历史;这些数字是仓库对免费额度下可达规模的声明,本文未实际压测。

GitHub 仓库信息 ​

信息内容
项目标题UptimeFlare
项目描述运行在 Cloudflare Workers 上的免费无服务器网站可用性监控与状态页,支持按地区发起探测
GitHub 仓库lyc8503/UptimeFlare
官网地址未知(已检索但未找到可靠官网;官方文档托管在 GitHub Wiki,作者维护的在线演示见 uptimeflare.pages.dev,核对日 2026-09-23 可访问)
主要开发语言TypeScript 93.27%、JavaScript 2.52%、Python 2.21%
开源许可证Apache-2.0
最近代码更新2026-06-01(GitHub pushed_at,核对日期:2026-09-23)

一份 TypeScript 文件管住所有配置 ​

UptimeFlare 没有管理后台,也没有数据库里的设置表。监控对象、状态页标题、通知渠道、维护窗口,全部写在仓库根目录的 uptime.config.ts 里,由构建流程打包进 Worker 和状态页。改配置的动作就是改代码:提交、推送、等流水线跑完。

monitors 数组是核心。HTTP 监控除了 URL,还能指定请求方法、headers、body、可接受的 expectedCodes(默认 2xx),以及 responseKeyword / responseForbiddenKeyword 两种响应内容断言——网关返回 200 但页面里写着 "database error" 的情况可以被判为故障。TCP 监控把 method 设为 TCP_PING、target 写成 host:port,用来盯数据库或 SSH 端口是否可连。状态页一侧,pageConfig 负责标题、头部链接和分组展示,passwordProtection 可以给整个页面加一层 HTTP Basic 认证,maintenances 数组声明的计划内维护会在页面上挂横幅,并在维护期间跳过对应的宕机通知。

仓库里同时提供 uptime.config.full.ts 作为全量参考:包括用 IIFE 生成每月循环维护窗口这类 TypeScript 才玩得动的写法,也提醒这种动态生成可能引入不确定输出,调试不了就慎用。

探针从哪里发出,由你指定 ​

监控 worker 被 Cloudflare 的 cron 触发时,会在某个随机边缘数据中心执行;对绝大多数探活这无所谓,但当被监控的服务只对特定地区友好(比如只对内地图加速的站点),探针落在哪里就决定了结果是真实故障还是连通性误报。UptimeFlare 用一个 checkProxy 字段解决这件事,官方文档给出三种方案:

写法探测执行者适合场景
worker://weur部署在你账号内、通过 Durable Objects 固定在指定 Cloudflare 地区的远程检查器选择官方列出的地区参数(如西欧 weur)即可,无需额外部署
globalping://<token>/?magic=CN第三方 Globalping 的全球探针网络需要城市/ASN 级粒度或境内探针;标记为实验性,POST 监控和 checkProxyFallback 在该模式下不生效
https://proxy.example.com/自建 Node.js 检查代理(仓库 proxy/ 目录),可跑在 VPS 或 Vercel 等平台监控内网服务或 Cloudflare 覆盖不到的地区;代理端要用公网可达的域名地址(HTTP 也行),不能是裸 IP 或自签证书

早期的定区域方案 checkLocationWorkerRoute 因 Cloudflare 内部变更在 2025-04-13 被官方移除,读到旧教程里扫描地域 IP、配 Workers 路由的做法可以直接跳过。

状态变化之外还有响应延迟数据。源码显示 worker 用 p-limit 把并发检查数压到 5(注释写明 Cloudflare Workers 的上限是 6 个并发连接,取 5 保险)。每分钟的检查结果先并入一份压缩状态,再整体写回 D1 的那张两列 key/value 表:延迟时间戳定宽转十六进制串接、探测地点做游程编码(store.ts)。D1 的写入量直接对应免费额度消耗,deploy.tf 的 cron 注释因此指向了节流阀 kvWriteCooldownMinutes:默认没有状态变化时每 3 分钟才落一次盘,宕机与恢复则即时记录。

状态页:一份构建产物,两种消费方式 ​

状态页是 Next.js 前端经 @cloudflare/next-on-pages 编译后的 Pages 部署,交互延迟图、事故历史页、维护横幅、深色模式跟随和中英德法繁中多语言界面都在这份静态产物里。页面上没有后端 API 进程:数据从 Pages 函数直接读同一块 D1 数据库。

对外的消费入口有三个。/api/data 返回实时 JSON(各 monitor 的当前状态、延迟、最后一次探测所在数据中心和错误信息),适合把状态接进自己的仪表盘;URL 追加 #monitor_id 可以把单个监控卡片以 iframe 嵌进别的网页;pages/api/badge.ts 则输出 Shields 风格的总体状态徽章。README 功能清单里的 CNAME 自定义域名,操作是在 Cloudflare 控制台对 Pages 项目(不是 Worker)Setup custom domain,官方 Wiki 有一页截图说明。

通知走统一的 webhook 配置:指定 url、payloadType(param / json / x-www-form-urlencoded)和 payload,正文里的 $MSG 占位符会被替换成人话的状态变更消息,Telegram Bot、企业微信机器人、Pushover 在通知文档里都有可直接照抄的示例。gracePeriod 控制抖动抑制——监控持续宕满 N 分钟的连续检查后才发通知,恢复消息只对已通知过的故障发送。早期的 Apprise 聚合方案仍可用,但官方已把通用 webhook 列为推荐路径。

十分钟部署到 Cloudflare ​

以下流程按 官方 Quickstart 整理,本文未实际执行部署;前置条件是两个账号——Cloudflare 免费账号(不要求信用卡)和 GitHub 账号。

  1. 在 Cloudflare 控制台 API Tokens 页面 用 Edit Cloudflare Workers 模板创建 Token,并手动补上 D1 Edit 权限——存储层迁移到 D1 之后这一步不能省,缺权限时流水线会在建库脚本处以认证错误直接失败。
  2. 从没碰过 Workers 的新账号,先去控制台打开一次 Workers 落地页。这一步会静默开通部署所必需的 workers.dev 子域,跳过则初始化阶段会失败。
  3. 对 lyc8503/UptimeFlare 点击 Use this template 建自己的仓库。配置里可能要填 Bearer Token 之类的凭据,介意可见性的建私有仓库。
  4. 在自己仓库的 Settings → Secrets and variables → Actions 里新建 Secret,名字为 CLOUDFLARE_API_TOKEN,值为第一步的 Token。账号 ID 可以不填,流水线会自动查询。
  5. 编辑仓库根目录的 uptime.config.ts,把示例 monitor 的 target 换成自己的站点,id 保持不变历史数据才能延续。
  6. 推送后到 Actions 观察 Deploy to Cloudflare 工作流。配置有语法错误时流水线会红在构建阶段,改对再推即可。

成功的信号很直观:Cloudflare 控制台的 Workers & Pages 里出现 uptimeflare(Pages 项目)和 uptimeflare_worker(Worker)两个资源,打开 Pages 项目的默认域名就能看到自己的状态页,访问 /api/data 能返回带 monitor 状态的 JSON。此后改配置只需要重复第五步,流水线会自动对齐所有资源。

部署下去的到底是哪些资源 ​

状态页与探针共享一块 D1 数据库:deploy.tf 声明了全部四类云资源——D1 数据库 uptimeflare_d1(开启自动读复制)、绑定 UPTIMEFLARE_D1 的 Worker uptimeflare_worker、每分钟整点触发的 cron * * * * *、生产分支为 main 的 Pages 项目。Worker 还绑定了名为 REMOTE_CHECKER_DO 的 Durable Object,worker:// 区域探测正是由该对象在指定地区执行;流水线会先探测账号里是否已有这个命名空间,只在缺失时启用迁移。

部署工作流固定了版本口径:Terraform 1.6.4、Cloudflare provider v5(~> 5)、Node.js 22.x,运行时 compatibility_date 为 2025-04-02 并开启 nodejs_compat。数据库表由 deploy/init_d1.py 建(一张 key/value 表),老用户的历史数据由 deploy/migrate_kv.py 自动搬运。凭据面很小:整条流水线只需要 GitHub 里那一个 CLOUDFLARE_API_TOKEN Secret。

变更日期对使用方的影响
存储从 KV 迁到 D12026-01-03API Token 需补 D1 Edit 权限;历史数据自动同步,旧 KV 数据被清除,升级后延迟数据完整回填可能需要约 12 小时
通知改为通用 webhook2025-10-15沿用 Apprise 的配置需要按新格式改写
维护窗口功能引入2025-05-01旧配置文件需按 master 模板微调
移除 checkLocationWorkerRoute2025-04-13旧的定区域配置失效,改用 checkProxy

升级走仓库自带的 Upstream Sync 工作流:在自己的仓库里手动触发,代码会自动从上游合并并重新部署;当工作流文件本身有更新时,需要临时提供一个带 Workflows 与 Contents 权限的 GitHub Token。UptimeFlare 上游仓库没有发布过任何 Git tag 或 Release,版本粒度就是 main 分支头,上游同步文档按日期记录破坏性变更。回滚没有官方流程,可行的做法是把自有仓库 checkout 到旧提交再触发部署,历史数据仍在 D1 中不至于丢失,但新格式写回旧版本读取的行为没有文档背书。

值得先知道的限制 ​

  • 一切绑在 Cloudflare 免费额度上。GitHub issue 里有用户报告使用区域代理时撞上 Durable Objects 免费层的时长上限(#109),也有讨论要求聚合探测请求以降低消耗(#46)。监控数量少时这层风险很低,把上百个目标搬到 UptimeFlare 上之前值得先读这两条。
  • 凭据与配置同仓。监控 headers 里的 Bearer Token、通知 URL 中的机器人密钥都明文写在 uptime.config.ts,仓库必须按私有的姿态管理。2026-03-04 修复的安全公告(CVE-2026-29779)涉及 41257c6(2025-09-21)至修复日之间的版本会把配置暴露给客户端,仍在使用该区间部署的用户应尽快升级。
  • 部署链路是 GitOps 单向的:控制台里手改资源会被下一次 terraform apply 对齐回去,改配置永远回到 uptime.config.ts。
  • 本地部署方向已有官方 Dockerfile 和 entrypoint(用 wrangler 本地跑 Worker 与 Pages、cron 打 __scheduled 端点),README 也勾选了该项,但官方文档明确标注 docs WIP,issue #157 仍在讨论中。生产采用建议以 Cloudflare 路径为准。
  • 功能上,ICMP ping 和 SSL 证书检查在 README 的待办清单里处于未完成状态;需要这两项的读者要考虑 Uptime Kuma(自备服务器、功能面更全)或商业监控服务。

工作原理:配置的两次生命 ​

回到第一次部署成功后读者最好奇的问题:改一行配置,云端发生了什么。

Mermaid 流程图
查看源码
flowchart LR
    A["push uptime.config.ts"] --> B["GitHub Actions<br/>构建 worker 与 Pages 产物"]
    B --> C["Terraform apply<br/>对齐 D1 / Worker / cron / Pages"]
    B --> D["wrangler pages deploy<br/>上传状态页静态产物"]
    E["Cloudflare cron 每分钟"] --> F["uptimeflare_worker<br/>scheduled: 并行探活"]
    F -- "结果写入" --> G[("D1 uptimeflare_d1")]
    F -. "checkProxy=worker://region" .-> H["Durable Object<br/>RemoteChecker 异地执行"]
    D -- "页面函数读取" --> G
    G --> I["状态页 / /api/data"]

配置在这条链上被消费了两次。部署期,Actions 把 uptime.config.ts 连同源码构建成 worker bundle 和 Pages 静态产物,Terraform 只负责资源形状;运行期,worker 的 scheduled 入口直接 import 这份配置数组逐个发起检查——这就是为什么没有管理界面:改配置等价于重新发布一份编译了配置的代码。状态页一侧同理,pages/index.tsx 在服务端渲染时用 getFromStore 读 D1,pages/api/data.ts 则把同一份压缩状态整理成实时 JSON。

理解了这一点,设计选择就各归其位:id 不变历史才延续,因为监控记录按 monitor id 挂在那份压缩状态里;前面看到的十六进制压缩与写入节流,则同出于免费额度这一条预算逻辑。

下一步 ​

  • 给最想盯的那个接口配上通知:从 Setup notification 挑 Telegram 或企业微信示例,加上 gracePeriod: 2,亲手制造一次超时(指向一个不存在的端口)验证通知到达。
  • 试用区域探测:给某个 monitor 加 checkProxy: 'worker://weur',观察状态页延迟图里探测节点标识的变化。
  • 想读源码的话,worker/src/monitor.ts 里 HTTP/TCP/代理三条检查分支和 worker/src/store.ts 的压缩存储是全项目信息密度最高的两个文件;本地开发按 How to develop 的建议改码推送、交给 Actions 重新部署,嫌流水线慢可以在本机跑工作流里的构建与 wrangler deploy;仓库根 package.json 还有一个 preview 脚本,用 wrangler pages dev 在本地预览状态页。

参考资料 ​

全部公开文章由同一个站点构建和发布。