如何使用 Upptime 免费搭建自己的状态站点

如何使用 Upptime 免费搭建自己的状态站点

把监控这件事整个儿搬进 GitHub 仓库------Actions 当探针、仓库当数据库、Pages 当 CDN、Issues 当事件簿。零服务器,零月费,愣是凑出一个能看能查能留痕的状态站。说是黑魔法也好,说是穷人的智慧也罢,反正它跑起来了。

背景

运维一个由十几个对外服务凑起来的小型产品矩阵时,"到底通不通"这事常常变成了口头禅。客户反馈说访问不了,你 ssh 上去 curl 一遍发现是好的;过几分钟它又挂了,可你这次没盯到。商业监控(Pingdom、UptimeRobot 的高级档、Datadog)当然能解决,只是要么按站点收费,要么按请求次数收费,对一个独立开发者来说,成本和心智负担都不太划算而已。

更关键的是,状态页本身也得让用户能查。理想的样子是:一个域名(比如 status.hagicode.com),实时展示每个服务的可用率、响应时间曲线、历史事件,故障时还能自动留痕、自动通知。传统做法要凑齐四件套------跑 cron 的服务器、存历史数据的数据库、前端站点、CDN。这四样一摆开,运维成本立刻就盖过了被监控的服务本身,毕竟杀鸡用了牛刀,鸡还嫌挤。

为了解决这些痛点,我们做了一个决定:整个监控方案直接搬到 GitHub 上。这个决定带来的变化,可能比你想的还要大------稍后我再慢慢说。

关于 HagiCode

本文分享的方案,来自我们在 HagiCode 项目里摸爬滚打的经验。HagiCode 是个 AI 代码助手项目,对外吐出了网页、文档站、下载端点等十几个公共服务,背后由 HagiCode-org/site 这个主仓库驱动着。这些站点必须稳定可用,所以状态监控对我们不是可选项,而是刚需。下面这套 Upptime 方案,正是 HagiCode 实际生产环境在用的------不是我编的。

分析:Upptime 到底是怎么跑起来的

Upptime 的本质,其实是一份 GitHub 仓库模板,加上六个由模板生成的 workflow。理解它的关键,就是看清楚"谁在什么时候、调用谁、产出什么落到哪里"。把它拆开了看,也就不那么神秘了。

数据流:一个配置文件驱动一切

整个系统,就绕着 .upptimerc.yml 这一个声明式配置文件转。HagiCode 的实际配置结构,大概是这样:

yaml 复制代码
owner: HagiCode-org
repo: upptime

sites:
  - name: HagiCode Website
    url: https://hagicode.com
  - name: HagiCode Docs
    url: https://docs.hagicode.com
  - name: Server Package Index
    url: https://index.hagicode.com/server/index.json
  # ... 共 14 个站点

status-website:
  cname: status.hagicode.com
  logoUrl: https://raw.githubusercontent.com/HagiCode-org/upptime/master/assets/upptime-icon.svg
  name: HagiCode Status
  introTitle: "**HagiCode Status**"
  introMessage: Real-time availability tracking for public HagiCode websites and download endpoints.
  navbar:
    - title: Status
      href: /
    - title: GitHub
      href: https://github.com/$OWNER/$REPO

这里有两点值得拎出来说。第一,sites 既能监控网页(返回 HTML),也能监控纯 JSON 端点(比如 index.json),Upptime 只看 HTTP 状态码和响应时间,不做内容校验。第二,cname 指向 status.hagicode.com,这要求你得拥有该域名,并把 DNS 指向 GitHub Pages------毕竟白嫖归白嫖,域名还是要自己出的。

六个 workflow 的分工

.github/workflows/ 下所有文件顶部都有一行警告 Do not edit this file directly!------它们由模板每周自动更新,你只改 .upptimerc.yml 就好。每个 workflow 用 cron 触发,调用同一个 action upptime/uptime-monitor@v1.42.6 的不同子命令,分工明确,倒也省心:

