Beszel 完整教學 2026:11 MB 記憶體的輕量伺服器監控與告警設定

Beszel 是一套 MIT 授權、GitHub 2.6 萬星的輕量伺服器監控(Hub+Agent 架構,以 PocketBase 為後端)。本文用 Docker 實測 v0.21.1:Hub 容器閒置約 11 MB 記憶體、映像檔 47.6 MB,Agent 常駐約 15 MB,完整走過 compose 設定、加入主機、Docker 容器統計、S.M.A.R.T.、網路監控與 Shoutrrr 告警(含 ntfy/Telegram),並整理與 Uptime Kuma、Prometheus+Grafana 的定位差異與已知限制。

  • Dennis
  • 9 分鐘閱讀
Beszel 完整教學 2026:11 MB 記憶體的輕量伺服器監控與告警設定

Beszel 是一套 MIT 授權的開源伺服器監控,用「Hub + Agent」兩件元件做出主機 CPU/記憶體/磁碟/網路、Docker 容器、S.M.A.R.T. 硬碟健康與網路探測的長時間歷史圖表,外加可自訂門檻的告警。實測 Hub 容器閒置只吃約 11 MB 記憶體、映像檔 47.6 MB,適合那種「只想要一張看得懂的儀表板」而不是一整套觀測平台的場合。

為什麼還需要第三種監控工具

自架圈對監控的選擇長期卡在兩個極端:

痛點實際狀況
Uptime Kuma 只看「有沒有活」網站掛了會通知,但「CPU 連續三小時 95%」「硬碟剩 8%」「某個容器記憶體一直漲」這類慢性問題它不管你
Prometheus + Grafana 太重要 node_exporter、cAdvisor、Prometheus、Grafana 四件以上,設定檔、retention、面板 JSON 都要自己顧;小專案常常裝完就放在那裡吃資源
雲端監控要月費主機數量一多,基本方案很容易超過一台 VPS 的錢,而且 agent 會回傳內網資訊
只想看歷史趨勢很多工具只給「即時」與「最近 1 小時」,要回答「上週改設定後記憶體有沒有降」就得另外拉資料

Beszel 的定位就在中間:一個容器 + 一支 agent,資料落在自己的機器,圖表預設就有歷史區間,告警用現成的通知服務(Shoutrrr URL),不用學 PromQL。

一表看懂:規格與實測數字

以下數據分兩類標明:官方標示(GitHub/官方文件)與 本文實測(2026-10-31,在一台 Docker 主機上以獨立容器跑起來量測)。

項目內容來源
授權MIT官方(GitHub API)
GitHub 星數26,731官方,2026-10-31 查詢
最新版本v0.21.1(2026-10-22 發布)官方 release
語言Go(單一靜態執行檔)官方
架構Hub(PocketBase 後端)+ Agent官方文件
Hub 映像檔47.6 MB本文實測 docker images
Agent 映像檔15.6 MB本文實測 docker images
Hub 閒置記憶體11.2 MiB本文實測 docker stats
Agent 常駐記憶體約 15.2 MB(RSS);執行檔 10.68 MB本文實測 ps
健康檢查端點GET /api/health → {"message":"API is healthy.","code":200}本文實測 HTTP 200
資料存放單一目錄 ./beszel_data(內含 PocketBase 資料庫)官方文件

需要說明的是:Agent 的記憶體數字來自直接執行官方 Linux 執行檔(v0.21.1,amd64),不是容器內量測;docker stats 對 network_mode: host 的容器會顯示 0B,這是 Docker 本身的顯示限制,不是 agent 不耗資源。

架構:兩個元件、三種連線方式

元件角色你在哪裡看到它
Hub網頁儀表板與資料庫(PocketBase)。負責帳號、系統清單、警報規則、通知設定http://你的主機:8090(後台管理在 /_/)
Agent跑在被監控主機上,收集指標並回傳沒有介面,只有 log

