#!/usr/bin/env bash # scripts/server-setup.sh # One-time setup for a direct Node.js deployment (no Docker). # Run this once on the server as root or with sudo. # Usage: bash scripts/server-setup.sh [install-dir] # # Installs: Node.js 18, PM2, creates app directory and data dirs. set -euo pipefail INSTALL_DIR="${1:-/opt/bill-tracker}" DATA_DIR="${INSTALL_DIR}/data" APP_USER="${APP_USER:-www-data}" echo "=== Bill Tracker — Server Setup ===" echo "Install dir : $INSTALL_DIR" echo "Data dir : $DATA_DIR" echo "App user : $APP_USER" echo "" # ── Node.js 18 ───────────────────────────────────────────────────────────────── if ! command -v node &>/dev/null || [[ "$(node -e 'console.log(process.version.split(".")[0].slice(1))')" -lt 18 ]]; then echo "→ Installing Node.js 18..." if command -v apt-get &>/dev/null; then curl -fsSL https://deb.nodesource.com/setup_18.x | bash - apt-get install -y nodejs elif command -v dnf &>/dev/null; then curl -fsSL https://rpm.nodesource.com/setup_18.x | bash - dnf install -y nodejs else echo "ERROR: Unsupported package manager. Install Node.js 18 manually." exit 1 fi else echo "✓ Node.js $(node --version) already installed" fi # ── PM2 ──────────────────────────────────────────────────────────────────────── if ! command -v pm2 &>/dev/null; then echo "→ Installing PM2..." npm install -g pm2 else echo "✓ PM2 already installed" fi # ── App and data directories ─────────────────────────────────────────────────── echo "→ Creating directories..." mkdir -p "$INSTALL_DIR" "$DATA_DIR/db" "$DATA_DIR/backups" if id "$APP_USER" &>/dev/null; then chown -R "$APP_USER:$APP_USER" "$INSTALL_DIR" fi # ── PM2 startup (survives reboots) ──────────────────────────────────────────── echo "→ Configuring PM2 startup..." pm2 startup systemd -u "$APP_USER" --hp "/home/$APP_USER" 2>/dev/null || \ echo " (Run the 'pm2 startup' command shown above as root to enable auto-start)" echo "" echo "=== Setup complete ===" echo "" echo "Next steps:" echo " 1. rsync the project: ./deploy.sh user@$(hostname) $INSTALL_DIR" echo " 2. On the server, create $INSTALL_DIR/.env from .env.example" echo " 3. PM2 will start the app automatically after rsync"