Fixes the tsc-not-found build error when NODE_ENV=production omits build tooling. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Deployment (Proxmox LXC, auto-start)
Shelfless runs as a small Node server that serves the built SPA and reverse-proxies
the ABS API. So the browser only ever talks to Shelfless (one origin → no CORS), and the
Audiobookshelf address is fixed by the deployment (ABS_URL) — users only log in.
1. Prerequisites on the container
apt update && apt install -y nodejs npm git # Node 18+ (20+ recommended)
node --version
2. Get the code & build
mkdir -p /opt/shelfless && cd /opt/shelfless
# copy the project here (git clone / scp / rsync), then:
npm ci
npm run build # produces dist/
3. Configure the ABS target
The server reads these env vars (see the systemd unit):
ABS_URL— the Audiobookshelf server, e.g.http://127.0.0.1:13378(same container) orhttp://192.168.1.71:13378(another host).PORT— the port Shelfless listens on (default8080).HOST— bind address (default0.0.0.0).
Quick manual test:
ABS_URL=http://127.0.0.1:13378 PORT=8080 npm start
# open http://<container-ip>:8080
4. One-shot install + auto-start (recommended)
The installer does everything (Node, build, systemd enable/start). The ABS URL and port are positional args (or env vars):
git clone https://git.scarriffle.com/Scarriffle/shelfless.git /opt/shelfless
cd /opt/shelfless
bash deploy/install.sh http://127.0.0.1:13378 8080
- 1st arg = ABS_URL (default
http://127.0.0.1:13378) - 2nd arg = PORT (default
8080)
Manage it afterwards:
systemctl status shelfless # check it's running
journalctl -u shelfless -f # logs
systemctl restart shelfless # restart
Open http://<container-ip>:8080. The setup screen asks only for username + password
(the server URL is fixed). "Angemeldet bleiben" keeps you logged in across reloads;
otherwise you log in each session.
Updating
cd /opt/shelfless
git pull # or copy new files
npm ci && npm run build
systemctl restart shelfless
Notes
- Put it behind a reverse proxy (nginx/Caddy/Traefik) for HTTPS + a domain if you expose it beyond the LAN.
- Proxied paths:
/api,/login,/logout,/public,/status,/hls,/feed,/socket.io. Everything else is served fromdist/(SPA fallback toindex.html).