other Β· Detailed guide Β· verified 2026-09-01

uptime-kuma:Detailed Guide

Self-hosted uptime monitoring with HTTP/TCP/Ping heartbeats, status pages and alerts; Docker one-command setup.

uptime-kuma Detailed Guide

Version 2.5.3~2.5.3 | Category observability | Security (reviewed) | Sources: official project docs (English README/docs) + local measurements (2026-09-01)
Companion: site docs (manifest + guide + evidence) | Quick version: site docs

1. Scenario: when to use it

You run a service (blog, API, home server, internal system) and everything is fine β€” until a user says "it's down" and you had no idea. You want something that probes your services every 30 seconds and tells you immediately when one is down, plus a public status page so users can check themselves. uptime-kuma does exactly that: self-hosted, free open source (MIT), Chinese UI, one Docker command.

Use it when:

  • You run multiple machines/services and want one uptime panel;
  • You want alert notifications (Telegram/Webhook/email etc.);
  • You want a public status page (users check themselves instead of asking you);
  • You want to notice services getting slower (heartbeats include ping latency).

Don't use it when: you need internal application telemetry (logs/traces/metrics) β€” that is logfire's job; you just need a one-off curl β€” no tool needed.

Division of labor with logfire: logfire = application telemetry (works with OpenAI SDK etc.); uptime-kuma = liveness probing. Complementary, not overlapping (matrix: possible-compatible).

2. Capability list

CapabilityWhat it does
Multiple probe typesHTTP(s) / TCP / Ping / DNS etc. (adjustable interval)
Heartbeat recordsOne record per probe (status: 1=up / 0=down + ping), the source of truth for monitoring
Alert notificationsTelegram / Webhook / email etc. (Webhook needs no account)
Public status page/status/<slug> read-only page, pick monitors to publish
Data persistenceSQLite (kuma.db) in volume /app/data
Self-hostedData stays on your machine; MIT free open source

3. Quick install

One command to start the container (measured China path: ghcr.nju.edu.cn prefix + volume):

# Source: Trove detailed guide Β· verified 2026-09-01
docker run -d --name uptime-kuma --restart=always -p 3001:3001 -v uptime-kuma:/app/data ghcr.nju.edu.cn/louislam/uptime-kuma:2.5.3

Expected output: a container ID; docker ps shows uptime-kuma Up (healthy after ~12 seconds, measured 2026-09-01)

Open http://localhost:3001: first visit runs setup (pick SQLite β†’ create admin β†’ login). Then "Add Monitor" on the left: type HTTP(s), URL target, interval 30s, save β€” first heartbeat within 30 seconds.

When monitoring host services (open-webui/ollama/your own API), use http://172.17.0.1:<port>, not 127.0.0.1 (measured pitfall: inside the container 127.0.0.1 is the container itself β€” all DOWN; 172.17.0.1 is the docker bridge gateway to the host).

Confirm:

  • docker ps shows healthy;
  • http://localhost:3001 shows the setup page;
  • after adding the first monitor, an UP heartbeat (green) appears within 30 seconds.

Install variants (deep dive)

PathCommandStatus
Docker (recommended, measured)ghcr.nju.edu.cn prefix + volumeβœ… full-chain measured 2026-09-01 (2.48GB image)
Image pull failsswitch to another ghcr mirror (ghcr.dockerproxy.com etc.) or wait for a proxy windownot tested (ghcr.nju worked)
Bare metal / other platformsofficial docs cover bare-metal and multi-platformnot tested (Docker form in this env)

4. Why it works this way (mechanism & shared surfaces) (deep dive)

uptime-kuma is a Node.js app (GitHub louislam/uptime-kuma, MIT, 65k+ stars): a daemon sends probes (HTTP GET / TCP connect / Ping / DNS lookup etc.) to targets at the configured interval, writes each result (up/down, response time) to a database, renders the web UI, and triggers notifications.

Two key mechanisms:

  • Heartbeat: each probe produces a record (status: 1=up / 0=down + ping), the single source of truth for monitoring; status pages and alerts are all derived from heartbeats.
  • Container network isolation: the official recommendation is Docker (data in /app/data). 127.0.0.1 inside the container is the container itself β€” to monitor host services use 172.17.0.1 (docker bridge gateway, Linux/WSL) or host.docker.internal (Docker Desktop). Measured 2026-09-01: 127.0.0.1 targets all DOWN; switching to 172.17.0.1 β†’ UP immediately.

