Uptime Kuma Docker 自架監控與警報設定
使用 Docker 部署 Uptime Kuma,監控網站、連接埠、DNS 與 cron jobs,並透過電子郵件或 Telegram 發送警報,從獨立 VPS 發布狀態頁面。
建置內容
這是一個小型獨立容器,從外部監控其他伺服器與網站,並在其中一個停止回應時,立即透過電子郵件、Telegram、Discord 或 webhook 通知你。Uptime Kuma 是由 SQLite 檔案支援的單一 Node 程序,因此只需 256-512 MB RAM 即可穩定執行,並提供即時儀表板、歷史圖表及公開狀態頁面。安裝只需要十行 Compose 檔案;真正重要的是 執行它的位置,以及 警報是否曾在測試中成功觸發。因為如果從未確認監控程式能夠聯絡到你,還不如完全沒有監控:它會讓你以為系統受到監控,實際上卻沒有監看任何內容。
在監控目標無法影響的位置執行監控程式
這項決策會直接影響整體架構,因此優先處理。不要將 Uptime Kuma 與受監控的服務部署在同一台主機上。 如果監控程式位於受監控的伺服器上,當該伺服器故障或記憶體耗盡時,監控程式也會一併停止,完全不會發出警示:故障監控程式的無聲狀態,與「一切正常」看起來完全相同。即使主機仍在運作,也有較不明顯的問題:指向 localhost 的監控程式會與工作負載共用 CPU,因此負載突增時,自身的檢查可能逾時,並將目標誤判為 down,形成誤報;但實際使用者仍能正常存取服務。
因此,應將 Uptime Kuma 執行在與受監控主機不同的 VPS 上,最好位於不同的供應商或區域,並以使用者的存取方式連線至服務:透過公用網際網路,使用主機名稱。使用低價的執行個體即可,一台小型監控 VPS 就能監控所有伺服器。對於託管的高負載應用程式,這種隔離尤其重要。例如,PhotoPrism 或 Immich 相片庫在索引新匯入的資料時,可能讓 CPU 持續滿載數小時;如果監控程式共用同一套硬體,就會將僅是忙碌中的服務誤判為 down。若要偵測 Kuma 本身停止運作,請從其他位置透過 cron 傳送 push heartbeat。
先決條件與規模評估
- 全新 Ubuntu 24.04 VPS,已安裝 Docker Engine 與 Compose v2 plugin,且是從 Docker 自有的 apt repository 安裝,而非套件落後的
docker.iodistro package。 - 256 MB RAM 可執行少量監控項目;若要執行數十個監控項目並搭配反向代理,512 MB 至 1 GB 會較為充裕。各次檢查之間的 CPU 使用率接近閒置。
- 網域與 DNS
Arecord(例如status.example.com指向 VPS),僅在需要 TLS 與公開狀態頁面時才需要。私人 instance 可略過 DNS,改用 VPN 或 SSH tunnel。 - 可連出至警示目的地的網路:連往郵件供應商的 SMTP,或連往 Telegram 與 Discord 的 HTTPS。
Compose 檔案
將以下內容放入 /srv/uptime-kuma/compose.yaml。
services:
uptime-kuma:
image: louislam/uptime-kuma:2
container_name: uptime-kuma
restart: unless-stopped
ports:
- "127.0.0.1:3001:3001"
volumes:
- kuma-data:/app/data
volumes:
kuma-data:啟動服務,並監看首次啟動過程:
sudo mkdir -p /srv/uptime-kuma
# save the file above as /srv/uptime-kuma/compose.yaml, then:
cd /srv/uptime-kuma && sudo docker compose up -d
sudo docker compose logs -f uptime-kuma正確啟動時,日誌會記錄 Listening on 3001,之後不再輸出訊息。該檔案中的 3 項設定是刻意如此配置的。
使用 127.0.0.1:3001:3001,而不是 3001:3001。 Docker 會以 DNAT 規則發布連接埠,且該規則在 ufw 看到封包之前就會套用。因此,單獨使用 3001:3001,無論防火牆設定為何,都會讓儀表板暴露在公開網際網路上。繫結至 loopback 可維持私有存取,只公開反向代理;私有執行個體也可以略過代理,改用 自架的 WireGuard VPN 存取 3001。
在 /app/data 使用具名 volume。 Uptime Kuma 記錄的所有內容,包括 SQLite 資料庫、監控項目、通知設定及狀態頁面標誌,都會儲存在該 volume。遺失後,服務會從空白的管理畫面開始;這是唯一必須備份的內容。
映像檔固定使用主要版本標籤 :2。 這是目前的穩定版本線。複製設定前,請先查看 Docker Hub 上最新的主要版本。不要追蹤 latest 這類會變動的標籤,因為專案已將其棄用。此映像檔升級主要版本時,會執行單向的資料庫遷移。應該刻意觸發這項操作,不要在例行 pull 時意外執行。
有一點需要注意:/app/data 必須位於支援 POSIX 檔案鎖定的檔案系統上。本機 Docker volume 沒有問題;在 NFS 上,SQLite 資料庫會損毀,並出現 SQLITE_BUSY 與 database disk image is malformed。因此,絕對不要使用網路共用。
首次執行:建立管理員帳號
透過代理伺服器瀏覽 https://status.example.com,或使用 SSH 通道:執行 ssh -L 3001:127.0.0.1:3001 user@your-vps,然後開啟 http://localhost:3001。第一個頁面是設定管理員使用者名稱與密碼的表單;系統沒有預設登入資訊。請設定真正安全的密碼:此儀表板可以查看所有受監控服務的內部位址與權杖。之後忘記密碼?請從主機重設,不要使用瀏覽器:
sudo docker compose exec uptime-kuma npm run reset-password先新增通知頻道並進行測試
先設定警示,再新增監控項目。這樣建立每個監控項目時,就能直接附加通知頻道。前往 Settings then Notifications then Setup Notification,並使用每個頻道的 Test 按鈕確認訊息確實送達,因為未經測試的通知,是設定無聲失敗的第二常見原因。
Email (SMTP)。 填寫主機、連接埠、加密方式、使用者名稱、密碼、From 和 To。可正常運作的組合有兩種:465 並將「Secure」設為 TLS/SSL,或 587 搭配 STARTTLS。對 Gmail 及大多數啟用雙因素驗證的服務供應商,必須產生 app password;使用一般帳戶密碼會回傳 Error: Invalid login: 535-5.7.8 Username and Password not accepted。
Telegram。 傳送訊息給 @BotFather,再傳送 /newbot,並複製 bot token。若要取得 chat ID,先對新的 bot 傳送一次訊息,開啟 https://api.telegram.org/bot<token>/getUpdates,再從 JSON 讀取 chat.id。如果從未先傳送訊息給 bot,getUpdates 會是空的,bot 也沒有可傳送訊息的目的地。
Discord。 在頻道中開啟 Edit Channel then Integrations then Webhooks then New Webhook,複製 URL,並將其貼上作為 Discord 通知。
Generic webhook。 若要使用其他服務,例如 Slack incoming webhook、自訂端點或家庭自動化 hook,Webhook 類型會將 JSON payload POST 至你提供的 URL。內建的 Apprise 整合也涵蓋清單中其他約九十種服務。若不希望第三方介於服務中斷與手機之間,請選擇內建的 ntfy 類型,並將其指向 自行執行的 ntfy 伺服器。系統會透過由你全程控制的頻道,將通知推送至手機。
新增監控項目,一次設定一種類型
按一下 Add New Monitor,選擇類型,然後設定 Friendly Name、Check Interval(60 seconds 通常合適)、Retries(在判定「down」前允許的連續失敗次數;設定為 2 或 3,可避免單一封包遺失就觸發通知),以及要觸發的通知。以下是會使用的類型:
- HTTP(s). 完整 URL。狀態碼符合條件即視為正常(預設為 200-299;如果
301或401對你的服務屬正常狀態,可在 Accepted Status Codes 中放寬範圍)。這是網站與 API 的主要監控方式。 - HTTP(s) - Keyword. 使用相同的請求,但除了狀態碼正常外,回應內容中也必須包含指定字串;若啟用 Invert,則必須不包含該字串。這可偵測網站雖回傳
200 OK,卻顯示「Error establishing a database connection」的情況;單純的 HTTP 監控會將其判定為正常。對於連接獨立後端的瀏覽器前端,這也是適合的監控方式。例如 Jellyfin 上的 Halcyon 影音商店面板,其頁面外殼可能正常回傳200,但後方的媒體伺服器已無法連線。 - TCP Port. 對主機與連接埠建立基本 TCP 連線,適用於非 HTTP 服務,例如 22 上的 SSH、5432 上的 Postgres、25 上的 SMTP 伺服器,以及遊戲伺服器。
- Ping. ICMP echo,用於低成本檢查可連線性與延遲。不過許多網路與雲端防火牆會丟棄 ICMP,因此紅色的 ping 監控可能表示「主機停止運作」,也可能表示「供應商封鎖 ping」;請使用 TCP 監控確認。
- DNS. 使用指定的 resolver 查詢記錄(A、AAAA、MX、TXT 等),並可驗證回應內容,以便及早偵測註冊商或 DNS 中斷。
- Push. 由內向外的監控方式,下一節會說明。
監控 cron 工作的 push(heartbeat)監控
上述每個監控都會從外部主動連入您的服務。push 監控則相反:Uptime Kuma 會等待,由您的工作呼叫它並回報「我已執行」。這是監控備份或 cron 的唯一可靠方式:HTTP 檢查只能知道 URL 有回應,但只有該工作知道自己是否完成。
建立類型為 Push 的監控。Uptime Kuma 會產生類似以下的唯一 URL:
https://status.example.com/api/push/j8Xa2Kd9Qe?status=up&msg=OK&ping=將 Heartbeat Interval 設定為工作執行的週期,再預留一些寬限時間。接著在指令碼的最後加入一行,讓它只在成功時傳送 heartbeat:
#!/usr/bin/env bash
set -euo pipefail
# ... your backup or job runs here; set -e aborts on any failure ...
curl -fsS --retry 3 "https://status.example.com/api/push/j8Xa2Kd9Qe?status=up&msg=backup+ok&ping="如果工作失敗,set -e 會在執行 curl 前中止;如果主機故障,工作也不會執行。無論是哪種情況,heartbeat 都會停止。當「週期加上重試」的時間範圍過後,Uptime Kuma 會將監控切換為 down,並發出警示。請將這個 push token 視為 secret:任何取得它的人都能偽造正常的 heartbeat。
建立公開狀態頁面
狀態頁面是面向客戶的檢視畫面,可顯示哪些服務正常運作及其近期歷程,但不會公開儀表板。前往 Status Pages then New Status Page,輸入名稱與 slug(公開路徑,例如 /status/main),將所需的監控項目拖曳到「Websites」和「APIs」等群組,加入標誌與簡短說明,然後按一下 Save。您也可以將此頁面綁定至專用網域,讓 status.example.com 直接提供該頁面。
請注意兩點:只加入您願意公開的監控項目,因為狀態頁面會透露某項服務存在,以及目前是否正常運作;儀表板仍受您的登入保護,而狀態頁面則刻意設為公開,無需驗證。
將其置於 TLS 反向代理後方,並注意 WebSocket
若要公開提供服務,請在綁定 loopback 的容器前方設定反向代理,處理 TLS 與主機名稱。最容易出錯的地方是:Uptime Kuma 的 UI 是即時 Socket.IO 應用程式,因此代理必須升級 WebSocket 連線。 若遺漏此設定,頁面雖然會載入,卻永遠無法連線;儀表板會停留在「Connecting...」,即時 heartbeat 不會更新,而瀏覽器主控台會顯示 WebSocket connection to 'wss://.../socket.io/...' failed。
安裝 nginx 與 certbot,然後撰寫將請求代理到 loopback 埠的 vhost。暫時讓它監聽 port 80,之後再讓 certbot 加入 TLS;challenge、續期計時器及其失敗模式,請參閱 使用 certbot 與 nginx 申請 Let's Encrypt 憑證。
sudo apt install -y nginx certbot python3-certbot-nginx將以下內容儲存為 /etc/nginx/sites-available/status.example.com;兩行 WebSocket 設定是關鍵:
server {
listen 80;
server_name status.example.com;
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 3600s;
}
}啟用此網站並測試設定,然後讓 certbot 改寫此區塊,使其監聽 443、加入憑證,並新增 HTTP-to-HTTPS 重新導向:
sudo ln -s /etc/nginx/sites-available/status.example.com /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d status.example.comUpgrade 與 Connection "upgrade" 這一對設定是關鍵,proxy_read_timeout 3600s 則可避免 nginx 中斷長時間維持的 socket;certbot 會將兩者複製到產生的 443 區塊中。如果你已經透過單一代理將多個容器放在後方,透過 Traefik 搭配自動 TLS 進行路由可使用容器 labels 完成相同工作,並預設轉送 WebSocket 升級要求。
不要對整個 vhost 啟用 basic authentication,因為這也會封鎖公開狀態頁面與 /api/push endpoint。保留 Uptime Kuma 內建的登入功能;若服務直接暴露在網際網路,請加入 監控重複登入失敗的 fail2ban。如果儀表板不需要公開,請移除代理,改透過 VPN 存取。
正確設定憑證到期監控
HTTP(s) monitor 也能在 TLS 憑證到期前發出警告:勾選 Certificate Expiry Notification,Uptime Kuma 就會在指定天數前發出警示。以下兩個錯誤會導致判讀結果不正確。請依主機名稱而非 IP進行監控,否則未帶 SNI 的請求會取得伺服器的預設憑證,並顯示 Hostname/IP does not match certificate's altnames。如果希望 monitor 發出到期警告,請勿勾選 Ignore TLS/SSL Error:這項設定適用於使用自簽憑證的內部主機(unable to verify the first certificate、DEPTH_ZERO_SELF_SIGNED_CERT),但會使 Uptime Kuma 完全略過憑證檢查,包括到期日檢查。
備份:只有一個目錄
由於所有資料都位於 /app/data,因此備份就是在容器停止時複製該 volume,確保 SQLite 檔案保持一致:
cd /srv/uptime-kuma
sudo docker compose stop
sudo docker run --rm \
-v uptime-kuma_kuma-data:/data \
-v /var/backups/kuma:/backup \
alpine tar czf /backup/kuma-$(date -u +%Y%m%dT%H%M%SZ).tgz -C /data .
sudo docker compose start先使用 docker volume ls | grep kuma 確認 volume 的實際名稱,因為 Compose 會在名稱前加上專案目錄。接著將 tarball 複製到主機以外的位置,因為儲存在同一台 VPS 上的備份只是副本,不是真正的備份。還原時則反向操作:停止 stack,將內容解壓縮到空的 /app/data volume,然後啟動 stack。
升級
升級就是拉取映像檔:
cd /srv/uptime-kuma
sudo docker compose pull
sudo docker compose up -d新容器會在首次啟動時執行資料庫遷移;請監看 docker compose logs -f。請在拉取前先完成上述備份,並維持在同一個 major tag:從 :1 移至 :2 是單向遷移,因此請先備份並查看版本發布說明。
失效情況與你會看到的訊息
監控指向 localhost 時誤判為「停止」。 監控因 timeout of 48000ms exceeded 或 connect ETIMEDOUT 顯示紅色,但服務仍可從筆記型電腦連線。如果監控目標與 Uptime Kuma 執行於同一台主機,可能是 CPU 或記憶體尖峰導致監控檢查無法取得資源,而不是目標服務發生問題。請將監控移至獨立的 VPS,並以公開主機名稱作為目標。
connect ECONNREFUSED 127.0.0.1:443(或任何連接埠)。該連接埠沒有服務在監聽。可能是服務已停止,也可能是你在容器內監控 localhost,此時 127.0.0.1 指的是容器,不是你的伺服器。請監控公開主機名稱,不要監控 loopback。
Invalid login: 535-5.7.8 Username and Password not accepted 出現在電子郵件測試中。SMTP 憑證錯誤,或服務提供者要求應用程式專用密碼,但你輸入了帳戶密碼。請產生應用程式密碼並貼上該密碼。
connect ETIMEDOUT 或 queryA ETIMEDOUT <host> 出現在電子郵件測試中。連接埠錯誤,或服務提供者封鎖了輸出的 SMTP 流量。請確認 465 或 587 與 Secure/STARTTLS 設定一致,並使用 nc -vz smtp.example.com 587 從主機測試。許多服務提供者會封鎖輸出的 25,部分服務提供者則會在你提出要求前封鎖 submission 連接埠。
self signed certificate 或 unable to verify the first certificate 出現在電子郵件測試中。SMTP 伺服器提供的憑證不受 Node 信任。請修正郵件伺服器的憑證,不要以繞過驗證的方式暫時掩蓋問題。
儀表板停留在「Connecting...」,主控台顯示 WebSocket connection ... failed。 反向代理未升級 WebSocket。請在 nginx 中加入 Upgrade 和 Connection "upgrade" 標頭,或使用 Traefik、Caddy 等預設會轉送這些標頭的代理。HTML 能載入,是因為那是一般的 HTTP GET;只有即時 socket 需要升級。
憑證到期監控從不發出警告,或警告內容錯誤。 可能勾選了 Ignore TLS/SSL Error,導致憑證檢查停用;也可能監控指向 IP,因缺少 SNI 而讀取錯誤的憑證,並顯示 Hostname/IP does not match certificate's altnames。請取消勾選忽略錯誤,並以主機名稱作為監控目標。
日誌中出現 SQLITE_BUSY 或 database disk image is malformed。 /app/data volume 位於未正確支援檔案鎖定的檔案系統上,通常是 NFS。請將其移至本機 Docker volume,並從備份還原。
FAQ
我應該在哪裡執行 uptime monitor?
請在與受監控主機不同的伺服器上執行,最好使用其他供應商或區域,並像使用者一樣,透過公開網際網路以主機名稱連線。如果監控程式與目標主機共用同一台伺服器,導致伺服器停止運作的中斷也會同時使監控程式失效;主機負載過高時,還可能將正常服務誤判為「down」。使用一台獨立的小型 VPS 即可避免這兩個問題。
如何在 Telegram 或電子郵件中接收警示?
在 Settings then Notifications 中新增通知管道,再將該管道套用至各個監控項目。若使用 Telegram,請透過 @BotFather 建立 bot,並從 https://api.telegram.org/bot<token>/getUpdates 讀取 chat.id;若使用電子郵件,請使用 465 進行 SSL,或使用 587 進行 STARTTLS。若供應商啟用雙因素驗證,請使用應用程式密碼。按下 Test,確認能收到訊息後再依賴此通知功能。
Uptime Kuma 能監控 cron 工作或備份指令碼嗎?
可以,這就是 Push 監控項目:Uptime Kuma 會提供 URL,您可在指令碼結尾執行 curl,如此只有在成功完成時才會送出通知。如果工作失敗或主機停止運作,監控訊號就不會送達;經過設定的間隔後,您會收到警示。這是確認排程工作確實執行的唯一可靠方式,因為外部檢查無法查看工作內部的執行狀態。
Uptime Kuma 與 Zabbix 之間,我應該使用哪一個?
Uptime Kuma 能在 10 分鐘內回答「服務是否正常、從外部是否可連線,以及是否已通知我」,幾乎不需要系統資源,並提供狀態頁面。它不會收集 CPU、記憶體和磁碟趨勢等深度指標,也不支援整個主機群組的閾值管理;如果需要這些功能,完整的 Zabbix 監控伺服器 是較為複雜且以 agent 為基礎的工具,許多人會同時使用兩者。如果您仍在考慮是否要執行監控服務,我們整理的 2026 年自架服務建議 可協助您了解監控在整體架構中的位置。