Workflow cron 命令 作用
uptime.yml */5 * * * * update 每 5 分钟探活,写 history/*.yml
response-time.yml --- response-time 计算响应时间统计
graphs.yml --- graphs 生成日/周/月/年 PNG 曲线
summary.yml --- summary 更新 README 里的状态表
site.yml 0 1 * * * site 每日构建静态站,部署到 Pages
update-template.yml 0 0 * * * --- 每周同步上游模板

uptime.yml 的核心片段,展示了"探针"是怎么跑的:

yaml 复制代码
on:
  schedule:
    - cron: "*/5 * * * *"
jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          token: ${{ secrets.GH_PAT || github.token }}
      - name: Check endpoint status
        uses: upptime/uptime-monitor@v1.42.6
        with:
          command: "update"
        env:
          GH_PAT: ${{ secrets.GH_PAT || github.token }}
          SECRETS_CONTEXT: ${{ toJson(secrets) }}

site.yml 则多了一步,用 peaceiris/actions-gh-pages@v4 把构建产物推到 gh-pages 分支:

yaml 复制代码
- uses: peaceiris/actions-gh-pages@v4
  with:
    github_token: ${{ secrets.GH_PAT || github.token }}
    publish_dir: "site/status-page/__sapper__/export/"
    user_name: "Upptime Bot"
    user_email: "73812536+upptime-bot@users.noreply.github.com"

数据落盘:文件即数据库

监控结果不存数据库,而是直接以文件形式 commit 回仓库。这听起来有点野,但用起来倒也踏实。每个站点有三类产物。

状态快照 history/{slug}.yml,例如 history/hagi-code-website.yml

yaml 复制代码
url: https://hagicode.com
status: up
code: 200
responseTime: 96
lastUpdated: 2026-06-17T00:22:34.485Z
startTime: 2026-03-24T10:07:32.531Z

shields.io 的 endpoint 徽章数据源 api/{slug}/response-time.jsonuptime.json

json 复制代码
{"schemaVersion":1,"label":"response time","message":"739 ms","color":"yellow"}

以及响应时间曲线图 graphs/{slug}/response-time-{day,week,month,year}.png

这套"文件即数据库"的取舍,其实想得挺清楚:写多读少、规模可控(每个站点一天约 288 条采样,存增量而非全量)、天然带版本历史、零基础设施。代价嘛,就是仓库会持续长大,偶尔得回头关心一下它而已。

事件与通知:Issues 当事件簿

故障留痕靠 GitHub Issues,配合仓库自带的两个模板:.github/ISSUE_TEMPLATE/bug_report.md(用户报障)和 maintainance-event.md(计划性维护)。维护模板用 frontmatter 表达时间窗:

markdown 复制代码
<!--
start: 2021-08-24T13:00:00.220Z
end: 2021-08-24T14:00:00.220Z
expectedDown: google, hacker-news
-->

Upptime 会解析这些 Issue,把"正在维护"和"已发生事件"渲染到状态页和 README 上。通知则靠 Issue 自身的 watch 机制,外加可配置的 webhook、Slack、Telegram(在 .upptimerc.yml 顶部声明 notifications,HagiCode 的示例仓库目前没启用,毕竟能少一样是一样)。

解决:五步复刻一套状态站

复刻一套 HagiCode 同款状态站,从零到上线,一共五步。说是五步,其实每步都不长,慢慢来就是。

第 1 步:从模板创建仓库

git clone 后改,直接用 GitHub 的 "Use this template" 创建仓库(例如 your-org/upptime)。模板已经内置了全部 workflow、Issue 模板和静态站点骨架。clone 到本地后,唯一需要手改的就是 .upptimerc.yml------其它的,留着别动就好。

第 2 步:编辑 .upptimerc.yml

