#!/bin/bash set -euo pipefail # Phase 6, Plan 1: Standalone Server Start Script # Usage: ./start_server.sh # Purpose: Start backend and frontend servers without Docker # Requirements: Python 3.12+, Node.js 20+, and dependencies installed # Color output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; } log_info "=== TFM aInventory Standalone Server Start ===" # ============================================================================ # STEP 1: Pre-flight checks # ============================================================================ log_info "Step 1/7: Running pre-flight checks..." # Check Python version command -v python3 &> /dev/null || log_error "Python 3 not installed" PYTHON_VERSION=$(python3 --version 2>&1 | awk '{print $2}') log_success " ✓ Python $PYTHON_VERSION found" # Check Node.js version command -v node &> /dev/null || log_error "Node.js not installed" NODE_VERSION=$(node --version) log_success " ✓ Node.js $NODE_VERSION found" # Check required files [[ -f "inventory.env" ]] || log_error "inventory.env not found. Copy from inventory.env.template" log_success " ✓ inventory.env found" [[ -d "backend" ]] || log_error "backend/ directory not found" log_success " ✓ backend/ directory found" [[ -d "frontend" ]] || log_error "frontend/ directory not found" log_success " ✓ frontend/ directory found" # ============================================================================ # STEP 2: Load environment # ============================================================================ log_info "Step 2/7: Loading environment configuration..." source inventory.env BACKEND_PORT=${BACKEND_PORT:-8000} FRONTEND_PORT=${FRONTEND_PORT:-3000} DATA_DIR=${DATA_DIR:-./data} LOGS_DIR=${LOGS_DIR:-./logs} LOG_LEVEL=${LOG_LEVEL:-INFO} log_success " ✓ Environment loaded (Backend: $BACKEND_PORT, Frontend: $FRONTEND_PORT)" # ============================================================================ # STEP 3: Prepare directories # ============================================================================ log_info "Step 3/7: Preparing data and log directories..." mkdir -p "$DATA_DIR" "$LOGS_DIR" mkdir -p "$DATA_DIR/temp" chmod -R 755 "$DATA_DIR" "$LOGS_DIR" log_success " ✓ Directories ready" # ============================================================================ # STEP 4: Check port availability # ============================================================================ log_info "Step 4/7: Checking port availability..." for port in $BACKEND_PORT $FRONTEND_PORT; do if command -v netstat &> /dev/null; then if netstat -tuln 2>/dev/null | grep -q ":$port "; then log_error "Port $port is already in use. Stop the application using it or change the port." fi else log_warn " netstat not available; skipping port check" fi done log_success " ✓ Required ports are available" # ============================================================================ # STEP 5: Start backend server # ============================================================================ log_info "Step 5/7: Starting backend API server..." # Create backend log file BACKEND_LOG="$LOGS_DIR/backend.log" touch "$BACKEND_LOG" # Start backend in background cd backend || log_error "Failed to enter backend directory" if [[ ! -f "requirements.txt" ]]; then log_error "backend/requirements.txt not found" fi # Create and use Python virtual environment in project root VENV_DIR=".venv" if [[ ! -d "$VENV_DIR" ]]; then log_info " Creating Python virtual environment..." cd - > /dev/null || true # Return to project root python3 -m venv "$VENV_DIR" || log_error "Failed to create virtual environment" cd backend || log_error "Failed to enter backend directory" fi # Activate virtual environment (from project root) source "../$VENV_DIR/bin/activate" # Install dependencies if needed if ! python3 -c "import fastapi" &> /dev/null; then log_info " Installing Python dependencies..." pip install -q -r requirements.txt || log_error "Failed to install backend dependencies" fi # Initialize database if needed if [[ ! -f "../$DATA_DIR/inventory.db" ]]; then log_info " Initializing database..." python3 -c "from db_manager import init_db; init_db()" || true fi # Start uvicorn in background (with proper working directory) log_info " Starting uvicorn server..." (cd "$(pwd)" && python3 -m uvicorn main:app --host 0.0.0.0 --port "$BACKEND_PORT" --log-level "${LOG_LEVEL,,}" >> "$BACKEND_LOG" 2>&1) & BACKEND_PID=$! log_success " ✓ Backend started (PID: $BACKEND_PID, Port: $BACKEND_PORT)" cd - > /dev/null || true # ============================================================================ # STEP 6: Start frontend server # ============================================================================ log_info "Step 6/7: Starting frontend web server..." FRONTEND_LOG="$LOGS_DIR/frontend.log" touch "$FRONTEND_LOG" cd frontend || log_error "Failed to enter frontend directory" if [[ ! -f "package.json" ]]; then log_error "frontend/package.json not found" fi # Install dependencies if needed if [[ ! -d "node_modules" ]]; then log_info " Installing npm dependencies..." npm ci --silent || log_error "Failed to install frontend dependencies" fi # Build Next.js if not already built if [[ ! -d ".next" ]]; then log_info " Building Next.js application..." npm run build || log_error "Failed to build frontend" fi # Start Next.js in production mode (with proper working directory) log_info " Starting Next.js server..." FRONTEND_DIR="$(pwd)" (cd "$FRONTEND_DIR" && PORT="$FRONTEND_PORT" node .next/standalone/server.js >> "$FRONTEND_LOG" 2>&1) & FRONTEND_PID=$! log_success " ✓ Frontend started (PID: $FRONTEND_PID, Port: $FRONTEND_PORT)" cd - > /dev/null || true # ============================================================================ # STEP 7: Verify services # ============================================================================ log_info "Step 7/7: Verifying services..." # Wait a few seconds for services to start sleep 3 # Check backend if curl -sf "http://localhost:${BACKEND_PORT}/health" &> /dev/null; then log_success " ✓ Backend API responding at http://localhost:${BACKEND_PORT}/health" else log_warn " Backend not responding yet; it may still be initializing" fi # Check frontend if curl -sf "http://localhost:${FRONTEND_PORT}/" &> /dev/null; then log_success " ✓ Frontend responding at http://localhost:${FRONTEND_PORT}" else log_warn " Frontend not responding yet; it may still be initializing" fi # ============================================================================ # Summary and instructions # ============================================================================ echo "" echo -e "${GREEN}╔════════════════════════════════════════════════════════════╗${NC}" echo -e "${GREEN}║${NC} Standalone servers started successfully! ${GREEN}║${NC}" echo -e "${GREEN}╚════════════════════════════════════════════════════════════╝${NC}" echo "" echo "Access points:" echo " Frontend: http://localhost:${FRONTEND_PORT}" echo " Backend: http://localhost:${BACKEND_PORT}" echo " API Docs: http://localhost:${BACKEND_PORT}/docs" echo "" echo "Process IDs:" echo " Backend: $BACKEND_PID" echo " Frontend: $FRONTEND_PID" echo "" echo "Log files:" echo " Backend: $BACKEND_LOG" echo " Frontend: $FRONTEND_LOG" echo "" echo "Monitoring:" echo " Backend: tail -f $BACKEND_LOG" echo " Frontend: tail -f $FRONTEND_LOG" echo " All logs: tail -f $LOGS_DIR/*.log" echo "" echo "To stop servers:" echo " kill $BACKEND_PID $FRONTEND_PID" echo "" log_success "Servers are running!" # Keep script running indefinitely and handle signals trap "log_info 'Received interrupt signal'; kill $BACKEND_PID $FRONTEND_PID 2>/dev/null || true; exit 0" SIGINT SIGTERM # Monitor processes - restart if they crash while true; do if ! kill -0 $BACKEND_PID 2>/dev/null; then log_warn "Backend process died (PID $BACKEND_PID), monitoring stopped" fi if ! kill -0 $FRONTEND_PID 2>/dev/null; then log_warn "Frontend process died (PID $FRONTEND_PID), monitoring stopped" fi sleep 5 done