Self-Host Uptime Kuma in One Form — Image, Volume, HTTPS

·4 min read·Updated
uptime-kumaself-hostedmonitoringdockervolumeshow-to

To self-host Uptime Kuma you need three things: the public louislam/uptime-kuma image, a persistent volume at /app/data, and an HTTPS URL to reach the dashboard on. On JustRunMy.App all three go into a single Existing Image form — image reference, volume path, and port, filled in before you click Create — so the app comes up already persistent and already on HTTPS. Uptime Kuma is a good fit for a small container: it idles at roughly 50–200 MB of RAM and spends most of its life asleep between checks.

What you're deploying

Uptime Kuma is a self-hosted monitoring tool — HTTP, TCP, ping, and certificate-expiry checks, with a dashboard, notifications, and public status pages. Per its install docs the container listens on port 3001 and keeps everything in a SQLite database under /app/data (Uptime Kuma wiki).

That's the whole configuration surface: one port, one directory.

Fill in one form

Open Existing Image on the Advanced tab of Create new application, then expand Advanced — environment variables, persistent volumes, and container ports are all set here, before the app exists.

The Existing Docker Image create form in the JustRunMy.App panel with the Advanced section expanded, showing environment variables, persistent volumes, and container ports

Three fields matter:

  1. Image and label — louislam/uptime-kuma:2.
  2. Persistent volumes → Add folder → /app/data.
  3. Container ports → Add port → container port 3001, protocol HTTPS.

Leave the run command empty; the image's own entrypoint is correct. Click Create and you get a running dashboard on a platform subdomain with a certificate issued automatically — HTTPS is included free, so there's no reverse proxy to configure and no cert to renew.

Setting the volume in this form rather than afterwards matters. A volume added to an existing app is applied on the next container start, so it comes up empty — and anything already written to that path is in the layer that just got discarded. Doing it at creation means the database is on the volume from the very first write.

The one mistake that corrupts the database

If you take nothing else from this: /app/data must be a real volume on local disk, not network storage.

Uptime Kuma's own install docs are explicit that the filesystem must support POSIX file locks, and warn against NFS specifically, because SQLite relies on that locking to avoid corruption. This bites people who reflexively point container data at an NFS share or an object-storage gateway.

Volumes here are ordinary Docker volumes on the node's local disk, which is exactly what SQLite wants. It's the same reason a bot's SQLite database belongs on a volume — same storage, same constraint, same failure mode if you get it wrong.

Sizing it

Uptime Kuma is light, but it isn't free of cost: memory grows with the number of monitors, since each one is a scheduled check with its own history.

  • A handful of monitors sits comfortably in the low end of that 50–200 MB range.
  • 0.25 GB is enough for a small set of checks. Monitoring is only worth anything if it is always up, so keep credit on the balance.
  • Disk is a non-issue. The SQLite database plus heartbeat history is small; trim retention in Kuma's settings if it ever isn't.

Check current usage on the Limits page, and raise RAM before adding a large batch of monitors rather than after.

Don't monitor yourself with yourself

The obvious caveat, stated plainly because it's easy to miss when you're pleased with the setup: a monitor hosted on the same infrastructure it monitors can't tell you when that infrastructure is down. If the node goes away, so does the thing that would have alerted you.

That's fine for what most people use it for — watching other services, your own APIs, third-party dependencies, certificate expiry. It's not fine as the only alerting for the platform it runs on. If you need that, run the monitor somewhere else, or pair it with an external check.

Uptime Kuma supports push monitors for exactly this: a heartbeat URL your app calls on a schedule, so a missed call raises the alert. Useful in the other direction too — a bot with no HTTP endpoint can ping a push monitor from its main loop, which gives you liveness checking on a process nothing can poll.

FAQ

What port does Uptime Kuma use?

3001 inside the container. Bind it as HTTPS and you get a public URL with a certificate; you don't need to expose 3001 publicly yourself.

Where does Uptime Kuma store its data?

In a SQLite database under /app/data. Mount a volume at that path or you'll lose every monitor the next time the container is recreated.

Can I use NFS or network storage for /app/data?

No. Uptime Kuma requires POSIX file locks and its docs warn that NFS can corrupt the SQLite database. Use a local-disk volume.

How much RAM does Uptime Kuma need?

Roughly 50–200 MB depending on how many monitors you run. Start small and raise the quota as you add checks.

Do I need a domain or an SSL certificate?

No. An HTTPS port binding gives the app a subdomain with a certificate issued and renewed automatically.

Can it monitor a bot or worker with no HTTP endpoint?

Yes — use a push monitor. Your process calls a heartbeat URL on a schedule, and a missed heartbeat triggers the alert.

Wrapping up

Self-hosting a tool is usually three decisions: which image, what has to persist, and how you reach it. Uptime Kuma makes all three obvious — one image, one directory, one port — which is why it's a good first thing to run on a container platform. Get the volume right at creation time, keep it on local disk, and give it enough memory for the monitors you actually plan to add.