feat(start.sh): add stop and restart commands to manage services

Allows stopping/restarting services when ports are already in use,
with PID tracking, lsof fallback, and SIGKILL escalation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-02-15 00:24:05 +00:00
parent e21cf03a16
commit 07cc58908f

152
start.sh
View File

@@ -4,54 +4,132 @@ set -e
PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)" PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)"
BACKEND_DIR="$PROJECT_DIR/backend" BACKEND_DIR="$PROJECT_DIR/backend"
FRONTEND_DIR="$PROJECT_DIR/frontend" FRONTEND_DIR="$PROJECT_DIR/frontend"
PID_FILE="$PROJECT_DIR/.pids"
# Colors # Colors
GREEN='\033[0;32m' GREEN='\033[0;32m'
YELLOW='\033[1;33m' YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' NC='\033[0m'
cleanup() { BACKEND_PORT=8000
echo -e "\n${YELLOW}Stopping services...${NC}" FRONTEND_PORT=5173
kill $BACKEND_PID $FRONTEND_PID 2>/dev/null
wait $BACKEND_PID $FRONTEND_PID 2>/dev/null stop_services() {
echo -e "${GREEN}Done.${NC}" echo -e "${YELLOW}Stopping services...${NC}"
local stopped=0
# Kill by PID file first
if [ -f "$PID_FILE" ]; then
while read -r pid; do
if kill -0 "$pid" 2>/dev/null; then
kill "$pid" 2>/dev/null && stopped=1
echo -e " Killed process $pid (from PID file)"
fi
done < "$PID_FILE"
rm -f "$PID_FILE"
fi
# Kill anything still on our ports
for port in $BACKEND_PORT $FRONTEND_PORT; do
local pids
pids=$(lsof -ti :"$port" 2>/dev/null || true)
if [ -n "$pids" ]; then
for pid in $pids; do
kill "$pid" 2>/dev/null && stopped=1
echo -e " Killed process $pid on port $port"
done
fi
done
# Wait a moment for ports to free up
if [ "$stopped" -eq 1 ]; then
sleep 1
fi
# Verify ports are free
local still_busy=0
for port in $BACKEND_PORT $FRONTEND_PORT; do
if lsof -ti :"$port" >/dev/null 2>&1; then
echo -e "${RED} Port $port still in use! Sending SIGKILL...${NC}"
kill -9 $(lsof -ti :"$port") 2>/dev/null || true
still_busy=1
fi
done
[ "$still_busy" -eq 1 ] && sleep 1
echo -e "${GREEN}Services stopped.${NC}"
} }
trap cleanup EXIT
# Backend setup start_services() {
echo -e "${GREEN}[Backend] Setting up...${NC}" # Check if ports are busy
if [ ! -d "$BACKEND_DIR/venv" ]; then for port in $BACKEND_PORT $FRONTEND_PORT; do
python3 -m venv "$BACKEND_DIR/venv" if lsof -ti :"$port" >/dev/null 2>&1; then
source "$BACKEND_DIR/venv/bin/activate" echo -e "${RED}Port $port is already in use!${NC}"
pip install -q -r "$BACKEND_DIR/requirements.txt" echo -e "${YELLOW}Use '$0 restart' to restart or '$0 stop' to stop first.${NC}"
else exit 1
source "$BACKEND_DIR/venv/bin/activate" fi
fi done
# Seed DB if empty # Backend setup
if [ ! -f "$BACKEND_DIR/space_booking.db" ]; then echo -e "${GREEN}[Backend] Setting up...${NC}"
echo -e "${GREEN}[Backend] Seeding database...${NC}" if [ ! -d "$BACKEND_DIR/venv" ]; then
cd "$BACKEND_DIR" && python seed_db.py python3 -m venv "$BACKEND_DIR/venv"
fi source "$BACKEND_DIR/venv/bin/activate"
pip install -q -r "$BACKEND_DIR/requirements.txt"
else
source "$BACKEND_DIR/venv/bin/activate"
fi
echo -e "${GREEN}[Backend] Starting on :8000${NC}" # Seed DB if empty
cd "$BACKEND_DIR" && uvicorn app.main:app --reload --host 0.0.0.0 --port 8000 & if [ ! -f "$BACKEND_DIR/space_booking.db" ]; then
BACKEND_PID=$! echo -e "${GREEN}[Backend] Seeding database...${NC}"
cd "$BACKEND_DIR" && python seed_db.py
fi
# Frontend setup echo -e "${GREEN}[Backend] Starting on :${BACKEND_PORT}${NC}"
echo -e "${GREEN}[Frontend] Setting up...${NC}" cd "$BACKEND_DIR" && uvicorn app.main:app --reload --host 0.0.0.0 --port $BACKEND_PORT &
if [ ! -d "$FRONTEND_DIR/node_modules" ]; then BACKEND_PID=$!
cd "$FRONTEND_DIR" && npm install --silent
fi
echo -e "${GREEN}[Frontend] Starting on :5173${NC}" # Frontend setup
cd "$FRONTEND_DIR" && npm run dev -- --host 0.0.0.0 & echo -e "${GREEN}[Frontend] Setting up...${NC}"
FRONTEND_PID=$! if [ ! -d "$FRONTEND_DIR/node_modules" ]; then
cd "$FRONTEND_DIR" && npm install --silent
fi
echo -e "\n${GREEN}=== Space Booking Running ===${NC}" echo -e "${GREEN}[Frontend] Starting on :${FRONTEND_PORT}${NC}"
echo -e " Backend: http://localhost:8000" cd "$FRONTEND_DIR" && npm run dev -- --host 0.0.0.0 &
echo -e " Frontend: http://localhost:5173" FRONTEND_PID=$!
echo -e " API Docs: http://localhost:8000/docs"
echo -e "${YELLOW} Press Ctrl+C to stop${NC}\n"
wait # Save PIDs
echo "$BACKEND_PID" > "$PID_FILE"
echo "$FRONTEND_PID" >> "$PID_FILE"
echo -e "\n${GREEN}=== Space Booking Running ===${NC}"
echo -e " Backend: http://localhost:${BACKEND_PORT}"
echo -e " Frontend: http://localhost:${FRONTEND_PORT}"
echo -e " API Docs: http://localhost:${BACKEND_PORT}/docs"
echo -e "${YELLOW} Press Ctrl+C to stop${NC}\n"
trap 'stop_services; exit 0' EXIT INT TERM
wait
}
# --- Main ---
case "${1:-start}" in
start)
start_services
;;
stop)
stop_services
;;
restart)
stop_services
echo ""
start_services
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
;;
esac