Where it writes: Docker volume (data dir /app/data, SQLite kuma.db). Removing the container keeps data; removing the volume loses it.

5. Common operations

Step 1: setup + create admin

Explanation: first visit runs the setup wizard (database β†’ admin β†’ login).

# Source: Trove detailed guide Β· verified 2026-09-01
docker ps --filter name=uptime-kuma

Expected output: container Up (healthy, ~12s, measured 2026-09-01)

Browser http://localhost:3001 β†’ SQLite β†’ create admin β†’ login to dashboard.

If stuck:

  • container won't start β†’ docker logs uptime-kuma tail; port 3001 busy β†’ -p 3002:3001;
  • setup repeats β†’ volume not mounted (data not persisted); confirm -v uptime-kuma:/app/data.

Step 2: add your first monitor

Explanation: a monitor is a probe target; HTTP is the most common type.

# Source: Trove detailed guide Β· verified 2026-09-01
docker exec uptime-kuma wget -qO- http://172.17.0.1:3000/api/health

Expected output: target service responds (verify reachability from inside the uptime-kuma container first; measured 2026-09-01: open-webui /health UP via 172.17.0.1)

UI: left "Monitors" β†’ "Add Monitor" β†’ type HTTP(s) β†’ URL http://172.17.0.1:<port> β†’ interval 30s β†’ status codes 200-299 β†’ save.

CLI equivalent (socket.io "add" event, measured):

# Source: Trove detailed guide Β· verified 2026-09-01
# socket "add"({name:"my-api", type:"http", url:"http://172.17.0.1:8080/health",
#   interval:30, maxretries:1, accepted_statuscodes:["200-299"], conditions:[]})

Expected output: {"ok":true,"monitorID":1}; the monitor shows UP (green) after ~30 seconds

If stuck:

  • always DOWN β†’ verify the target is reachable from inside the container (wget or a temporary curl container); 127.0.0.1 is always DOWN (see "Why it works this way");
  • save errors β†’ v2.5's add event requires accepted_statuscodes/conditions etc. (missing conditions β†’ NOT NULL error, measured); UI does not hit this;
  • status stuck PENDING β†’ wait one interval (30s) for the first heartbeat.

Step 3: verify heartbeats and DOWN detection

Explanation: heartbeats are the truth; verify both UP and DOWN before calling it done.

# Source: Trove detailed guide Β· verified 2026-09-01
# heartbeat query (socket.io "getMonitorBeats" event)
#   socket "getMonitorBeats"(monitorID, 24)  -> {"ok":true,"data":[{status:1,ping:16,time:"..."}]}

Expected output: latest record has status:1 with a ping value (measured UP=status:1, ping 16/104ms)

# Source: Trove detailed guide Β· verified 2026-09-01
# verify DOWN on purpose: stop the monitored service, monitor turns red in ~30s, restart to recover
docker stop open-webui && sleep 35 && docker start open-webui

Expected output: monitor goes DOWN (red) after stop, recovers UP after restart (measured 2026-09-01: down-probe judged DOWN correctly)

If stuck:

  • no DOWN after stopping the service β†’ check the interval; heartbeats are scheduled probes with latency;
  • data survives restart β†’ volume persistence OK (docker restart uptime-kuma keeps history, measured).

Step 4 (optional): notifications + public status page

Explanation: notification channels (Telegram/Webhook/email); Webhook needs no account and can be self-tested.

# Source: Trove detailed guide Β· verified 2026-09-01
# self-test a Webhook: curl your own webhook address first (example; configure your real one)
curl -s -X POST https://your-webhook.example/hook -H "Content-Type: application/json" -d '{"msg":"test"}'

