如何使用 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 的實際配置結構,大概是這樣:
owner: HagiCode-orgrepo: upptime
sites: - name: HagiCode Website url: https://www.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 的核心片段,展示了”探針”是怎麼跑的:
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 分支:
- 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:
url: https://www.hagicode.comstatus: upcode: 200responseTime: 96lastUpdated: 2026-06-17T00:22:34.485ZstartTime: 2026-03-24T10:07:32.531Zshields.io 的 endpoint 徽章數據源 api/{slug}/response-time.json、uptime.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 表達時間窗:
<!--start: 2021-08-24T13:00:00.220Zend: 2021-08-24T14:00:00.220ZexpectedDown: 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 配置站點。最小可用版本大概是這樣:
owner: your-orgrepo: 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 能跑通基本流程,但有兩個限制會咬人:
- 默認 token 觸發的 workflow 不會再觸發下游 workflow(防止循環),導致”探活 → 建 Issue → 通知”這條鏈斷在中間。
- 跨倉庫操作(比如多組織)權限不足。
推薦新建一個 PAT(需要 repo + workflow 權限),存為倉庫 Secret GH_PAT。update-template.yml 裡專門有一段檢查:沒有 GH_PAT 就跳過模板自動更新並打印 warning,所以這個 secret 不只是可選項,更是省心的關鍵。
第 4 步:開啟 GitHub Pages
倉庫 Settings → Pages → Source 選 Deploy from a branch,分支選 gh-pages、目錄 /root。site.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://www.hagicode.com)和純數據端點(https://index.hagicode.com/server/index.json)放在同一個 sites 列表裡。對 JSON 端點,Upptime 會請求並解析 HTTP 狀態碼,但不校驗內容結構。如果你需要”返回 200 但內容錯誤”這種深度檢查,得用 expectedStatusCodes 加上外部探針來補,Upptime 本身只做黑盒 HTTP 檢查——它只看臉色,不讀心事。
實踐 2:響應時間徽章的妙用
api/{slug}/response-time.json 是 shields.io 的 endpoint 徽章 數據源。HagiCode 的 README 裡大量引用這種 URL:
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 裡用官方支持的配置項(如 skipTopics、customStatusWebsite、runnerSettings),而不是去改 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 免費搭建自己的狀態站點”,更穩妥的推進方式是先把關鍵配置、依賴邊界和落地路徑逐步跑通,再補齊優化細節。
當目標、步驟和驗收點都明確之後,這類方案通常就能更順暢地進入實際交付。
开始使用 HagiCode
一次安装,几分钟上手
HagiCode for Windows 在 Microsoft Store 免费提供。打开商店即可安装并保持更新;也可以先对比各版本与定价,再决定从哪个渠道开始。