#!/bin/bash # Tool_OCR - Unified Development Server Startup Script # Usage: # ./start.sh Start all services (backend + frontend) # ./start.sh backend Start only backend # ./start.sh frontend Start only frontend # ./start.sh --stop Stop all services # ./start.sh --status Show service status # ./start.sh --help Show help set -e # Colors GREEN='\033[0;32m' YELLOW='\033[1;33m' RED='\033[0;31m' BLUE='\033[0;34m' NC='\033[0m' # Configuration SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PID_DIR="$SCRIPT_DIR/.pid" BACKEND_PID_FILE="$PID_DIR/backend.pid" FRONTEND_PID_FILE="$PID_DIR/frontend.pid" BACKEND_PORT=${BACKEND_PORT:-8000} FRONTEND_PORT=${FRONTEND_PORT:-5173} # Create PID directory mkdir -p "$PID_DIR" # Functions print_header() { echo "" echo -e "${BLUE}================================${NC}" echo -e "${BLUE} Tool_OCR Development Server${NC}" echo -e "${BLUE}================================${NC}" echo "" } show_help() { echo "Tool_OCR - Development Server Manager" echo "" echo "Usage: ./start.sh [command]" echo "" echo "Commands:" echo " (none) Start all services (backend + frontend)" echo " backend Start only backend service" echo " frontend Start only frontend service" echo " --stop Stop all running services" echo " --status Show status of services" echo " --help Show this help message" echo "" echo "Examples:" echo " ./start.sh # Start everything" echo " ./start.sh backend # Start only backend" echo " ./start.sh --stop # Stop all services" echo "" } check_requirements() { local missing=0 # Check virtual environment if [ ! -d "$SCRIPT_DIR/venv" ]; then echo -e "${RED}Error: Python virtual environment not found${NC}" echo "Please run: ./setup_dev_env.sh" missing=1 fi # Check node_modules if [ ! -d "$SCRIPT_DIR/frontend/node_modules" ]; then echo -e "${RED}Error: Frontend dependencies not found${NC}" echo "Please run: ./setup_dev_env.sh" missing=1 fi # Check .env.local if [ ! -f "$SCRIPT_DIR/.env.local" ]; then echo -e "${RED}Error: .env.local not found${NC}" echo "Please copy .env.example to .env.local and configure" missing=1 fi return $missing } is_running() { local pid_file=$1 if [ -f "$pid_file" ]; then local pid=$(cat "$pid_file") if ps -p "$pid" > /dev/null 2>&1; then return 0 else # PID file exists but process is not running, clean up rm -f "$pid_file" fi fi return 1 } get_pid() { local pid_file=$1 if [ -f "$pid_file" ]; then cat "$pid_file" fi } start_backend() { if is_running "$BACKEND_PID_FILE"; then echo -e "${YELLOW}Backend already running (PID: $(get_pid $BACKEND_PID_FILE))${NC}" return 0 fi echo -e "${GREEN}Starting backend server...${NC}" # Activate virtual environment source "$SCRIPT_DIR/venv/bin/activate" # Load environment variables if [ -f "$SCRIPT_DIR/.env.local" ]; then export $(grep -v '^#' "$SCRIPT_DIR/.env.local" | xargs) fi # Start backend in background cd "$SCRIPT_DIR/backend" # Create necessary directories mkdir -p uploads/{temp,processed,images} mkdir -p storage/{markdown,json,exports,results} mkdir -p models/paddleocr mkdir -p logs # Start uvicorn nohup uvicorn app.main:app --reload --host 0.0.0.0 --port $BACKEND_PORT > "$SCRIPT_DIR/.pid/backend.log" 2>&1 & local pid=$! echo $pid > "$BACKEND_PID_FILE" cd "$SCRIPT_DIR" # Wait a moment and verify sleep 2 if is_running "$BACKEND_PID_FILE"; then echo -e "${GREEN}Backend started (PID: $pid)${NC}" echo -e " API Docs: http://localhost:$BACKEND_PORT/docs" echo -e " Health: http://localhost:$BACKEND_PORT/health" else echo -e "${RED}Backend failed to start. Check .pid/backend.log${NC}" return 1 fi } start_frontend() { if is_running "$FRONTEND_PID_FILE"; then echo -e "${YELLOW}Frontend already running (PID: $(get_pid $FRONTEND_PID_FILE))${NC}" return 0 fi echo -e "${GREEN}Starting frontend server...${NC}" # Load nvm export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" cd "$SCRIPT_DIR/frontend" # Start vite in background nohup npm run dev > "$SCRIPT_DIR/.pid/frontend.log" 2>&1 & local pid=$! echo $pid > "$FRONTEND_PID_FILE" cd "$SCRIPT_DIR" # Wait a moment and verify sleep 3 if is_running "$FRONTEND_PID_FILE"; then echo -e "${GREEN}Frontend started (PID: $pid)${NC}" echo -e " URL: http://localhost:$FRONTEND_PORT" else echo -e "${RED}Frontend failed to start. Check .pid/frontend.log${NC}" return 1 fi } stop_service() { local name=$1 local pid_file=$2 if is_running "$pid_file"; then local pid=$(get_pid "$pid_file") echo -e "${YELLOW}Stopping $name (PID: $pid)...${NC}" # Try graceful shutdown first kill -TERM "$pid" 2>/dev/null || true # Wait up to 5 seconds local count=0 while [ $count -lt 5 ] && is_running "$pid_file"; do sleep 1 count=$((count + 1)) done # Force kill if still running if is_running "$pid_file"; then kill -9 "$pid" 2>/dev/null || true fi rm -f "$pid_file" echo -e "${GREEN}$name stopped${NC}" else echo -e "${YELLOW}$name is not running${NC}" fi } stop_all() { echo -e "${YELLOW}Stopping all services...${NC}" stop_service "Backend" "$BACKEND_PID_FILE" stop_service "Frontend" "$FRONTEND_PID_FILE" echo -e "${GREEN}All services stopped${NC}" } show_status() { echo -e "${BLUE}Service Status:${NC}" echo "" if is_running "$BACKEND_PID_FILE"; then local pid=$(get_pid "$BACKEND_PID_FILE") echo -e " Backend: ${GREEN}Running${NC} (PID: $pid)" echo -e " http://localhost:$BACKEND_PORT" else echo -e " Backend: ${RED}Stopped${NC}" fi if is_running "$FRONTEND_PID_FILE"; then local pid=$(get_pid "$FRONTEND_PID_FILE") echo -e " Frontend: ${GREEN}Running${NC} (PID: $pid)" echo -e " http://localhost:$FRONTEND_PORT" else echo -e " Frontend: ${RED}Stopped${NC}" fi echo "" } # Main case "${1:-all}" in --help|-h) show_help ;; --stop) stop_all ;; --status) show_status ;; backend) print_header check_requirements || exit 1 start_backend echo "" echo -e "${YELLOW}Press Ctrl+C to stop (or use ./start.sh --stop)${NC}" echo -e "${YELLOW}Logs: tail -f .pid/backend.log${NC}" ;; frontend) print_header check_requirements || exit 1 start_frontend echo "" echo -e "${YELLOW}Press Ctrl+C to stop (or use ./start.sh --stop)${NC}" echo -e "${YELLOW}Logs: tail -f .pid/frontend.log${NC}" ;; all|"") print_header check_requirements || exit 1 start_backend start_frontend echo "" echo -e "${GREEN}================================${NC}" echo -e "${GREEN}All services started!${NC}" echo -e "${GREEN}================================${NC}" echo "" echo "Access the application:" echo -e " Frontend: ${BLUE}http://localhost:$FRONTEND_PORT${NC}" echo -e " API Docs: ${BLUE}http://localhost:$BACKEND_PORT/docs${NC}" echo "" echo -e "${YELLOW}Use ./start.sh --stop to stop all services${NC}" echo -e "${YELLOW}Use ./start.sh --status to check status${NC}" echo "" echo "Logs:" echo " Backend: tail -f .pid/backend.log" echo " Frontend: tail -f .pid/frontend.log" ;; *) echo -e "${RED}Unknown command: $1${NC}" show_help exit 1 ;; esac