#!/usr/bin/env bash # One-shot setup for the PON Fleet web server on a Debian 13 LXC. # # Clone the repo first (anywhere — /opt/ponfw recommended), then run this # from inside the checkout as root: # # git clone ssh://forgejo@int.git.vanvikinternet.no/Svorka/ponfw.git /opt/ponfw # sudo /opt/ponfw/web/deploy/install.sh # # It installs runtime deps (tough-cookie only; skips Electron), creates an # unprivileged service user, writes /etc/pon-fleet-web.env on first run, and # installs + enables a systemd unit pointed at THIS checkout. Safe to re-run. set -euo pipefail SERVICE="pon-fleet-web" SERVICE_USER="ponfw" ENV_FILE="/etc/pon-fleet-web.env" # Repo root is two levels up from this script (web/deploy/install.sh). SCRIPT_DIR="$(cd "$(dirname "$(readlink -f "$0")")" && pwd)" REPO="$(cd "$SCRIPT_DIR/../.." && pwd)" DEPLOY="$REPO/web/deploy" if [[ $EUID -ne 0 ]]; then echo "Run as root: sudo $0" >&2 exit 1 fi echo "==> Repo checkout: $REPO" case "$REPO" in /home/*) echo "!! WARNING: the repo is under /home. The hardened systemd unit sets" >&2 echo "!! ProtectHome=true, which will stop the service from reading it." >&2 echo "!! Clone to /opt/ponfw instead, or remove ProtectHome from the unit." >&2 ;; esac # --- dependencies (git, node, npm) --- need=() command -v git >/dev/null 2>&1 || need+=(git) command -v node >/dev/null 2>&1 || need+=(nodejs) command -v npm >/dev/null 2>&1 || need+=(npm) if (( ${#need[@]} )); then echo "==> apt-get install ${need[*]}" apt-get update -y apt-get install -y "${need[@]}" fi NODE_MAJOR="$(node -p 'process.versions.node.split(".")[0]' 2>/dev/null || echo 0)" if (( NODE_MAJOR < 18 )); then echo "!! Node $(node -v 2>/dev/null || echo '?') is too old (need >= 18)." >&2 echo "!! Install a newer Node (e.g. via NodeSource) and re-run." >&2 exit 1 fi echo "==> Using $(node -v)" # --- service user --- if ! id -u "$SERVICE_USER" >/dev/null 2>&1; then echo "==> Creating system user $SERVICE_USER" adduser --system --group --no-create-home "$SERVICE_USER" fi # --- runtime deps (npm install, not ci: package-lock.json is gitignored) --- echo "==> Installing runtime dependencies" ( cd "$REPO" && npm install --omit=dev --no-audit --no-fund ) # --- env file (first run only; never clobber operator edits) --- if [[ -f "$ENV_FILE" ]]; then echo "==> $ENV_FILE already exists — leaving it untouched" else echo "==> Writing $ENV_FILE from the example (review it)" install -m 0640 "$DEPLOY/pon-fleet-web.env.example" "$ENV_FILE" fi # --- systemd unit, with WorkingDirectory pointed at THIS checkout --- echo "==> Installing systemd unit" sed "s|^WorkingDirectory=.*|WorkingDirectory=$REPO/web|" \ "$DEPLOY/$SERVICE.service" > "/etc/systemd/system/$SERVICE.service" systemctl daemon-reload systemctl enable --now "$SERVICE" sleep 1 systemctl --no-pager --lines=10 status "$SERVICE" || true IP="$(hostname -I 2>/dev/null | awk '{print $1}')" cat < Done — $SERVICE is enabled and running. Config: $ENV_FILE Logs: journalctl -u $SERVICE -f Update: sudo $DEPLOY/update.sh Point Nginx Proxy Manager at this LXC: Forward Hostname/IP: ${IP:-} Forward Port: 8080 Scheme: http Add your Access List, request an SSL cert, enable Block Common Exploits. (If NPM runs on a different host, set HOST=0.0.0.0 in $ENV_FILE and restart: systemctl restart $SERVICE) MSG