Hub 與 Agent 之間有三種連線方式,選哪一種會影響防火牆設定:

方式設定方式適用場景
Unix socketAgent 的 LISTEN 指向共享 volume 裡的 socket 檔(Hub 與 Agent 同一台)單機自架,最省事、不開任何 port
WebSocketAgent 設 HUB_URL + TOKEN,主動連回 Hub被監控主機在 NAT/防火牆後面,無法被連入
SSHHub 主動連 Agent 的 45876 埠內網多主機、已有 SSH 金鑰管理

其中 WebSocket 這條路是清理防火牆最有效的一招:Agent 往外連,Hub 不需要主動打進來。Hub 端可設 DISABLE_SSH=true,讓它不再對沒有 WebSocket 連線的系統反覆撥號。

安裝:官方 compose 原文照貼

官方提供三份 compose 範本(supplemental/docker/ 目錄下):hub 單獨、agent 單獨、同一台主機兩者一起。以下是最常見的「同一台主機」版本,內容與官方檔案一致,只把埠號與容器名改成實測時使用的值:

services:
  beszel:
    image: henrygd/beszel:latest
    container_name: beszel
    restart: unless-stopped
    environment:
      APP_URL: http://localhost:8090   # 改成你實際使用的網域或 IP:port
    ports:
      - 8090:8090
    volumes:
      - ./beszel_data:/beszel_data
      - ./beszel_socket:/beszel_socket

  beszel-agent:
    image: henrygd/beszel-agent:latest
    container_name: beszel-agent
    restart: unless-stopped
    network_mode: host
    volumes:
      - ./beszel_agent_data:/var/lib/beszel-agent
      - ./beszel_socket:/beszel_socket
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      LISTEN: /beszel_socket/beszel.sock
      HUB_URL: http://localhost:8090
      TOKEN: <token>     # 從 Hub 的「Add System」對話框取得
      KEY: "<key>"       # 同上

啟動前先驗語法,再跑起來:

docker compose config --quiet && echo OK
docker compose up -d
docker compose ps

實測啟動後的 Hub log 會印出三個位置,記下來會省下不少找路時間:

Server started at http://0.0.0.0:8090
├─ REST API:  http://0.0.0.0:8090/api/
└─ Dashboard: http://0.0.0.0:8090/_/

/_/ 是 PocketBase 原生後台(資料表層級),/ 是 Beszel 自己的儀表板。多數操作在前者之外的前端完成,/_/ 只在需要直接看資料表或改使用者時用。

驗證服務真的活著:

curl -s http://localhost:8090/api/health
# {"message":"API is healthy.","code":200,"data":{}}

加入第一台主機(Hub 與 Agent 同機)

  1. 開 http://你的主機:8090,建立管理員帳號。
  2. 點右上角 Add System,Host/IP 填 socket 路徑 /beszel_socket/beszel.sock。
  3. 對話框會給你 KEY 與 TOKEN,貼回 compose 的環境變數,docker compose up -d 重啟 agent。
  4. 表格上的系統狀態變成綠色,就代表資料開始進來。

這一步有一個容易誤解的錯誤訊息。若 agent 在還沒拿到 KEY 之前就啟動,log 會直接報:

Failed to load public keys: no key provided: must set -key flag, KEY env var, or KEY_FILE env var

這不是映像檔壞了,而是設計如此:KEY 一定要先在 Hub 端建立系統後才會產生,順序反了 agent 就起不來。遠端主機(WebSocket)情境也一樣,只是改成把 HUB_URL 指向 Hub 的公開位址、LISTEN 改成 45876。

另外,0.12.0 之後支援「通用權杖(universal token)」:在 Hub 的 /settings/tokens 建一組權杖,agent 端只帶 TOKEN 就能註冊,不必事先在 UI 建系統。大量部署時比一台一台點快很多。

它到底收哪些資料