Expected output: webhook service responds normally (200 or the service's defined success)

  • Notifications: left "Notifications" β†’ "Add Notification" β†’ pick channel β†’ fill address/credentials β†’ attach to monitors. Not tested (zero-account red line; Webhook needs no account, configure per official docs).
  • Status page: left "Status Page" β†’ create β†’ check monitors β†’ get /status/<slug> public URL. Not tested (requires UI config).

If stuck:

  • notification test fails β†’ make sure it is configured under "Notifications", not inline on the monitor; self-test the Webhook with curl first;
  • status page blank β†’ at least one monitor must be checked and saved; public URL is /status/<slug>, not the root path.

6. Conflict pairs (summary)

Same source as the tool-page matrix; full pairs, states and evidence on the conflict matrix. Known relations:

  • open-webui Γ— uptime-kuma = compatible (verified): measured 2026-09-01 (uptime-kuma probes open-webui /health via 172.17.0.1 UP, ping 16ms) β€” prober and probed, naturally complementary;
  • ollama Γ— uptime-kuma = compatible (verified): measured 2026-09-01 (probes ollama /api/version UP, ping 104ms);
  • logfire Γ— uptime-kuma: complementary (app telemetry vs liveness probing), non-overlapping write surfaces, static: can coexist;
  • Others: static possible-compatible (container volume write surface, no overlap).

7. Troubleshooting quick reference

  • Symptom: all monitors DOWN β†’ check whether URLs use 127.0.0.1 (container self-reference); switch to 172.17.0.1 (docker bridge gateway)
  • Symptom: container not healthy after 12s β†’ docker logs uptime-kuma tail; port conflict β†’ change mapping
  • Symptom: add event save error β†’ v2.5 needs accepted_statuscodes/conditions fields (missing conditions β†’ NOT NULL, measured); UI has no such issue
  • Symptom: status stuck PENDING β†’ wait one interval (30s) for the first heartbeat
  • Symptom: data lost after restart β†’ volume not mounted; confirm -v uptime-kuma:/app/data
Full four-section entries (symptom→cause→fix→evidence): site docs (if recorded)

8. Uninstall & residue check

# Source: Trove detailed guide Β· verified 2026-09-01
docker stop uptime-kuma && docker rm uptime-kuma
docker volume rm uptime-kuma

Expected output: container stopped/removed; after volume removal docker volume ls no longer shows uptime-kuma

Note: removing the volume deletes all monitors/heartbeat history/status-page config. To keep data, remove only the container and keep the volume.

9. FAQ

  • Q: Why are all host-service monitors DOWN? A: inside the container, 127.0.0.1 is the container itself. Monitor the host with http://172.17.0.1:<port> (docker bridge gateway, measured) or host.docker.internal (Docker Desktop).
  • Q: Image won't pull? A: ghcr.nju.edu.cn measured working (2.48GB full pull); switch to another ghcr mirror or wait for a proxy window.
  • Q: Where is the data, and does deleting the container lose it? A: SQLite at volume /app/data/kuma.db. With -v uptime-kuma:/app/data, deleting the container keeps data; deleting the volume loses it.
  • Q: Does it overlap with logfire? A: No. logfire = internal app telemetry (logs/traces/metrics); uptime-kuma = service liveness + alerts + status page. Can coexist.
  • Q: Do notifications need accounts? A: Telegram/email need credentials (not tested, zero-account); Webhook needs no account, configurable.
  • Q: Where do I report issues? A: install/uninstall issues go through this entry's feedback; project issues go to the author repo.
  • Version: 2.5.3 (manifest locked; image measured 2026-09-01).
  • Environment: Docker 29.1.3 (WSL2 Ubuntu measured); RAM β‰₯1GB (lightweight, 12s healthy measured).
  • Network: ghcr.nju.edu.cn measured working (2.48GB).
  • Write surface: Docker volume uptime-kuma (/app/data, SQLite kuma.db).
  • Port: 3001 (host mapping example; 3001 inside the container).

10. Sources

  • Sources: official project docs (English README/docs) + local measurements (2026-09-01)
  • Entry signature: louislam/uptime-kuma (MIT, kept as 2.5.3)
  • Measured: `site docs (2026-09-01: ghcr.nju 2.48GB pull β†’ container healthy in 12s β†’ POST /setup-database sqlite β†’ socket setup admin + login (token) β†’ add 5 HTTP monitors β†’ heartbeat verify: open-webui UP ping 16ms / ollama UP ping 104ms / bad target correctly DOWN; 127.0.0.1 self-reference pitfall reproduced end to end)
  • Not tested: notification channels (Telegram/email need accounts, zero-account red line); public status page (requires UI config); bare-metal deployment.

Merged sources

This page merges multiple source articles β€” deduplicated by content hash, measured, and rewritten by AI. Sources are not scattered; they all live on this single page.

No merged sources yet: this page distills local verification and community rewrites; provenance details live on the linked solution page.

← Back to uptime-kuma solution page | other domain