Upgrading Uptime Kuma from version 1 to 2 with Docker, without losing anything
How I moved from Uptime Kuma 1.23 to 2.x: the backup you can't skip, the right image tag and a Python library that stopped working.
Uptime Kuma 2 brings plenty of improvements (including support for other databases and lots of fixes), but it’s a major version: the database structure changes. So you can’t just change a number and hope.
Here’s how I did it on the Raspberry Pi.
1. Back up first
Kuma keeps everything (monitors, history, notifications) in one data folder. For the backup, stop the container first, so there are no half-finished writes:
docker compose stop uptime-kuma
tar czf ~/backup/uptime-kuma-before-v2.tar.gz -C ~/servicios uptime-kuma
If something goes wrong, restoring means extracting that folder and going back to the old image.
The SQLite WAL-mode trap
Kuma uses SQLite in WAL mode. In that mode, recent changes aren’t in kuma.db but in kuma.db-wal until they’re flushed. If you ever copy the database “hot” to inspect it, copy all three files together:
kuma.db kuma.db-wal kuma.db-shm
If you copy only kuma.db, you’ll be missing the latest changes and think something got lost.
2. Change the image
In docker-compose.yml:
uptime-kuma:
image: louislam/uptime-kuma:2
I use the 2 tag, not latest. That way I get version 2 updates, but the day a 3 comes out it won’t be installed without warning.
docker compose pull uptime-kuma
docker compose up -d uptime-kuma
docker logs -f uptime-kuma
The first start takes longer than usual: it’s migrating the database. Don’t interrupt it. The logs show the migration progress; when it finishes, the web UI responds again.
3. Check
- Open the web UI and make sure all monitors are there.
- Check the history is still there.
- Review the notifications and send a test.
What broke: the Python library
I had created the monitors programmatically with an unofficial Python library that talks to Kuma’s API. With Kuma 2 it stopped working: the internal API changed.
If you automate Kuma with scripts, check this before upgrading. In my case, to look things up “behind the scenes” I now read the SQLite database directly (copying all three files, as above), and make changes from the web UI.
Summary
- Stop the container and copy the data folder.
- Switch to the
2tag, notlatest. - Let the first migration finish.
- Check monitors, history and alerts.
- If you have scripts using its API, make sure they still work.
Did it stick?
Three quick questions. Each right answer is worth 10 XP.