DEV Community

karthik
karthik

Posted on Originally published at freetierwatch-eax.pages.dev

Self-host Uptime Kuma: a status page in 10 minutes (with real RAM numbers)

Originally published on FreeTierWatch, where we hand-verify free tiers and actually test the self-hosted apps we write about.

Uptime Kuma is the self-hosted answer to UptimeRobot and Pingdom: a monitoring dashboard that pings your sites, APIs, and databases, and alerts you when they go down. No per-monitor pricing, no 5-minute-interval paywall — your hardware, your rules.

We deployed version 2 from scratch, measured its actual resource usage, and broke a couple of monitors on purpose to see what failure looks like. Everything below is from that run.

What you need

  • Any machine with Docker — we used a workstation with 30 GB RAM, but our measurements show 256 MB free RAM is plenty
  • 1 GB free disk (the image alone is 574 MB)
  • 5-10 minutes

Docker not installed? On Ubuntu/Debian: curl -fsSL https://get.docker.com | sh

Step 1: the Compose file

Make a directory and drop this in as compose.yaml:

services:
  uptime-kuma:
    image: louislam/uptime-kuma:2
    container_name: uptime-kuma
    volumes:
      - kuma-data:/app/data
    ports:
      - "3001:3001"
    restart: unless-stopped

volumes:
  kuma-data:
Enter fullscreen mode Exit fullscreen mode

Two deliberate choices here:

  • Named volume (kuma-data) instead of a bind mount — survives container recreation and avoids the host-permissions mess that bind mounts cause on some systems.
  • restart: unless-stopped — the container comes back after reboots without systemd units or cron hacks.

Step 2: start it

docker compose up -d
Enter fullscreen mode Exit fullscreen mode

First run pulls the image (574 MB — a minute or two on decent broadband). Then open http://localhost:3001 (or http://<machine-ip>:3001 from another device on your network).

Step 3: database choice (new in v2)

Version 2 asks which database to use before anything else:

Uptime Kuma database setup screen offering Embedded MariaDB, external MariaDB/MySQL, and SQLite

Pick SQLite for a homelab. The embedded MariaDB option exists for large installations (hundreds of monitors); for anything under ~50 monitors, SQLite is simpler, uses less RAM, and backs up as a single file. After 2 months with 3 monitors, our SQLite data volume was under 2 MB.

Then create your admin account. Use a real password manager entry — this dashboard knows every URL you care about.

Step 4: add monitors

Add New Monitor → pick a type → paste a URL. We set up three real ones:

Uptime Kuma dashboard showing three monitors up with response time history

Lessons from the two monitors we got wrong on the first try (visible as red in the history — we left them in deliberately):

  • HTTP-monitoring a private GitHub repo returns 404. The unauthenticated check sees what a logged-out user sees. Monitor something public, or use a keyword/API monitor with a token.
  • Supabase's REST endpoint returns 401 without an API key — "down" according to an HTTP monitor even though the service is fine. For databases, use a TCP Port monitor instead: ours checks the Postgres pooler on port 5432 and reports ~33 ms from India to Mumbai.

That's the general rule: HTTP monitors for pages, TCP monitors for databases and services that require auth.

What it actually costs to run (measured)

Metric Measured value
Image size 574 MB
RAM, idle (0 monitors) 143 MB
RAM, 3 active monitors (60s interval) 133–147 MB
CPU, idle 0.02%
CPU, 3 monitors ~0.7–0.9% of one core
Disk (data volume, 3 monitors) 1.4 MB
Restart time (docker restart) 1.6 s, serving again in under 10 s

Translation: Uptime Kuma runs comfortably on a Raspberry Pi, a 10-year-old laptop, or the smallest VPS money can buy. RAM is the only number that matters, and it stays well under 200 MB.

Gotchas

  • The monitor is only as available as the machine it runs on. Our test box is a workstation that isn't on 24/7 — fine for learning, useless for real alerting. See below.
  • Port 3001 conflicts: if something already listens there, change the left side of the mapping ("3002:3001").
  • No built-in HTTPS. On a LAN that's fine; exposing it to the internet needs a reverse proxy (Caddy/Traefik/nginx) in front — or better, don't expose it and use Tailscale.
  • Updates: docker compose pull && docker compose up -d. The named volume keeps your data.

Backups

Everything lives in one volume. Snapshot it with:

docker run --rm -v kuma-data:/data -v "$PWD":/backup alpine \
  tar czf /backup/kuma-backup-$(date +%F).tar.gz -C /data .
Enter fullscreen mode Exit fullscreen mode

Cron that weekly and copy it somewhere that isn't the same disk.

When NOT to self-host this

  • Your monitoring box isn't always on. A monitor that's offline when your site goes down is theatre. If you don't have an always-on machine, run Uptime Kuma on a free or cheap cloud box — Oracle's Always Free tier fits it with room to spare, or any ~$4-6/mo VPS.
  • You're monitoring the same machine the monitor runs on. It can't tell you it's down.
  • You need SMS alerting and SLA reports for a client contract — paid services earn their fee there.

What we actually ran this on

  • Machine: Intel Core Ultra 7 255H (16 cores), 30 GB RAM, NVMe — massively overkill; see measurements above for what it actually needs
  • OS: Ubuntu 24.04.5 LTS, x86_64
  • Docker: 29.8.1, Compose v5.1.3
  • Uptime Kuma: louislam/uptime-kuma:2 (v2, SQLite backend)
  • Date: 2026-10-06

Top comments (0)