Skip to main content

Running Uptime Kuma on a Raspberry Pi Zero W

Running Uptime Kuma 2.4.0 on a Raspberry Pi Zero W — Everynerd
← BACK TO EVERYNERD

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.

Before You Start Uptime Kuma 2.4.0 officially requires Node.js ≥20.4.0. The official Node.js project doesn't ship an ARMv6 binary for that release — only ARMv7 and ARM64. This guide uses Node.js 18.9.1 from the community-maintained 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.

Hardware
Pi Zero W Rev. 1.1
CPU
ARMv6
RAM
512 MB
OS
Pi OS Lite Bookworm, 32-bit
Node.js
18.9.1 (ARMv6 unofficial)
npm
8.19.1
Uptime Kuma
2.4.0
Install method
Native (no Docker)

To confirm your own Pi matches this profile before starting:

uname -a
cat /proc/cpuinfo

The Install, Step by Step

1

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.

2

Update the OS

sudo apt update
sudo apt full-upgrade -y
sudo reboot

Reconnect over SSH once it's back up.

3

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.

4

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.

5

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
6

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.

7

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.

8

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');"
9

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.

10

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.

11

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.

12

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.

Don't Do This Do not run 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.
npm runs out of memory Symptoms: 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
Heads Up Future Uptime Kuma releases may bump their minimum Node.js requirement further, or add dependencies that simply don't have ARMv6 support at all. Treat every update as a fresh test, not a guaranteed drop-in.

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.

The Pi Zero W was never going to make this easy — the goal was just proving it could be done at all.

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.
  • gdb traced the crash directly to node_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-dist sidestepped the failing Vite build.
  • Uptime Kuma 2.4.0 ultimately ran successfully, start to finish, on the Pi Zero W.

Final Working Configuration

Hardware
Pi Zero W Rev. 1.1
Architecture
ARMv6
OS
Pi OS Lite Bookworm, 32-bit
Node
18.9.1 ARMv6
npm
8.19.1
Uptime Kuma
2.4.0
SQLite
sqlite3 15.1.6, compiled locally
Frontend
Prebuilt via download-dist
Swap
2 GB swapfile + zram
Service
systemd
Port
3001
Docker
Not used
Bottom Line

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.