Initial commit: Shelfless – alternative Audiobookshelf frontend

React + Vite + TypeScript SPA covering the full ABS feature set (library
browsing, item detail, metadata/cover editing, podcasts, player with session
sync, admin: users/libraries/scanner/server settings). Dev uses a dynamic
CORS proxy; production is served by server/index.mjs (static + reverse proxy
to ABS_URL). Includes systemd unit and installer under deploy/.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-06-02 20:23:04 +02:00
commit 83d8b7b99d
93 changed files with 9790 additions and 0 deletions

75
deploy/install.sh Normal file
View File

@@ -0,0 +1,75 @@
#!/usr/bin/env bash
# Shelfless installer for a Debian/Ubuntu Proxmox LXC.
# Installs Node, fetches the repo, builds the frontend, and sets up a systemd service
# that serves the app and reverse-proxies to your Audiobookshelf server.
#
# Usage (as root on the container):
# REPO_URL=https://git.scarriffle.com/<owner>/shelfless.git \
# ABS_URL=http://127.0.0.1:13378 PORT=8080 \
# bash install.sh
#
# Re-running updates an existing install.
set -euo pipefail
REPO_URL="${REPO_URL:?Set REPO_URL to your git repo, e.g. https://git.scarriffle.com/owner/shelfless.git}"
INSTALL_DIR="${INSTALL_DIR:-/opt/shelfless}"
ABS_URL="${ABS_URL:-http://127.0.0.1:13378}"
PORT="${PORT:-8080}"
SERVICE="${SERVICE:-shelfless}"
echo "==> Installing system dependencies"
apt-get update -y
apt-get install -y git curl ca-certificates
if ! command -v node >/dev/null 2>&1; then
echo "==> Installing Node.js 20.x"
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
apt-get install -y nodejs
fi
echo " node $(node --version), npm $(npm --version)"
echo "==> Fetching source into $INSTALL_DIR"
if [ -d "$INSTALL_DIR/.git" ]; then
git -C "$INSTALL_DIR" pull --ff-only
else
git clone "$REPO_URL" "$INSTALL_DIR"
fi
echo "==> Building"
cd "$INSTALL_DIR"
npm ci
npm run build
echo "==> Writing systemd unit /etc/systemd/system/$SERVICE.service"
NODE_BIN="$(command -v node)"
cat > "/etc/systemd/system/$SERVICE.service" <<EOF
[Unit]
Description=Shelfless (Audiobookshelf frontend)
After=network.target
[Service]
Type=simple
WorkingDirectory=$INSTALL_DIR
ExecStart=$NODE_BIN server/index.mjs
Restart=on-failure
RestartSec=3
Environment=NODE_ENV=production
Environment=PORT=$PORT
Environment=ABS_URL=$ABS_URL
[Install]
WantedBy=multi-user.target
EOF
echo "==> Enabling and starting service"
systemctl daemon-reload
systemctl enable --now "$SERVICE"
sleep 1
systemctl --no-pager --full status "$SERVICE" || true
IP="$(hostname -I 2>/dev/null | awk '{print $1}')"
echo ""
echo "Done. Shelfless is running:"
echo " URL: http://${IP:-<container-ip>}:$PORT"
echo " ABS: $ABS_URL"
echo " Logs: journalctl -u $SERVICE -f"