類別內容
主機CPU、記憶體(含 swap 與 ZFS ARC)、磁碟使用率、磁碟 I/O、網路流量、負載、溫度、風扇轉速
容器每個 Docker/Podman 容器的狀態、CPU、記憶體、網路用量歷史
硬碟健康S.M.A.R.T. 屬性、eMMC 壽命、Linux mdraid 陣列狀態、硬碟故障通知
ZFS池容量、使用率、健康狀態、I/O、scrub 進度、各 dataset 用量
GPUNVIDIA、AMD、Intel 的使用率與功耗(需對應映像或 collector 設定)
網路探測ICMP/TCP/HTTP/DNS 的延遲與封包遺失(Agent 0.20.0 以上)

Docker 容器資料要掛 /var/run/docker.sock(唯讀即可)。不想讓 Beszel 去查各 registry 有沒有新映像,可設 agent 的 DOCKER_IMAGE_CHECK=false;容器太多太雜,可用 EXCLUDE_CONTAINERS="test-*,*-staging" 這種 wildcard 規則排除。

告警:用 Shoutrrr URL,不用寫程式

Beszel 的通知不吃自訂 webhook JSON,而是用 Shoutrrr 的 URL schema。常用幾個:

服務URL 格式
ntfyntfy://:存取權杖@你的ntfy主機/主題名
Telegramtelegram://bot_token@telegram?chats=@頻道或chat_id
Discorddiscord://token@id
Slackslack://[botname@]token-a/token-b/token-c
Gotifygotify://主機/token
通用 HTTPgeneric://example.com?template=json

設定位置在 Settings → Notifications,警報門檻則在系統那一列的 alerts 面板逐項打開(CPU、記憶體、磁碟、溫度、頻寬、容器狀態等)。門檻是「超過就通知、回到門檻以下就自動解除」,不用自己寫狀態機。

以台灣最常見的組合來說,一條 ntfy://:tk_xxxx@ntfy.example.com/beszel 就能同時推到手機與桌面,自架 ntfy 的完整設定可以看站內另一篇教學(見文末延伸閱讀)。

反向的監控:heartbeat(死人開關)

如果 Beszel 主機自己掛了,它沒辦法通知你。Hub 支援 HEARTBEAT_URL:定期對外部服務(Healthchecks.io、BetterStack、Uptime Kuma 的 push 端點)發 ping,對方收不到就報警。用 POST 時還會附上狀態摘要:

{
  "status": "error",
  "systems": { "total": 5, "up": 3, "down": 1, "paused": 1, "pending": 0 },
  "msg": "1 system(s) down: Production-DB"
}

這個設計很實用:等於用一個免費的外部服務,幫你的自架監控買保險。

網路監控:從每台主機的視角量延遲

0.20.0 之後,Agent 可以主動探測你指定的目標,全部在 Hub UI 設定(沒有 agent 環境變數):

協定量什麼逾時算遺失的條件
icmpecho 往返時間(IPv4/IPv6)3 秒沒回應
tcp建立連線的時間(不含 DNS)3 秒連不上或逾時
httpGET 到回應的時間10 秒失敗或狀態碼 ≥ 400
dns解析主機名的時間3 秒查不到

ICMP 需要 CAP_NET_RAW 或 root;容器內若削掉了 capabilities,要在 compose 補 cap_add: [NET_RAW]。tcp/http/dns 不需要特權。

實務上這一欄最好用的是「從不同機器看同一個服務」:例如從台北與東京兩台 VPS 同時打自家 API,延遲曲線分開畫,問題是線路還是服務立刻分得出來。

與同類方案的定位差異