owner/repo 改成你的,sites 列出要监控的地址,status-website 配置站点。最小可用版本大概是这样:

yaml 复制代码
owner: your-org
repo: upptime

sites:
  - name: Main Site
    url: https://example.com
  - name: API Health
    url: https://api.example.com/health
    expectedStatusCodes:
      - 200

status-website:
  cname: status.example.com   # 没有域名可删掉,用默认的 your-org.github.io/upptime
  name: Example Status
  introTitle: "**Example Status**"
  introMessage: 服务可用性实时监控
  navbar:
    - title: Status
      href: /
    - title: GitHub
      href: https://github.com/$OWNER/$REPO

进阶项:expectedStatusCodes 限定可接受的状态码(默认 200-399);headers 自定义请求头(用于需要鉴权的端点);maxResponseTime 标记慢响应。这些都看你需要,按需取用罢了。

第 3 步:配置 Secret 与权限

workflow 默认用 ${{ secrets.GH_PAT || github.token }}github.token 能跑通基本流程,但有两个限制会咬人:

  1. 默认 token 触发的 workflow 不会再触发下游 workflow(防止循环),导致"探活 → 建 Issue → 通知"这条链断在中间。
  2. 跨仓库操作(比如多组织)权限不足。

推荐新建一个 PAT(需要 repo + workflow 权限),存为仓库 Secret GH_PATupdate-template.yml 里专门有一段检查:没有 GH_PAT 就跳过模板自动更新并打印 warning,所以这个 secret 不只是可选项,更是省心的关键。

第 4 步:开启 GitHub Pages

仓库 Settings → Pages → Source 选 Deploy from a branch,分支选 gh-pages、目录 /rootsite.yml 每天凌晨 1 点会自动把构建产物推到这个分支。如果配了 cname,再到你的 DNS 服务商加一条 CNAME 记录指向 your-org.github.io

第一次手动触发一下也好:Actions 页面找到 "Static Site CI" → Run workflow,不用傻等定时任务,毕竟能早一秒看到结果,心里就早一秒踏实。

第 5 步:验证与维护

push 配置后,去 Actions 看 "Uptime CI" 是否每 5 分钟跑一次、history/ 是否开始出现 *.yml 文件。状态页地址就是 https://<your-org>.github.io/upptime/ 或你的自定义域名。后续加站点、改域名,只动 .upptimerc.yml 一个文件就行,workflow 全自动。HagiCode 这一年多就靠这套机制维护 14 个端点的可用性,基本没怎么操心过。

实践:踩过的坑都替你趟过了

下面这几条,是 HagiCode 实际运行中积累下来的经验,写出来也好让你少走点弯路。

实践 1:监控粒度选择

