Wiki.js works well inside a FreeBSD jail, but there is one important catch: the official Wiki.js release ships a prebuilt Linux sqlite3 native module. On FreeBSD this needs to be rebuilt locally before Wiki.js will start.
This post covers a simple Wiki.js 2.5.314 installation on FreeBSD 15.1 using SQLite, Node.js 24, and a native rc.d service.
Setup
The jail is a normal FreeBSD 15.1-RELEASE jail with its own IP on the LAN.
FreeBSD 15.1-RELEASE Host
│
└── wiki jail
└── Wiki.js :3000
No Docker or Linux emulation is needed. Wiki.js itself runs natively under FreeBSD Node.js.
Installing Wiki.js
I created a small bootstrap script which handles the whole installation.
Inside the jail as root:
fetch https://codeberg.org/dkade/BSD/raw/branch/main/FreeBSD/wikijs/install-wikijs-freebsd-15.1.sh
chmod +x install-wikijs-freebsd-15.1.sh
./install-wikijs-freebsd-15.1.sh
The script installs:
node24
npm-node24
python311
gmake
pkgconf
sqlite3
ca_root_nss
It then downloads Wiki.js 2.5.314 and extracts it under:
/usr/local/wikijs
A dedicated wikijs user is created to run the service instead of running Wiki.js as root.
The SQLite FreeBSD gotcha
The official Wiki.js release includes its node_modules, including a prebuilt sqlite3 native module.
Trying to start it directly on FreeBSD results in errors such as:
Shared object "libc.musl-x86_64.so.1" not found,
required by "node_sqlite3.node"
Running ldd makes the problem obvious:
ldd /usr/local/wikijs/node_modules/sqlite3/build/Release/node_sqlite3.node
returns:
not a FreeBSD ELF shared object
The bundled module is a Linux/musl binary, so it cannot be used natively on FreeBSD.
The solution is to rebuild only the SQLite native module:
cd /usr/local/wikijs
rm -rf node_modules/sqlite3/build
env \
npm_config_python=/usr/local/bin/python3.11 \
npm_config_build_from_source=true \
MAKE=gmake \
npm rebuild sqlite3
Python 3.11 is used because the version of node-gyp bundled with Wiki.js 2.5.x still depends on Python’s old distutils module, which was removed in Python 3.12.
After the rebuild:
file node_modules/sqlite3/build/Release/node_sqlite3.node
should identify it as a FreeBSD ELF shared object.
Test it directly:
node -e "const s=require('sqlite3'); console.log(s.VERSION); console.log('sqlite3 OK')"
Configuration
Wiki.js uses:
/usr/local/wikijs/config.yml
For a simple SQLite setup:
port: 3000
db:
type: sqlite
storage: /usr/local/wikijs/data/wiki.db
Make sure the database directory is writable by the Wiki.js user:
mkdir -p /usr/local/wikijs/data
chown -R wikijs:wikijs /usr/local/wikijs
FreeBSD rc.d service
The installer creates:
/usr/local/etc/rc.d/wikijs
Wiki.js is started using FreeBSD’s daemon(8) and Node.js:
/usr/local/bin/node /usr/local/wikijs/server
The service is enabled with:
sysrc wikijs_enable=YES
Start it:
service wikijs start
Check the status:
service wikijs status
Restart it:
service wikijs restart
Logs are written to:
/var/log/wikijs.log
so they can be followed with:
tail -f /var/log/wikijs.log
Once running, Wiki.js is available at:
http://<jail-ip>:3000
The first connection opens the Wiki.js setup wizard.
Upgrading
Before upgrading, take a ZFS snapshot or at least back up:
/usr/local/wikijs/config.yml
/usr/local/wikijs/data/
After replacing the Wiki.js application files with a newer release, rebuild the SQLite module again:
cd /usr/local/wikijs
env \
npm_config_python=/usr/local/bin/python3.11 \
npm_config_build_from_source=true \
MAKE=gmake \
npm rebuild sqlite3
Then restart Wiki.js:
service wikijs restart
Avoid blindly running:
npm update
or:
npm audit fix --force
inside the Wiki.js application tree. Wiki.js ships with a specific dependency set and changing package versions independently can break the application.
Gotchas
- SQLite native module: the bundled
node_sqlite3.nodeis Linux/musl and must be rebuilt for FreeBSD. - Python version: use Python 3.11 when rebuilding with the older bundled
node-gyp. - Node.js: Wiki.js 2.5.314 runs correctly with the FreeBSD
node24package. - Do not copy old
node_modules: when upgrading, use a clean Wiki.js release tree and preserve only your configuration and database. - rc.d PID tracking: when using
daemon(8), setprocnameto/usr/local/bin/nodesoservice wikijs statuscorrectly detects the running process.
Summary
Wiki.js runs cleanly inside a FreeBSD 15.1 jail without Docker or Linux emulation.
The only non-obvious part is rebuilding the bundled SQLite native module for FreeBSD. Once that is done, Wiki.js behaves like any other native FreeBSD service: a dedicated user, an rc.d script, automatic startup, and straightforward ZFS snapshots for backups and upgrades.
The bootstrap script automates the complete process from a fresh jail.
Disclaimer: I use AI as a productivity tool. For a senior engineer, AI is incredibly powerful as one can focus on the solution design and conceptualization and leave the boring part that is implementation to the AI.
