Emergency server help: get in touch

Uptime Kuma 2: Install with Docker and Upgrade Safely from 1.23 (Tested Upgrade)

We installed Uptime Kuma 1.23.17 with three monitors, upgraded the same data to 2.5.6 and checked that monitors and history survived. This guide covers a safe Docker install, the backup that works (and the one that does not), the slim image, and the 2.x changes that trip people up.

Published 7 min read

Short answer: run Uptime Kuma 2 with docker run -d --name uptime-kuma --restart=unless-stopped -p 127.0.0.1:3001:3001 -v uptime-kuma:/app/data louislam/uptime-kuma:2 and put a reverse proxy with HTTPS in front of it. To upgrade from 1.23, stop the container first, back up the whole data volume, then start the :2 image on the same volume and let the migration finish without interrupting it. In our test, all monitors and their history came through.

Applies to Uptime Kuma 1.23.17 (Node 18) upgraded to 2.5.6 (Node 22) with Docker 29.8 on AlmaLinux 9.8; images louislam/uptime-kuma:1, :2 and :2-slim; lab test 11 Oct 2026

We tested this on 11 October 2026 on our lab2 server (AlmaLinux 9.8, Docker 29.8). We installed Uptime Kuma 1.23.17, added three monitors (HTTP, keyword and TCP port), let them collect data, and upgraded to the current :2 tag, which was version 2.5.6. Uptime Kuma 2.0 itself was released in October 2025.

Where to run it

Run your uptime monitor somewhere other than the servers it watches. If it sits on the web server and that server goes down, nobody gets the alert. A small VPS with a different provider, or a home server, is fine: in our test the running 2.x container used about 110 to 125 MB of RAM with three monitors.

Install Uptime Kuma 2 with Docker

docker volume create uptime-kuma
docker run -d --name uptime-kuma --restart=unless-stopped \
  -p 127.0.0.1:3001:3001 \
  -v uptime-kuma:/app/data \
  louislam/uptime-kuma:2
  • 127.0.0.1:3001 keeps the dashboard off the internet until a reverse proxy with HTTPS is in front of it. Port 3001 was already taken on our lab, so check with ss -ltnp | grep 3001 first.
  • On first start, a fresh 2.x install redirects to /setup-database. There you choose SQLite, the embedded MariaDB (full image only) or an external MariaDB/MySQL. SQLite is fine for a few hundred monitors.
  • Then create the admin account and add monitors in the web UI.

Full image or slim image?

TagSize on our labIncludesChoose it when
louislam/uptime-kuma:22.49 GBChromium (for “real browser” monitors) and an embedded MariaDBYou want browser-based checks or the built-in MariaDB
louislam/uptime-kuma:2-slim850 MBNeither; the setup page offered no embedded MariaDBNormal HTTP, keyword, ping, port and DNS checks with SQLite or an external database
louislam/uptime-kuma:1724 MBVersion 1.23.xOnly to stay on 1.x

Upgrade from 1.23 to 2: what we did

1. Stop, then back up the whole volume

Uptime Kuma keeps its SQLite database in WAL mode: recent data sits in kuma.db-wal next to kuma.db. When we copied kuma.db alone from the running 1.23 container, the copy showed no heartbeats at all. The backup is only complete when the container is stopped:

docker stop uptime-kuma
docker run --rm -v uptime-kuma:/data -v "$PWD":/backup alpine:3.20 \
  tar czf /backup/uptime-kuma-before-v2.tgz -C /data .

We unpacked our backup and checked it: three monitors with three heartbeats each, as expected. The JSON backup and restore in Settings is not a substitute. It was deprecated in 1.x and removed in 2.0, so copying the data directory is the backup.

2. Start the 2.x image on the same volume

docker rm uptime-kuma
docker pull louislam/uptime-kuma:2
docker run -d --name uptime-kuma --restart=unless-stopped \
  -p 127.0.0.1:3001:3001 -v uptime-kuma:/app/data louislam/uptime-kuma:2
docker logs -f uptime-kuma

The log from our upgrade, shortened:

