#!/bin/bash # Configuration SERVER_PORT=5000 CLIENT_PORT=5173 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" resolve_node_toolchain() { # Common install locations when login shell PATH is not loaded if command -v npm >/dev/null 2>&1; then return 0 fi if [ -s "$HOME/.nvm/nvm.sh" ]; then # shellcheck disable=SC1090 . "$HOME/.nvm/nvm.sh" elif [ -s "/usr/local/nvm/nvm.sh" ]; then # shellcheck disable=SC1090 . "/usr/local/nvm/nvm.sh" fi if [ -d "$HOME/.fnm" ] && command -v fnm >/dev/null 2>&1; then eval "$(fnm env)" fi for candidate in \ /usr/local/bin/npm \ /usr/bin/npm \ "$HOME/.local/share/fnm/current/bin/npm" \ "$HOME/.nvm/versions/node/"*/bin/npm; do if [ -x "$candidate" ]; then export PATH="$(dirname "$candidate"):$PATH" break fi done command -v npm >/dev/null 2>&1 } require_node_toolchain() { if resolve_node_toolchain; then echo "Using Node $(node -v), npm $(npm -v)" return 0 fi echo "Error: npm was not found in PATH." echo "" echo "This script starts local Vite/Express dev servers and requires Node.js 20+ with npm." echo "Install Node.js on this machine, or use the Docker-based stack instead:" echo " ./scripts/start-dev-docker.sh" echo "" echo "On the production host, prefer updating the running stack:" echo " docker compose -f docker-compose.yml up -d --build" echo " # or from your workstation: ./scripts/update-prod.sh" exit 1 } echo "========================================" echo " Kapteins Daagbok Dev Environment " echo "========================================" echo "Preparing to (re)start services..." require_node_toolchain # Clean up processes running on ports cleanup_port() { local port=$1 if command -v lsof >/dev/null 2>&1; then local pid=$(lsof -t -i:$port) if [ ! -z "$pid" ]; then echo "Port $port is currently in use by PID $pid. Stopping process..." kill -9 $pid 2>/dev/null fi elif command -v fuser >/dev/null 2>&1; then echo "Port $port is currently in use. Stopping process..." fuser -k $port/tcp 2>/dev/null fi } cleanup_port $SERVER_PORT cleanup_port $CLIENT_PORT # Clean exit handler cleanup_all() { echo "" echo "Stopping all dev servers..." # Kill all child jobs kill $(jobs -p) 2>/dev/null exit 0 } # Trap termination signals trap cleanup_all SIGINT SIGTERM EXIT # Manage PostgreSQL Docker container if command -v docker >/dev/null 2>&1; then echo "Checking PostgreSQL Docker container (postgres-daagbox)..." if docker ps -a --format '{{.Names}}' | grep -Eq "^postgres-daagbox$"; then echo "Found existing postgres-daagbox container. Restarting..." docker restart postgres-daagbox >/dev/null else echo "postgres-daagbox container not found. Creating and starting a new one..." docker run -d \ --name postgres-daagbox \ -p 5432:5432 \ -e POSTGRES_USER=postgres \ -e POSTGRES_PASSWORD=postgres \ -e POSTGRES_DB=daagbox \ postgres:16 >/dev/null fi # Wait for PostgreSQL to be ready echo "Waiting for PostgreSQL database to be ready..." TIMEOUT=15 COUNTER=0 until docker exec postgres-daagbox pg_isready -U postgres >/dev/null 2>&1; do sleep 0.5 COUNTER=$((COUNTER + 1)) if [ $COUNTER -ge 30 ]; then echo "Warning: PostgreSQL did not start within $TIMEOUT seconds. Proceeding anyway..." break fi done if [ $COUNTER -lt 30 ]; then echo "PostgreSQL is ready!" fi else echo "Warning: Docker command not found. Skipping PostgreSQL container management." fi # Start backend server echo "Starting backend API server..." cd "$REPO_ROOT/server" || exit 1 if [ ! -d node_modules ]; then echo "Error: server/node_modules missing. Run: cd server && npm ci" exit 1 fi npm run dev & BACKEND_PID=$! cd "$REPO_ROOT" || exit 1 # Sleep briefly to let server start up sleep 1.5 if ! kill -0 "$BACKEND_PID" 2>/dev/null; then echo "Error: Backend dev server exited immediately. Check server logs above." exit 1 fi # Start frontend client echo "Starting frontend dev server..." cd "$REPO_ROOT/client" || exit 1 if [ ! -d node_modules ]; then echo "Error: client/node_modules missing. Run: cd client && npm ci" kill "$BACKEND_PID" 2>/dev/null exit 1 fi npm run dev & CLIENT_PID=$! cd "$REPO_ROOT" || exit 1 sleep 1.5 if ! kill -0 "$CLIENT_PID" 2>/dev/null; then echo "Error: Frontend dev server exited immediately. Check client logs above." kill "$BACKEND_PID" 2>/dev/null exit 1 fi echo "========================================" echo "Dev services are now running:" echo " -> Backend: http://localhost:$SERVER_PORT" echo " -> Frontend: http://localhost:$CLIENT_PORT" echo "========================================" echo "Press Ctrl+C to terminate both servers." echo "========================================" # Block to keep parent process alive wait