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.
Table of Contents
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:3001keeps 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 withss -ltnp | grep 3001first.- 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?
| Tag | Size on our lab | Includes | Choose it when |
|---|---|---|---|
louislam/uptime-kuma:2 | 2.49 GB | Chromium (for “real browser” monitors) and an embedded MariaDB | You want browser-based checks or the built-in MariaDB |
louislam/uptime-kuma:2-slim | 850 MB | Neither; the setup page offered no embedded MariaDB | Normal HTTP, keyword, ping, port and DNS checks with SQLite or an external database |
louislam/uptime-kuma:1 | 724 MB | Version 1.23.x | Only 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
Origindoes not match theHost; its log then saysInvalid origin urlorOrigin ... does not match host. Behind a reverse proxy, pass the originalHostheader and enable “Trust Proxy” in Settings → Reverse Proxy. The environment variableUPTIME_KUMA_WS_ORIGIN_CHECK=bypassturns 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 type | Example | Why |
|---|---|---|
| HTTP(s) – Keyword | Home page must contain the site name | Catches 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 port | 25, 465, 587, 993 on the mail server | Mail services answer |
| DNS | Your domain’s A and MX records | Catches DNS changes and broken zones |
| Ping | The server IP | Network-level reachability |
| Push | A cron job that calls the push URL after backups | Alerts 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.