工具主要回答的問題安裝元件數歷史資料適合誰
Beszel這幾台機器的資源與容器用量隨時間怎麼變2(Hub+Agent)內建,圖表可切時間區間1~20 台自架主機、想一次看到全部
Uptime Kuma這個服務現在活著嗎、多久沒回應1有(可用性為主)只要「掛了通知我」
Netdata這台機器每一秒發生了什麼1(每台)有,但存檔與長期保留要另外規劃單機即時除錯
Prometheus + Grafana任意指標的自訂查詢與長期儲存4 以上有,需規劃 retention指標要做為正式 SLO、已有團隊維護
Beszel +(可選)Loki資源趨勢 + 日誌檢索3 以上分工明確想要「數字與 log 對照」的自架者

一句話選法:要可用性通知選 Uptime Kuma;要資源趨勢與容器歷史選 Beszel;要自訂指標查詢與告警規則選 Prometheus 堆疊。

已知限制與本文沒做的事

這是本站產品文的固定段落,把驗證邊界講清楚:

  • 本文實測到的:官方 compose 能直接啟動、Hub /api/health 回 200、Hub 閒置記憶體 11.2 MiB、映像檔大小、Agent 執行檔可啟動並偵測到磁碟與網路介面、未設 KEY 時的錯誤訊息。
  • 本文沒有實際點完的:因為在無圖形介面的環境驗證,「Add System」對話框那一步沒有實際點擊,所以系統轉綠、容器統計曲線、S.M.A.R.T. 讀值、告警實際送達都沒有截圖級證據。這些步驟在官方文件中有完整說明,但請把它們當成「依官方文件轉述」而非實測結果。
  • 沒有測到的規模:只驗證單機兩容器。數十台主機時的 Hub 負載、資料庫成長速度未測。
  • 它不做的事:不收集日誌(沒有 log 搜尋,要日誌請搭 Loki 或同類方案)、不做分散式 tracing/APM、不是秒級即時面板(設計取向是資源趨勢,不是即時除錯)。
  • 備份還是要自己顧:Hub 內建「自動備份到本機或 S3 相容儲存」的功能,但備份排程、還原演練屬於站主要自己負責的維運工作;./beszel_data 一定要備。
  • 通知服務本身也要活著:告警是透過外部服務送出的,若 ntfy/Telegram 掛了,你不會知道系統掛了——所以 heartbeat 那條對外 ping 建議一起設。

誰適合、誰不需要

情境建議
3~10 台 VPS/家用伺服器,想知道資源趨勢適合,兩個容器就結束
想監控硬碟健康、提早換硬碟適合,S.M.A.R.T. 與 eMMC 壽命都有
只需要網站 200 檢查用 Uptime Kuma 就夠,Beszel 反而多一層
已經有 Prometheus + Grafana 在跑不需要重複投資,除非想要更低維運成本的第二套視角
需要 log 搜尋與 trace不是它的工作,搭配 Loki/Tempo 類方案
團隊要正式 SLO 與 on-call 流程Prometheus 堆疊或商用方案更合適

怎麼開始

mkdir -p ~/beszel && cd ~/beszel
# 貼上上面的 compose(或官方 supplemental/docker/same-system/docker-compose.yml)
docker compose config --quiet && docker compose up -d
curl -s http://localhost:8090/api/health

三步就能看到儀表板。真正花時間的通常是告警門檻要不要設得合理——建議前兩週先只開「磁碟使用率」與「系統離線」兩條,等累積出自己的正常值區間,再開 CPU 與記憶體,避免一開始就被誤報淹沒。

站內延伸閱讀

參考來源

利益揭露:本文無聯盟連結,也未接受 Beszel 專案任何形式的贊助。文中標示「實測」的數字皆為 2026-10-31 在單一 Docker 主機上量測所得,版本與數字以官方頁面當下顯示為準。

📬 訂閱 most.tw 電子報

每週精選 AI 工具教學與技術乾貨,直接送到你的信箱。免費、隨時可退訂。

訂閱即表示同意收到 most.tw 電子報,隨時可一鍵退訂。

💬 有問題想討論?加 LINE 聯絡我

歡迎透過 LINE 官方帳號直接留言,我會盡快回覆你的問題。

加入 LINE 好友