HagiCode 把网页(https://hagicode.com)和纯数据端点(https://index.hagicode.com/server/index.json)放在同一个 sites 列表里。对 JSON 端点,Upptime 会请求并解析 HTTP 状态码,但不校验内容结构。如果你需要"返回 200 但内容错误"这种深度检查,得用 expectedStatusCodes 加上外部探针来补,Upptime 本身只做黑盒 HTTP 检查------它只看脸色,不读心事。

实践 2:响应时间徽章的妙用

api/{slug}/response-time.jsonshields.ioendpoint 徽章 数据源。HagiCode 的 README 里大量引用这种 URL:

perl 复制代码
https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FHagiCode-org%2Fupptime%2FHEAD%2Fapi%2Fhagi-code-website%2Fresponse-time.json

这样一来,你就能在任何 Markdown(项目 README、博客、第三方页面)里嵌入实时响应时间徽章,颜色由 message 里的数值和 color 字段驱动。注意用 HEAD 而不是 master/main 引用 raw 文件,能避免分支改名后大面积失效------细节之处,藏着安稳。

实践 3:仓库体积控制

每 5 分钟一次采样,一年下来 history/ 会累积出可观的体积。Upptime 用增量 YAML 而非全量日志,相对克制,但仍建议定期看一眼仓库大小。如果某个站点监控价值下降了,从 sites 移除即可,对应的历史文件也可以手动清理掉,毕竟舍不得删,仓库迟早会臃肿给你看。

实践 4:维护事件的真实用法

maintainance-event.md 不是摆设。计划发版前,按模板开一个 Issue,填好 start/end/expectedDown,Upptime 会把这段时间内的对应站点标记为"计划内维护",不计入可用率统计,避免一次正常发版把全年 SLA 拉低。HagiCode 的 expectedDown 支持逗号分隔的站点名列表,与 sites[].name 一一对应。

实践 5:模板更新与自定义的边界

所有 .github/workflows/*.yml 顶部的 Do not edit this file directly!,不是吓唬人的。update-template.yml 每周会用上游模板覆盖这些文件。需要自定义行为时,正确做法是在 .upptimerc.yml 里用官方支持的配置项(如 skipTopicscustomStatusWebsiterunnerSettings),而不是去改 workflow。实在要改 workflow,要么关掉 update-template.yml,要么 fork 出来自己维护模板------后者会失去无痛升级,得失之间,自己掂量罢了。

实践 6:免费额度的现实约束

GitHub Actions 对公开仓库免费、不限时长,Upptime 设计上正是利用了这一点。私有仓库每月有 2000 分钟免费额度,而 uptime.yml 每 5 分钟跑一次、每次约 1 分钟,单这一项一个月就大概 8640 分钟,会超额。所以 Upptime 仓库必须是 public,这是"免费"两个字的前提------别图保密开成 private,然后收到账单,那就尴尬了。

总结

回到开头那个问题:监控一堆对外服务,到底有没有便宜的解法?HagiCode 的答案是------有,而且便宜得让你怀疑这是不是真的。Upptime 把监控拆成了四个 GitHub 原生组件:

  • 探针 = GitHub Actions 的 cron
  • 数据库 = 仓库里的 YAML/JSON 文件
  • CDN = GitHub Pages
  • 事件簿 = GitHub Issues

你得到的是:实时可用率、响应时间曲线、历史事件、可用率徽章、自定义域名、自动通知,全部零服务器、零月费。代价是要保持仓库公开,以及偶尔关心一下仓库体积。其实这点代价,比起手搓一套监控,已经轻得太多。

这套方案之所以能跑通,背后是 GitHub 生态对开源项目的诚意补贴。如果你也在维护一个多站点的小型产品矩阵,强烈建议花一个下午把它搭起来,比手搓监控省心太多。

参考资料

总结

围绕"如何使用 Upptime 免费搭建自己的状态站点",更稳妥的推进方式是先把关键配置、依赖边界和落地路径逐步跑通,再补齐优化细节。

当目标、步骤和验收点都明确之后,这类方案通常就能更顺畅地进入实际交付。

原文与版权说明

感谢您的阅读,如果您觉得本文有用,欢迎点赞、收藏和分享支持。 本内容采用人工智能辅助协作,最终内容由作者审核并确认。

相关推荐
沉默王二6 小时前
老板:“请说出一个录用你的理由。”我脱口而出:“每个月 AI 支出都超过我的生活费了!”老板愣了一下,随即哈哈大笑:“好吧,你被录用了。”
人工智能·ai编程·claude
乘风gg8 小时前
OpenClaw 爆火,但”飞书"赢麻了!!!
前端·ai编程·claude
_山海1 天前
Claude Code安装指南和初次使用
claude
ZJPRENO1 天前
Claude 桌面版 Cowork vs Code模式区别
claude
ZzT1 天前
谈谈 AI-Ready 和 AI-SDLC
openai·ai编程·claude
gis分享者1 天前
GPT-Image-2 图像生成模型新手实战指南
gpt·ai·image·模型·图像生成
星空1 天前
cloude操作流程
claude