Uptime Kuma Docker 安裝教學:自建網站監控系統
使用 Docker 部署 Uptime Kuma 進行網站、Port 與 DNS 監控,並透過 Telegram 或 Email 發送警報。本文特別強調監控主機應與目標服務分開部署在不同 VPS,以避免因單一主機故障導致監控失效,並提供 Docker Compose 完整設定範例。
建立目標
建立一個輕量級容器,從外部監控您的其他伺服器與網站。當服務停止回應時,系統會透過 email、Telegram、Discord 或 webhook 立即通知您。Uptime Kuma 是單一 Node 執行程序,並使用 SQLite 檔案作為後端,因此僅需 256-512 MB 的 RAM 即可穩定運行。它提供即時儀表板、歷史圖表以及公開狀態頁面。安裝僅需十行 Compose 檔案;關鍵在於「執行位置」以及「警報是否經過測試」,因為若未驗證監控功能是否能成功送達,該監控便毫無意義:它會讓您在完全沒有監控的情況下,產生安全假象。
將監控程式部署在故障範圍之外
此決策至關重要,因此須優先考慮。切勿將 Uptime Kuma 與被監控的服務部署在同一台主機上。 若監控程式與目標伺服器位於同一台機器,當目標發生故障(例如當機或記憶體耗盡)時,監控程式也會隨之失效,導致無法發出警報:監控程式停止運作所產生的靜默,在結果上等同於「一切正常」。此外,即便主機仍在運行,也存在更隱蔽的陷阱:若監控程式指向 localhost,它會與工作負載共用 CPU,當負載飆升時,監控檢查會逾時並將目標狀態誤判為 down,這會產生錯誤警報,但實際上使用者仍能正常使用服務。
因此,請將 Uptime Kuma 部署在與被監控目標不同的 VPS 上,理想情況下應選擇不同的供應商或區域,並透過使用者存取服務的方式(即透過公網與 hostname)來進行監控。使用廉價的執行個體即可,一台小型監控 VPS 就能監控所有伺服器。若要監控 Kuma 本身是否失效,請在其他地方透過 cron 設定 push heartbeat。
前置作業與規格建議
- 一台全新的 Ubuntu 24.04 VPS,且已安裝 Docker Engine 與 Compose v2 插件。請務必從 Docker 官方 apt 儲存庫安裝,而非使用版本較舊的
docker.io發行版套件。 - 256 MB RAM 僅能執行少量監控項目;若要執行數十個監控項目並包含反向代理,建議配置 512 MB 至 1 GB RAM。在檢查間隔期間,CPU 負載應接近閒置狀態。
- 一個網域與一筆 DNS
A紀錄(例如指向 VPS 的status.example.com)。僅在需要 TLS 與公開狀態頁面時才需要此配置。私有實例可跳過 DNS,改用 VPN 或 SSH 隧道。 - 連向警報接收端的出站網路:例如傳送至郵件供應商的 SMTP,或傳送至 Telegram 與 Discord 的 HTTPS。
The Compose file
請將此內容放入 /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 並停止輸出。該檔案中有三處設計是刻意為之。
使用 127.0.0.1:3001:3001,而非 3001:3001。 Docker 會使用 DNAT 規則發布埠號,且其評估順序在 ufw 之前,因此若僅使用 3001:3001,無論防火牆設定為何,都會將儀表板暴露於公網。綁定至 loopback 可保持私密,僅公開 reverse proxy;私有實例可以跳過 proxy,改透過 自建的 WireGuard VPN 存取 3001。
在 /app/data 使用具名 volume。 Uptime Kuma 儲存的所有資料(包括 SQLite 資料庫、監控項目、通知設定與狀態頁面標誌)都存放在此。若遺失此資料,管理介面將會重置;這是唯一必須備份的項目。
映像檔版本固定在主要版本標籤 :2。 這是目前的穩定版本;複製前請至 Docker Hub 確認最新的主要版本。切勿追蹤如 latest 之類的移動標籤(moving tag),該專案已不建議使用。此映像檔的主要版本跳躍會觸發單向資料庫遷移,應由使用者刻意執行,而非在例行性的 pull 過程中意外觸發。
注意事項:/app/data 必須位於支援 POSIX 檔案鎖(file locks)的檔案系統上。使用本地 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。首頁為管理員使用者名稱與密碼的設定表單;系統不提供預設登入資訊。請設定一個強密碼:此儀表板可存取所有監控對象的內部位址與 token。若日後遺忘密碼,請從主機端進行重設,而非透過瀏覽器:
sudo docker compose exec uptime-kuma npm run reset-password首先新增通知管道並進行測試
請在新增監控項目前先設定警報,以便在建立每個項目時即可關聯通知管道。前往 Settings > Notifications > Setup Notification,並使用各管道的 Test 按鈕確認訊息是否成功送達。未經測試的通知是導致設定靜默失敗(silently fails)的第二大原因。
Email (SMTP)。 填寫 host、port、encryption、username、password、From 與 To。兩種可行的組合為:將 "Secure" 設為 TLS/SSL 的 465,或使用 STARTTLS 的 587。若使用 Gmail 或大多數開啟兩步驟驗證的供應商,必須產生 app password;使用一般帳號密碼會導致 Error: Invalid login: 535-5.7.8 Username and Password not accepted。
Telegram。 傳送訊息給 @BotFather,傳送 /newbot,然後複製 bot token。若要取得 chat ID,請先傳送一次訊息給新機器人,開啟 https://api.telegram.org/bot<token>/getUpdates,並從 JSON 中讀取 chat.id。若未曾主動傳送訊息給機器人,其 getUpdates 將為空,導致無法傳送訊息。
Discord。 在頻道中,開啟 Edit Channel > Integrations > Webhooks > New Webhook,複製 URL,並將其貼上作為 Discord 通知。
Generic webhook。 若需使用其他服務(如 Slack incoming webhook、自定義 endpoint 或家用自動化 hook),請使用 Webhook 類型,將 JSON payload POST 到您提供的 URL。內建的 Apprise 整合功能可支援清單中其餘 90 多種服務。
新增監控項目,一次僅限一種類型
點擊 Add New Monitor,選擇類型,並設定 Friendly Name、Check Interval(建議設為 60 seconds)、Retries(判定為 "down" 前的連續失敗次數;建議設為 2 或 3,避免單次封包遺失即發出警報),以及要觸發的通知。您將使用的類型如下:
- HTTP(s). 完整的 URL。狀態碼為 Accepted 即代表 "up"(預設為 200-299;若
301或401為正常值,請於 Accepted Status Codes 調整範圍)。適用於網站與 API 的主要工具。 - HTTP(s) - Keyword. 執行相同的請求,但除了狀態碼外,還須在 Body 中偵測到特定字串(若未勾選 Invert)才判定為 "up"。這能偵測到網站雖回傳
200 OK,但內容卻顯示 "Error establishing a database connection" 的情況,而一般的 HTTP 檢查會誤判此狀態為正常。 - 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. 由內而外的監控方式,詳見下節。
使用 Push (Heartbeat) 監控 cron job
上述所有監控方式都是從外部存取您的服務。Push 監控則相反:Uptime Kuma 會保持等待,並由「您的任務」主動呼叫以回報「我已執行」。這是監控備份或 cron 任務最準確的方法:HTTP 檢查只能確認 URL 有回應,但只有任務本身知道是否已成功完成。
建立一個類型為 Push 的監控項目。Uptime Kuma 會產生一個唯一的 URL,例如:
https://status.example.com/api/push/j8Xa2Kd9Qe?status=up&msg=OK&ping=將 Heartbeat Interval 設定為任務執行的頻率,並額外增加一點緩衝時間。接著在指令碼的「末端」加入一行,確保僅在成功時才發送請求:
#!/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 視為機密:任何持有該 token 的人都能偽造健康的 Heartbeat。
建立公開狀態頁面
狀態頁面是面向客戶的視圖:顯示哪些服務正常運作及其近期歷史紀錄,且不會暴露您的控制台。前往 Status Pages then New Status Page,輸入名稱與 slug(公開路徑,例如 /status/main),將您要監控的 monitors 拖曳至「Websites」或「APIs」等群組中,新增 logo 與簡短描述,然後點擊 Save。您也可以將頁面綁定至獨立網域,讓 status.example.com 直接提供服務。
兩點注意事項:請僅新增您願意公開的 monitors,因為狀態頁面會揭露服務的存在及其運作狀態;此外,控制台受登入保護,而狀態頁面則刻意設計為公開,無需進行身份驗證。
使用反向代理與 TLS,並注意 WebSockets
若要建立公開實例,請在綁定 loopback 的 container 前方部署反向代理,以提供 TLS 與主機名稱。最常出錯的細節:Uptime Kuma 的 UI 是 Socket.IO 即時應用程式,因此代理伺服器必須支援 WebSocket 連線升級 (upgrade)。若未設定此項,頁面雖可載入但無法連線;儀表板會卡在 "Connecting...",即時狀態不會更新,且瀏覽器主控台會顯示 WebSocket connection to 'wss://.../socket.io/...' failed。
安裝 nginx 與 certbot,然後撰寫將請求代理至 loopback port 的 vhost。目前先設定在 port 80,稍後由 certbot 加入 TLS;關於挑戰、續期計時器及其錯誤模式,請參閱 issuing Let's Encrypt certificates with certbot and nginx。
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 重寫該 block 以監聽 443 port,並加入憑證與 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 block 中。若您已在單一代理伺服器後執行多個 container,使用 routing them through Traefik with automatic TLS 透過 container labels 達成相同效果,且預設會轉發 WebSocket 升級請求。
請勿對整個 vhost 使用 basic-auth,因為這會導致公開狀態頁面與 /api/push endpoint 無法存取。請保留 Uptime Kuma 內建的登入機制;若服務暴露於網際網路,請加入 fail2ban watching for repeated failed logins;若儀表板不需要公開,請移除代理並透過 VPN 存取。
正確的憑證過期監控
HTTP(s) 監控器可以在 TLS 憑證過期前發出警告:勾選 Certificate Expiry Notification,Uptime Kuma 會在設定的天數前發出警示。若發生以下兩項錯誤,監控結果將不正確。首先,請使用 hostname 而非 IP 進行監控,否則若請求不含 SNI,系統會取得伺服器的預設憑證,導致出現 Hostname/IP does not match certificate's altnames。其次,若需要憑證過期警示,請勿在監控設定中勾選 Ignore TLS/SSL Error:該選項適用於自簽章內部主機 (unable to verify the first certificate, DEPTH_ZERO_SELF_SIGNED_CERT),但啟用後會導致 Uptime Kuma 完全停止檢查憑證(包含過期檢查)。
Backups: it is one directory
由於所有資料都儲存在 /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,然後啟動。
Upgrades
升級作業包含拉取映像檔:
cd /srv/uptime-kuma
sudo docker compose pull
sudo docker compose up -d新容器會在首次啟動時執行任何資料庫遷移;請密切觀察 docker compose logs -f。在拉取映像檔 之前,請先完成上述備份,並保持在相同的 Major Tag 範圍內:從 :1 遷移至 :2 為單向遷移,因此請先進行備份並確認版本說明。
Failure modes, with the strings you will see
監控 localhost 時出現錯誤的 "down" 狀態。 監控介面顯示 timeout of 48000ms exceeded 或 connect ETIMEDOUT 錯誤,但服務在你的筆電上仍可正常回應。若監控目標與 Uptime Kuma 位於同一台主機,則是由 CPU 或記憶體瞬間飆升導致檢查失敗,而非目標服務故障。請將監控移至獨立的 VPS 並監控其公網主機名稱。
connect ECONNREFUSED 127.0.0.1:443 (或任何連接埠)。該連接埠無服務在監聽:可能是服務已停止,或是你在容器內部監控 localhost,此時 127.0.0.1 指的是 container 而非你的伺服器。請監控公網主機名稱,而非 loopback。
電子郵件測試出現 Invalid login: 535-5.7.8 Username and Password not accepted。 SMTP 憑證錯誤,或是供應商要求使用應用程式專用密碼 (app-specific password),而你卻使用了帳戶密碼。請產生應用程式專用密碼並貼上。
電子郵件測試出現 connect ETIMEDOUT 或 queryA ETIMEDOUT <host>。 連接埠錯誤,或是供應商封鎖了外發 SMTP。請確認 465 或 587 與 Secure/STARTTLS 設定相符,並使用 nc -vz smtp.example.com 587 從主機端進行測試。許多供應商會封鎖外發 25,部分供應商則會在收到申請前封鎖提交連接埠 (submission ports)。
電子郵件測試出現 self signed certificate 或 unable to verify the first certificate。 你的 SMTP 伺服器提供的憑證不被 Node 信任;請修復郵件伺服器的憑證,而非嘗試規避錯誤。
儀表板卡在 "Connecting...",主控台顯示 WebSocket connection ... failed。 反向代理 (reverse proxy) 未進行 WebSocket 升級 (upgrade)。請在 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 磁碟區位於不支援正確檔案鎖定 (file locking) 的檔案系統(通常是 NFS);請將其移至本地 Docker volume 並從備份還原。
FAQ
我應該在哪裡執行 uptime monitor?
請將 monitor 部署在與被監控目標不同的伺服器上,理想情況是使用不同的供應商或區域。請透過公網使用 hostname 進行連線,模擬使用者行為。若 monitor 與目標主機位於同一台機器,當伺服器故障時,monitor 也會隨之失效;此外,主機負載過高會導致 monitor 誤報服務異常。使用一台獨立的小型 VPS 可避免上述問題。
如何透過 Telegram 或 email 接收通知?
請至 Settings 中的 Notifications 新增頻道,並將其關聯至各個 monitor。若使用 Telegram,請透過 @BotFather 建立 bot,並從 https://api.telegram.org/bot<token>/getUpdates 取得 chat.id;若使用 email,請針對 SSL 使用 465,或針對 STARTTLS 使用 587(若供應商啟用雙重驗證,請使用應用程式專用密碼)。請按下 Test 並確認訊息送達,確認無誤後再正式啟用。
Uptime Kuma 可以監控 cron job 或備份腳本嗎?
可以,請使用 Push monitor:Uptime Kuma 會提供一個 URL,您只需在腳本結束時執行 curl,即可確保僅在執行成功時觸發。若任務失敗或主機斷線,則無法收到 heartbeat,系統會在間隔時間過後發出警報。由於外部檢查無法進入腳本內部,這是確認排程任務是否確實執行的唯一可靠方式。
Uptime Kuma 與 Zabbix 該選擇哪一個?
Uptime Kuma 僅需十分鐘即可完成設定,且幾乎不佔用資源,能回答「從外部看服務是否正常運作」以及「是否已發出通知」並提供狀態頁面。它無法收集 CPU、記憶體與磁碟趨勢等深度指標,亦無法進行全域閾值管理;若有此需求,完整的 Zabbix 監控伺服器 是更強大且基於 agent 的工具,許多使用者會同時運行兩者。若您仍在猶豫,請參考 我們在 2026 年的自架服務總結 以了解監控系統的定位。