INFO: Uptime Kuma Version: 2.5.6
INFO: db-config.json is not found or invalid ...
INFO: kuma.db is found, generate db-config.json
INFO: Database Type: sqlite
INFO: Migrating Aggregate Table
INFO: [DON'T STOP] Migrating monitor 1s' (1 of 3 total) data ...
INFO: Aggregate Table Migration Completed

The aggregate table migration converts the old heartbeat history into the new per-minute, per-hour and per-day statistics tables (stat_minutely, stat_hourly, stat_daily). With three monitors and a few minutes of data it took under a second. With hundreds of monitors and months of history it can take much longer. Do not stop or restart the container while it runs. If it is interrupted, restore the backup and start again.

3. Check the result

The web UI answered 11 seconds after start. After logging in, the same three monitors were there and active, and the heartbeat count kept going up (3 before the upgrade, 6 a minute later), so monitoring never paused for longer than the restart. The node runtime moved from 18 to 22 inside the image; nothing on the host changed.

Changes in 2.x that catch people out

  • No JSON backup/restore. Back up the data volume (above).
  • WebSocket origin check. 2.x rejects WebSocket connections whose Origin does not match the Host; its log then says Invalid origin url or Origin ... does not match host. Behind a reverse proxy, pass the original Host header and enable “Trust Proxy” in Settings → Reverse Proxy. The environment variable UPTIME_KUMA_WS_ORIGIN_CHECK=bypass turns the check off, but use it only if you understand why it fails.
  • New monitors default to 0 retries (it was 1), so a single failed check alerts at once. Set retries to 1 or 2 for sites behind slow networks.
  • Badge durations accept only 24, 24h, 30d or 1y.
  • Email notifications use LiquidJS templates with case-sensitive variable names. Check any custom templates after upgrading.
  • API scripts: 2.x registers its socket handlers a moment after the connection opens. Our test script’s first login attempt was silently ignored until we waited a few seconds after connecting.

Put it behind HTTPS

The dashboard and status pages should be served over HTTPS by a reverse proxy (Nginx, Caddy, Apache) that forwards WebSocket upgrades. Minimal Nginx location:

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-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

Turn on two-factor authentication for the admin account. Uptime Kuma holds your notification tokens (Telegram, Slack, email passwords).

What to monitor on a hosting server

Monitor typeExampleWhy
HTTP(s) – KeywordHome page must contain the site nameCatches a 200 response that serves a default page or an error, which a plain status check misses
HTTP(s)https://server:2087 (WHM) or :2222 (DirectAdmin)Panel is reachable; certificate expiry warnings
TCP port25, 465, 587, 993 on the mail serverMail services answer
DNSYour domain’s A and MX recordsCatches DNS changes and broken zones
PingThe server IPNetwork-level reachability
PushA cron job that calls the push URL after backupsAlerts when a backup job did not run

For a quick one-off check without installing anything, our free uptime, SSL and blacklist monitor and website down checker are enough.

If you would rather not host it

A self-hosted monitor needs its own server, updates and backups. Hosted services such as UptimeRobot, Better Stack and HetrixTools have free tiers and run the checks from several locations. For a single small site, a hosted free tier is usually simpler; for many sites or private checks inside your network, Uptime Kuma is the better fit.

Frequently asked questions

How do I upgrade Uptime Kuma from 1.23 to 2.0 in Docker?

Stop the container, back up the whole data volume (not just kuma.db), remove the old container and start louislam/uptime-kuma:2 on the same volume. Watch docker logs until the aggregate table migration completes and do not interrupt it.

Will I lose my monitors when upgrading to Uptime Kuma 2?

Not in our test: all monitors and their history were kept, and monitoring resumed straight after the restart. Back up the stopped data volume first so you can roll back.

Why is my Uptime Kuma backup of kuma.db empty?

The database runs in WAL mode, so recent data is in kuma.db-wal. Copying kuma.db from a running container misses it. Stop the container and copy the whole data directory.

What is the difference between the uptime-kuma:2 and 2-slim images?

The full image (2.49 GB on our lab) includes Chromium for real-browser monitors and an embedded MariaDB. 2-slim (850 MB) has neither and offers SQLite or an external MariaDB/MySQL.

Why does Uptime Kuma 2 say Invalid origin url?

Version 2 checks that a WebSocket’s Origin header matches the Host header. Behind a reverse proxy, pass the original Host header and enable Trust Proxy in the settings; the check can also be bypassed with UPTIME_KUMA_WS_ORIGIN_CHECK=bypass.

Reading a lot of our guides? Go ad-free with srvScripts Pro for $6 a month. It also pays for new guides. Cancel any time.

Share this guide

Free website test

Is your website set up right?

Check SSL, security headers, redirects, robots.txt, sitemap, llms.txt and security.txt in one test. It takes about 30 seconds.