Running Uptime Kuma 2.4.0 on a Raspberry Pi Zero W
The Raspberry Pi Zero W is a genuinely terrible platform for running much of anything modern — single-core ARMv6, 512 MB of RAM, no official Docker support to speak of. Which is exactly why getting Uptime Kuma 2.4.0 running on one natively, without Docker, felt worth documenting. This is not the standard Uptime Kuma install. It's the workaround version, and every step below exists because something failed first.
unofficial-builds project instead, which does provide an ARMv6 build. That project describes its ARMv6 builds as experimental and community-maintained, not official — go in with that expectation.
Why This Is Harder Than a Normal Install
A few ARMv6-specific problems make this install its own beast:
ARMv6 isn't ARMv7. The Pi Zero W's CPU is ARMv6, and you cannot run an ARMv7 binary on it — the result is a flat Illegal instruction crash, not a graceful failure.
Docker doesn't save you here. Uptime Kuma's standard installation path leans on Docker, but there's no suitable ARMv6 image available. Native installation is the only practical route on original Pi Zero-class hardware.
SQLite is the actual landmine. Uptime Kuma depends on @louislam/sqlite3, which ships native compiled code. The generic prebuilt Linux ARM binary is frequently incompatible with ARMv6 specifically, and loading it produces the same Illegal instruction crash.
Raspberry Pi OS Trixie makes it worse. Trixie ships Python 3.13, which dropped the distutils module. The version of node-gyp involved in compiling SQLite still tries to import it, so the native build fails before it starts. Raspberry Pi OS Bookworm avoids this entirely — use Bookworm, not Trixie.
Hardware & Software Used
This is the exact tested configuration. Deviating from it — especially the OS version — is where most of the failure modes above come from.
To confirm your own Pi matches this profile before starting:
uname -a cat /proc/cpuinfo
The Install, Step by Step
Flash Raspberry Pi OS Bookworm
Using Raspberry Pi Imager, select Raspberry Pi OS Lite, 32-bit, Bookworm release — not Trixie. In the imager's configuration step, set hostname, username, password, Wi-Fi, SSH, and time zone so it's ready to boot headless. SSH in once it's up to confirm connectivity.
Update the OS
sudo apt update sudo apt full-upgrade -y sudo reboot
Reconnect over SSH once it's back up.
Add a 2 GB swapfile
With only 512 MB of RAM, npm's dependency install and native compilation will outgrow available memory without help.
sudo fallocate -l 2G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
Verify with free -h and swapon --show. Output may look slightly different if zram is also active alongside the swapfile — that's expected.
Install build tools
sudo apt install -y \ git build-essential python3 python3-dev \ python3-setuptools make g++ pkg-config \ libsqlite3-dev ca-certificates curl
These are needed because SQLite's native module has to be compiled locally for ARMv6 rather than downloaded prebuilt.
Install Node.js 18.9.1 for ARMv6
The official Node 18.9.1 release doesn't include an ARMv6 build. The unofficial-builds project maintains a dedicated linux-armv6l build for Pi 1/Zero-class hardware:
cd ~ curl -LO https://unofficial-builds.nodejs.org/download/release/v18.9.1/node-v18.9.1-linux-armv6l.tar.gz tar -xzf node-v18.9.1-linux-armv6l.tar.gz sudo cp -a node-v18.9.1-linux-armv6l/. /usr/local/
Confirm it installed correctly:
node -v # v18.9.1 npm -v # 8.19.1 node -p "process.arch" # arm
Clone Uptime Kuma 2.4.0
cd ~ git clone https://github.com/louislam/uptime-kuma.git cd uptime-kuma git checkout 2.4.0
Checking out the tag explicitly matters — it stops you from accidentally building against a newer development branch that may not work on ARMv6 at all.
Install dependencies
npm ci
This takes a genuinely long time on a Pi Zero — the CPU and storage are both bottlenecks. A long stretch of apparent silence isn't necessarily a freeze; let it run.
Force SQLite to compile from source
This is the step the whole guide exists for. The prebuilt @louislam/sqlite3 binary that ships by default isn't ARMv6-safe and will crash with Illegal instruction at runtime.
rm -rf node_modules/@louislam/sqlite3/lib/binding npm rebuild @louislam/sqlite3 --build-from-source --verbose
This triggers node-gyp to run a real C/C++ compilation and produce a fresh node_sqlite3.node built for your actual CPU. Verify it worked:
find node_modules/@louislam/sqlite3 -name "*.node" -ls
node -e "require('@louislam/sqlite3'); console.log('SQLite loaded successfully');"
Download the prebuilt frontend
npm run download-dist
Uptime Kuma ships a script specifically for pulling the already-built frontend assets instead of compiling them locally — this is included in the project's own setup script, and it's what makes the next step possible.
Start it up and create your admin account
npm run start
Watch for Welcome to Uptime Kuma and Server Type: HTTP on port 3001, then browse to http://PI-IP-ADDRESS:3001 (e.g. http://192.168.1.100:3001). Create the initial administrator account and confirm the dashboard loads.
Turn it into a systemd service
Create /etc/systemd/system/uptime-kuma.service:
[Unit] Description=Uptime Kuma After=network.target [Service] Type=simple User=matt WorkingDirectory=/home/matt/uptime-kuma ExecStart=/usr/local/bin/node server/server.js Restart=always RestartSec=10 Environment=NODE_ENV=production [Install] WantedBy=multi-user.target
Swap User and WorkingDirectory for your own username and install path if they differ.
Enable it and confirm it survives a reboot
sudo systemctl daemon-reload sudo systemctl enable uptime-kuma sudo systemctl start uptime-kuma systemctl status uptime-kuma # look for "Active: active (running)"
Then actually test it — sudo reboot, reconnect, and check systemctl status uptime-kuma plus the dashboard again. If it comes back up on its own, the install is done.
npm run build on the Pi Zero. A standard install guide would suggest it, but on this ARMv6 hardware it fails with vite build → Illegal instruction. You don't need it — npm run download-dist (Step 9) already pulled the release's prebuilt frontend, which is sufficient on its own.
Troubleshooting
Illegal instruction when loading SQLite
Check with find node_modules/@louislam/sqlite3 -name "*.node". Fix by removing the prebuilt binding and rebuilding from source: rm -rf node_modules/@louislam/sqlite3/lib/binding then npm rebuild @louislam/sqlite3 --build-from-source --verbose.
ModuleNotFoundError: No module named 'distutils'
Caused by Python 3.13 (Trixie) paired with an older node-gyp. Fix by reinstalling on Raspberry Pi OS Bookworm instead.
FATAL ERROR: Reached heap limit, Allocation failed - JavaScript heap out of memory. Fix by increasing swap (Step 3) and confirming with free -h / swapon --show.
Cannot find module '@louislam/sqlite3'
Usually means you're not in the right directory. Run cd ~/uptime-kuma and try again.
vite build produces Illegal instruction
Don't build the frontend locally at all — use npm run download-dist instead and skip npm run build entirely.
Updating Later
Updating is trickier than a normal Uptime Kuma install, because the SQLite native module has to stay ARMv6-compatible through every version bump:
cd ~/uptime-kuma sudo systemctl stop uptime-kuma git fetch --all --tags git checkout <VERSION> npm ci rm -rf node_modules/@louislam/sqlite3/lib/binding npm rebuild @louislam/sqlite3 --build-from-source npm run download-dist sudo systemctl start uptime-kuma
What the Pi Zero Can Actually Handle
Worth setting expectations here: this is a single-core, 512 MB board. Keep an eye on CPU, RAM, swap usage, and SD card wear, and don't load it up with more monitors than it can realistically poll. This is a fine little uptime dashboard for a handful of services — it is not going to comfortably watch fifty endpoints.
Lessons Learned
- An initial attempt with Node 20 failed outright — building Node itself on the Pi Zero wasn't practical.
- Node 20 from a pre-built source ran, but Uptime Kuma's SQLite module crashed with
SIGILL. gdbtraced the crash directly tonode_sqlite3.node.- A clean install confirmed the prebuilt SQLite binary itself was the problem, not something environmental.
- Raspberry Pi OS Trixie introduced a second, unrelated failure via Python 3.13 and
node-gyp. - Switching to Bookworm eliminated that second problem entirely.
- Compiling SQLite locally finally produced a working ARMv6 module.
- The prebuilt frontend from
download-distsidestepped the failing Vite build. - Uptime Kuma 2.4.0 ultimately ran successfully, start to finish, on the Pi Zero W.
Final Working Configuration
Yes, you really can run Uptime Kuma on an original Raspberry Pi Zero W. It's not the easiest platform for it, and it takes a few real departures from the standard install — an unofficial ARMv6 Node build, a locally compiled SQLite module, and the prebuilt frontend instead of a local Vite build — but with those three workarounds in place, Uptime Kuma 2.4.0 runs, and keeps running, on genuinely tiny hardware.