#!/bin/bash # Start both backend and frontend services for SBA gameplay testing # Enhanced with pre-flight checks, health monitoring, and version logging set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" LOG_DIR="$SCRIPT_DIR/logs" # Default configuration BACKEND_PORT=8000 FRONTEND_PORT=3000 BACKEND_HOST="0.0.0.0" FRONTEND_HOST="0.0.0.0" HEALTH_CHECK_HOST="localhost" # For curl health checks # Environment mode (affects .env file used) ENV_MODE="dev" # dev, prod, or custom # Parse arguments FORCE_START=false FRONTEND_TYPE="sba" # Default to SBA frontend while [[ $# -gt 0 ]]; do case $1 in --force|-f) FORCE_START=true shift ;; --frontend) FRONTEND_TYPE="$2" shift 2 ;; --pd) FRONTEND_TYPE="pd" shift ;; --dev) ENV_MODE="dev" shift ;; --prod) ENV_MODE="prod" shift ;; --backend-port) BACKEND_PORT="$2" shift 2 ;; --frontend-port) FRONTEND_PORT="$2" shift 2 ;; --help|-h) echo "Usage: $0 [OPTIONS]" echo "" echo "Options:" echo " --force, -f Force start (stop existing services first)" echo " --frontend TYPE Start specific frontend (sba or pd)" echo " --pd Shortcut for --frontend pd" echo " --dev Development mode - use localhost URLs (default)" echo " --prod Production mode - use .env production URLs" echo " --backend-port N Override backend port (default: 8000)" echo " --frontend-port N Override frontend port (default: 3000)" echo " --help, -h Show this help message" echo "" echo "Environment Modes:" echo " --dev Sets NUXT_PUBLIC_API_URL=http://localhost:8000" echo " Sets NUXT_PUBLIC_WS_URL=http://localhost:8000" echo "" echo " --prod Uses URLs from frontend-{sba,pd}/.env file" echo " (e.g., https://gameplay-demo.manticorum.com)" exit 0 ;; *) echo "Unknown option: $1" exit 1 ;; esac done # Validate frontend type if [[ "$FRONTEND_TYPE" != "sba" && "$FRONTEND_TYPE" != "pd" ]]; then echo "❌ Invalid frontend type: $FRONTEND_TYPE (must be 'sba' or 'pd')" exit 1 fi FRONTEND_DIR="$SCRIPT_DIR/frontend-$FRONTEND_TYPE" # Create logs directory if it doesn't exist mkdir -p "$LOG_DIR" echo "========================================" echo "🚀 Starting SBA Gameplay Services" echo "========================================" echo "" # ============================================ # PRE-FLIGHT CHECKS # ============================================ echo "🔍 Pre-flight checks..." # Check dependencies check_dependency() { if ! command -v "$1" &> /dev/null; then echo "❌ Required tool not found: $1" echo " Please install $1 before running this script." exit 1 fi } check_dependency "uv" check_dependency "npm" check_dependency "curl" echo " ✓ Dependencies available (uv, npm, curl)" # Check if frontend directory exists if [ ! -d "$FRONTEND_DIR" ]; then echo "❌ Frontend directory not found: $FRONTEND_DIR" exit 1 fi echo " ✓ Frontend directory exists: frontend-$FRONTEND_TYPE" # Check if already running ALREADY_RUNNING=false if [ -f "$LOG_DIR/backend.pid" ]; then EXISTING_PID=$(cat "$LOG_DIR/backend.pid") if ps -p "$EXISTING_PID" > /dev/null 2>&1; then ALREADY_RUNNING=true echo " ⚠️ Backend already running (PID: $EXISTING_PID)" fi fi if [ -f "$LOG_DIR/frontend.pid" ]; then EXISTING_PID=$(cat "$LOG_DIR/frontend.pid") if ps -p "$EXISTING_PID" > /dev/null 2>&1; then ALREADY_RUNNING=true echo " ⚠️ Frontend already running (PID: $EXISTING_PID)" fi fi if [ "$ALREADY_RUNNING" = true ]; then if [ "$FORCE_START" = true ]; then echo " → Force flag set, stopping existing services..." "$SCRIPT_DIR/stop-services.sh" echo "" else echo "" echo "❌ Services already running. Use --force to restart or run ./stop-services.sh first." exit 1 fi fi # Check port availability check_port() { local port=$1 local name=$2 if lsof -ti :"$port" > /dev/null 2>&1; then echo " ⚠️ Port $port is in use ($name)" if [ "$FORCE_START" = true ]; then echo " → Force flag set, killing processes on port $port..." lsof -ti :"$port" | xargs kill -9 2>/dev/null || true sleep 1 else echo "" echo "❌ Port $port is in use. Use --force to kill existing processes." exit 1 fi fi } check_port $BACKEND_PORT "backend" check_port $FRONTEND_PORT "frontend" echo " ✓ Ports $BACKEND_PORT and $FRONTEND_PORT available" echo "" # ============================================ # VERSION LOGGING (helps debug deployment issues) # ============================================ echo "📌 Version Info:" GIT_COMMIT=$(git -C "$SCRIPT_DIR" rev-parse --short HEAD 2>/dev/null || echo "unknown") GIT_BRANCH=$(git -C "$SCRIPT_DIR" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown") GIT_DIRTY=$(git -C "$SCRIPT_DIR" diff --quiet 2>/dev/null && echo "" || echo " (dirty)") TIMESTAMP=$(date -Iseconds) echo " Branch: $GIT_BRANCH" echo " Commit: $GIT_COMMIT$GIT_DIRTY" echo " Started: $TIMESTAMP" # Log to file for debugging cat > "$LOG_DIR/startup.log" << EOF ======================================== Service Startup Log ======================================== Timestamp: $TIMESTAMP Git Branch: $GIT_BRANCH Git Commit: $GIT_COMMIT$GIT_DIRTY Environment: $ENV_MODE Frontend: $FRONTEND_TYPE Backend Port: $BACKEND_PORT Frontend Port: $FRONTEND_PORT ======================================== EOF echo "" # ============================================ # START BACKEND # ============================================ echo "📡 Starting Backend (FastAPI + Socket.io)..." cd "$SCRIPT_DIR/backend" uv run python -m app.main > "$LOG_DIR/backend.log" 2>&1 & BACKEND_PID=$! echo "$BACKEND_PID" > "$LOG_DIR/backend.pid" echo " PID: $BACKEND_PID" echo " Log: $LOG_DIR/backend.log" # Health check with timeout echo " Waiting for backend to be ready..." HEALTH_TIMEOUT=30 HEALTH_COUNT=0 BACKEND_READY=false while [ $HEALTH_COUNT -lt $HEALTH_TIMEOUT ]; do # Check if process is still running if ! ps -p $BACKEND_PID > /dev/null 2>&1; then echo "" echo "❌ Backend process died during startup!" echo " Check logs: tail -50 $LOG_DIR/backend.log" tail -20 "$LOG_DIR/backend.log" 2>/dev/null || true exit 1 fi # Check health endpoint if curl -s http://$HEALTH_CHECK_HOST:$BACKEND_PORT/health > /dev/null 2>&1; then BACKEND_READY=true break fi # Also accept root endpoint as fallback if curl -s http://$HEALTH_CHECK_HOST:$BACKEND_PORT/ > /dev/null 2>&1; then BACKEND_READY=true break fi sleep 1 HEALTH_COUNT=$((HEALTH_COUNT + 1)) printf "." done echo "" if [ "$BACKEND_READY" = true ]; then echo " ✓ Backend ready (${HEALTH_COUNT}s)" echo " URL: http://localhost:$BACKEND_PORT" else echo " ⚠️ Backend health check timed out after ${HEALTH_TIMEOUT}s" echo " Backend may still be starting. Check logs if issues occur." fi echo "" # ============================================ # START FRONTEND # ============================================ echo "🎨 Starting Frontend (Nuxt 3 - $FRONTEND_TYPE)..." cd "$FRONTEND_DIR" # Set environment variables based on mode if [ "$ENV_MODE" = "dev" ]; then echo " Mode: Development (localhost)" export NUXT_PUBLIC_API_URL="http://localhost:$BACKEND_PORT" export NUXT_PUBLIC_WS_URL="http://localhost:$BACKEND_PORT" export NUXT_PUBLIC_DISCORD_REDIRECT_URI="http://localhost:$FRONTEND_PORT/auth/callback" elif [ "$ENV_MODE" = "prod" ]; then echo " Mode: Production (using .env file)" # Load .env file if it exists (Nuxt will use these) if [ -f ".env" ]; then # Show what URLs will be used API_URL=$(grep "^NUXT_PUBLIC_API_URL=" .env 2>/dev/null | cut -d= -f2 || echo "not set") echo " API URL: $API_URL" else echo " ⚠️ No .env file found - using Nuxt defaults" fi fi npm run dev > "$LOG_DIR/frontend.log" 2>&1 & FRONTEND_PID=$! echo "$FRONTEND_PID" > "$LOG_DIR/frontend.pid" echo " PID: $FRONTEND_PID" echo " Log: $LOG_DIR/frontend.log" # Wait for frontend to be ready echo " Waiting for frontend to be ready..." FRONTEND_TIMEOUT=60 FRONTEND_COUNT=0 FRONTEND_READY=false while [ $FRONTEND_COUNT -lt $FRONTEND_TIMEOUT ]; do # Check if process is still running if ! ps -p $FRONTEND_PID > /dev/null 2>&1; then echo "" echo "❌ Frontend process died during startup!" echo " Check logs: tail -50 $LOG_DIR/frontend.log" tail -20 "$LOG_DIR/frontend.log" 2>/dev/null || true exit 1 fi # Check if frontend is responding if curl -s http://$HEALTH_CHECK_HOST:$FRONTEND_PORT > /dev/null 2>&1; then FRONTEND_READY=true break fi sleep 1 FRONTEND_COUNT=$((FRONTEND_COUNT + 1)) printf "." done echo "" if [ "$FRONTEND_READY" = true ]; then echo " ✓ Frontend ready (${FRONTEND_COUNT}s)" echo " URL: http://localhost:$FRONTEND_PORT" else echo " ⚠️ Frontend health check timed out after ${FRONTEND_TIMEOUT}s" echo " Frontend may still be compiling. Check logs if issues occur." fi echo "" # ============================================ # SUMMARY # ============================================ echo "========================================" echo "✅ Services Started Successfully!" echo "========================================" echo "" echo "📊 Service Status:" echo " Backend: http://localhost:$BACKEND_PORT (PID: $BACKEND_PID)" echo " Frontend: http://localhost:$FRONTEND_PORT (PID: $FRONTEND_PID)" echo "" # Show API URL based on mode if [ "$ENV_MODE" = "dev" ]; then echo "🔗 API Configuration (dev mode):" echo " API URL: http://localhost:$BACKEND_PORT" echo " WS URL: http://localhost:$BACKEND_PORT" elif [ "$ENV_MODE" = "prod" ]; then echo "🔗 API Configuration (prod mode):" if [ -f "$FRONTEND_DIR/.env" ]; then grep "^NUXT_PUBLIC_API_URL=" "$FRONTEND_DIR/.env" 2>/dev/null | sed 's/^/ /' || true grep "^NUXT_PUBLIC_WS_URL=" "$FRONTEND_DIR/.env" 2>/dev/null | sed 's/^/ /' || true fi fi echo "" echo "📋 Quick Commands:" echo " View logs: tail -f $LOG_DIR/backend.log" echo " tail -f $LOG_DIR/frontend.log" echo " Check status: ./status-services.sh" echo " Stop: ./stop-services.sh" echo " Restart: ./stop-services.sh && ./start-services.sh" echo "" echo "📌 Running: $GIT_BRANCH @ $GIT_COMMIT$GIT_DIRTY ($ENV_MODE mode)" echo ""