#!/usr/bin/env bash # LunarFront — One-time EC2 provisioning script # Run as root (or with sudo) on a fresh Ubuntu 24.04 instance. # Usage: sudo bash deploy/setup.sh set -euo pipefail REPO_URL="git@github.com:YOUR_ORG/YOUR_REPO.git" APP_DIR="/opt/lunarfront" APP_USER="ubuntu" DB_USER="lunarfront" DB_NAME="lunarfront" DB_PASS="$(openssl rand -hex 16)" # auto-generated; written to .env # ── 1. System packages ──────────────────────────────────────────────────────── echo "==> Updating system packages..." apt-get update -y && apt-get upgrade -y apt-get install -y curl git build-essential nginx certbot python3-certbot-nginx unzip # ── 2. Bun runtime ──────────────────────────────────────────────────────────── echo "==> Installing Bun..." sudo -u "$APP_USER" bash -c 'curl -fsSL https://bun.sh/install | bash' BUN_BIN="/home/${APP_USER}/.bun/bin/bun" # ── 3. PostgreSQL 16 ────────────────────────────────────────────────────────── echo "==> Installing PostgreSQL 16..." apt-get install -y postgresql-16 postgresql-contrib-16 systemctl enable --now postgresql echo "==> Creating database user and database..." sudo -u postgres psql -tc "SELECT 1 FROM pg_roles WHERE rolname='${DB_USER}'" | grep -q 1 || \ sudo -u postgres psql -c "CREATE USER ${DB_USER} WITH PASSWORD '${DB_PASS}';" sudo -u postgres psql -tc "SELECT 1 FROM pg_database WHERE datname='${DB_NAME}'" | grep -q 1 || \ sudo -u postgres psql -c "CREATE DATABASE ${DB_NAME} OWNER ${DB_USER};" # ── 4. Valkey 8 ─────────────────────────────────────────────────────────────── echo "==> Installing Valkey..." # Try official Valkey apt repo first; fall back to Redis 7 if unavailable if curl -fsSL https://packages.valkey.io/ubuntu/gpg.asc 2>/dev/null | \ gpg --dearmor -o /usr/share/keyrings/valkey.gpg; then echo "deb [signed-by=/usr/share/keyrings/valkey.gpg] https://packages.valkey.io/ubuntu noble main" \ > /etc/apt/sources.list.d/valkey.list apt-get update -y && apt-get install -y valkey REDIS_SERVICE="valkey" else echo "Valkey repo unavailable, falling back to Redis 7..." apt-get install -y redis-server REDIS_SERVICE="redis-server" fi systemctl enable --now "$REDIS_SERVICE" # ── 5. Clone repository ─────────────────────────────────────────────────────── echo "==> Cloning repository to ${APP_DIR}..." if [ -d "$APP_DIR" ]; then echo " ${APP_DIR} already exists, skipping clone." else git clone "$REPO_URL" "$APP_DIR" chown -R "$APP_USER:$APP_USER" "$APP_DIR" fi cd "$APP_DIR" # ── 6. Environment file ─────────────────────────────────────────────────────── if [ ! -f "${APP_DIR}/.env" ]; then echo "==> Generating .env..." JWT_SECRET=$(openssl rand -hex 32) cat > "${APP_DIR}/.env" < Installing dependencies..." sudo -u "$APP_USER" "$BUN_BIN" install --frozen-lockfile echo "==> Building admin frontend..." sudo -u "$APP_USER" bash -c "cd ${APP_DIR}/packages/admin && ${BUN_BIN} run build" # ── 8. Run database migrations ──────────────────────────────────────────────── echo "==> Running database migrations..." sudo -u "$APP_USER" bash -c \ "cd ${APP_DIR}/packages/backend && ${BUN_BIN} x drizzle-kit migrate" # ── 9. Create file storage directory ───────────────────────────────────────── mkdir -p "${APP_DIR}/data/files" chown -R "$APP_USER:$APP_USER" "${APP_DIR}/data" # ── 10. Systemd service ─────────────────────────────────────────────────────── echo "==> Installing systemd service..." # Substitute real Bun path into service file sed "s|/home/ubuntu/.bun/bin/bun|${BUN_BIN}|g" \ "${APP_DIR}/deploy/lunarfront.service" > /etc/systemd/system/lunarfront.service systemctl daemon-reload systemctl enable lunarfront systemctl restart lunarfront # ── 11. Nginx ───────────────────────────────────────────────────────────────── echo "==> Configuring Nginx..." cp "${APP_DIR}/deploy/nginx.conf" /etc/nginx/sites-available/lunarfront ln -sf /etc/nginx/sites-available/lunarfront /etc/nginx/sites-enabled/lunarfront rm -f /etc/nginx/sites-enabled/default nginx -t && systemctl reload nginx echo "" echo "========================================================" echo " Setup complete!" echo "" echo " Next steps:" echo " 1. Verify .env has correct values:" echo " nano ${APP_DIR}/.env" echo " 2. Restart backend after editing .env:" echo " sudo systemctl restart lunarfront" echo " 3. Set up HTTPS (after pointing DNS to this IP):" echo " sudo certbot --nginx -d YOUR_DOMAIN -d www.YOUR_DOMAIN" echo " 4. Check logs:" echo " journalctl -u lunarfront -f" echo "========================================================"