diff --git a/scripts/deploy.sh b/scripts/deploy.sh index 46ee79f..b7b2d61 100755 --- a/scripts/deploy.sh +++ b/scripts/deploy.sh @@ -51,7 +51,7 @@ info() { } # Check root -if [[ $EUID -ne 0 ]]; then +if [[ "${EUID}" -ne 0 ]]; then error "This script must be run as root (use sudo)" fi @@ -74,7 +74,7 @@ if ! command -v node &> /dev/null; then log "✓ Node.js $(node -v) installed successfully" else NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1) - if [ "$NODE_VERSION" -lt 18 ]; then + if [ "${NODE_VERSION}" -lt 18 ]; then warn "Node.js version too old ($(node -v)). Upgrading to 20.x..." curl -fsSL https://deb.nodesource.com/setup_20.x | bash - >> "$LOG_FILE" 2>&1 apt-get install -y nodejs >> "$LOG_FILE" 2>&1 || error "Failed to upgrade Node.js" @@ -100,7 +100,7 @@ if ! command -v pnpm &> /dev/null; then log "✓ pnpm $(pnpm -v) installed successfully" else PNPM_VERSION=$(pnpm -v | cut -d'.' -f1) - if [ "$PNPM_VERSION" -lt 8 ]; then + if [ "${PNPM_VERSION}" -lt 8 ]; then warn "pnpm version too old ($(pnpm -v)). Upgrading to 8.15.0..." npm install -g pnpm@8.15.0 >> "$LOG_FILE" 2>&1 || error "Failed to upgrade pnpm" log "✓ pnpm upgraded to $(pnpm -v)" @@ -154,16 +154,16 @@ fi # Use pnpm for monorepo PKG_MANAGER="pnpm" -log "✓ Package manager: $PKG_MANAGER" +log "✓ Package manager: ${PKG_MANAGER}" # Step 2: Setup PostgreSQL with Docker log "Step 2/8: Setting up PostgreSQL with Docker..." # Stop and remove existing container if exists -if docker ps -a | grep -q $DB_CONTAINER_NAME; then +if docker ps -a | grep -q "${DB_CONTAINER_NAME}"; then log "Removing existing PostgreSQL container..." - docker stop $DB_CONTAINER_NAME 2>/dev/null || true - docker rm $DB_CONTAINER_NAME 2>/dev/null || true + docker stop "${DB_CONTAINER_NAME}" 2>/dev/null || true + docker rm "${DB_CONTAINER_NAME}" 2>/dev/null || true fi # Remove old volume to ensure clean installation @@ -181,41 +181,41 @@ fi # Start PostgreSQL container log "Starting PostgreSQL container..." docker run -d \ - --name $DB_CONTAINER_NAME \ + --name "${DB_CONTAINER_NAME}" \ --network nginx-love-network \ - -e POSTGRES_DB=$DB_NAME \ - -e POSTGRES_USER=$DB_USER \ - -e POSTGRES_PASSWORD=$DB_PASSWORD \ - -p 127.0.0.1:$DB_PORT:5432 \ + -e POSTGRES_DB="${DB_NAME}" \ + -e POSTGRES_USER="${DB_USER}" \ + -e POSTGRES_PASSWORD="${DB_PASSWORD}" \ + -p 127.0.0.1:"${DB_PORT}":5432 \ -v nginx-love-postgres-data:/var/lib/postgresql/data \ --restart unless-stopped \ - postgres:15-alpine >> "$LOG_FILE" 2>&1 || error "Failed to start PostgreSQL container" + postgres:15-alpine >> "${LOG_FILE}" 2>&1 || error "Failed to start PostgreSQL container" # Wait for PostgreSQL to be ready log "Waiting for PostgreSQL to be ready..." sleep 5 for i in {1..30}; do - if docker exec $DB_CONTAINER_NAME pg_isready -U $DB_USER > /dev/null 2>&1; then + if docker exec "${DB_CONTAINER_NAME}" pg_isready -U "${DB_USER}" > /dev/null 2>&1; then log "✓ PostgreSQL is ready" break fi - if [ $i -eq 30 ]; then + if [ "${i}" -eq 30 ]; then error "PostgreSQL failed to start" fi sleep 1 done log "✓ PostgreSQL container started successfully" -log " • Database: $DB_NAME" -log " • User: $DB_USER" -log " • Port: $DB_PORT" +log " • Database: ${DB_NAME}" +log " • User: ${DB_USER}" +log " • Port: ${DB_PORT}" # Step 3: Install Nginx + ModSecurity log "Step 3/8: Installing Nginx + ModSecurity..." if ! command -v nginx &> /dev/null; then info "Nginx not found. Installing..." - bash "$PROJECT_DIR/scripts/install-nginx-modsecurity.sh" || error "Failed to install Nginx + ModSecurity" + bash "${PROJECT_DIR}/scripts/install-nginx-modsecurity.sh" || error "Failed to install Nginx + ModSecurity" log "✓ Nginx + ModSecurity installed" else log "✓ Nginx already installed ($(nginx -v 2>&1 | cut -d'/' -f2))" @@ -225,40 +225,40 @@ fi log "Step 4/8: Setting up Backend..." # Install root dependencies first (for monorepo) -cd "$PROJECT_DIR" +cd "${PROJECT_DIR}" if [ ! -d "node_modules" ]; then log "Installing monorepo dependencies..." - $PKG_MANAGER install >> "$LOG_FILE" 2>&1 || error "Failed to install monorepo dependencies" + "${PKG_MANAGER}" install >> "${LOG_FILE}" 2>&1 || error "Failed to install monorepo dependencies" else log "✓ Monorepo dependencies already installed" fi -cd "$BACKEND_DIR" +cd "${BACKEND_DIR}" # Create backend .env from .env.example (always create fresh) log "Creating fresh backend .env from .env.example..." cat > ".env" <> "$LOG_FILE" 2>&1 || error "Failed to build backend" +cd "${PROJECT_DIR}" +pnpm --filter @nginx-love/api build >> "${LOG_FILE}" 2>&1 || error "Failed to build backend" log "✓ Backend built successfully" # Step 6: Setup Frontend log "Step 6/8: Setting up Frontend..." -cd "$FRONTEND_DIR" +cd "${FRONTEND_DIR}" # Create frontend .env from .env.example (always create fresh) log "Creating fresh frontend .env from .env.example..." cat > ".env" <> "$LOG_FILE" 2>&1 || error "Failed to build frontend" +cd "${PROJECT_DIR}" +pnpm --filter @nginx-love/web build >> "${LOG_FILE}" 2>&1 || error "Failed to build frontend" # Update CSP in built index.html to use public IP log "Updating Content Security Policy with public IP..." -sed -i "s|__API_URL__|http://$PUBLIC_IP:3001 http://localhost:3001|g" "$FRONTEND_DIR/dist/index.html" -sed -i "s|__WS_URL__|ws://$PUBLIC_IP:* ws://localhost:*|g" "$FRONTEND_DIR/dist/index.html" +sed -i "s|__API_URL__|http://${PUBLIC_IP}:3001 http://localhost:3001|g" "${FRONTEND_DIR}/dist/index.html" +sed -i "s|__WS_URL__|ws://${PUBLIC_IP}:* ws://localhost:*|g" "${FRONTEND_DIR}/dist/index.html" log "✓ Frontend built successfully" -log "✓ CSP configured for: http://$PUBLIC_IP:3001, http://localhost:3001" +log "✓ CSP configured for: http://${PUBLIC_IP}:3001, http://localhost:3001" # Step 7: Setup Nginx Configuration log "Step 7/8: Configuring Nginx..." @@ -377,7 +377,7 @@ After=network.target postgresql.service [Service] Type=simple User=root -WorkingDirectory=$BACKEND_DIR +WorkingDirectory=${BACKEND_DIR} Environment=NODE_ENV=production ExecStart=$(which node) dist/index.js Restart=always @@ -398,7 +398,7 @@ After=network.target [Service] Type=simple User=root -WorkingDirectory=$FRONTEND_DIR +WorkingDirectory=${FRONTEND_DIR} Environment=NODE_ENV=production ExecStart=$(which pnpm) preview --host 0.0.0.0 --port 8080 Restart=always @@ -460,31 +460,31 @@ log "Deployment Completed Successfully!" log "==================================" log "" log "📋 Service Status:" -log " • PostgreSQL: Docker container '$DB_CONTAINER_NAME'" -log " • Backend API: http://$PUBLIC_IP:3001" -log " • Frontend UI: http://$PUBLIC_IP:8080" +log " • PostgreSQL: Docker container '${DB_CONTAINER_NAME}'" +log " • Backend API: http://${PUBLIC_IP}:3001" +log " • Frontend UI: http://${PUBLIC_IP}:8080" log " • Nginx: Port 80/443" log "" log "🔐 Database Credentials:" log " • Host: localhost" -log " • Port: $DB_PORT" -log " • Database: $DB_NAME" -log " • Username: $DB_USER" -log " • Password: $DB_PASSWORD" +log " • Port: ${DB_PORT}" +log " • Database: ${DB_NAME}" +log " • Username: ${DB_USER}" +log " • Password: ${DB_PASSWORD}" log "" log "🔑 Security Keys:" -log " • JWT Access Secret: $JWT_ACCESS_SECRET" -log " • JWT Refresh Secret: $JWT_REFRESH_SECRET" -log " • Session Secret: $SESSION_SECRET" +log " • JWT Access Secret: ${JWT_ACCESS_SECRET}" +log " • JWT Refresh Secret: ${JWT_REFRESH_SECRET}" +log " • Session Secret: ${SESSION_SECRET}" log "" log "📝 Manage Services:" -log " PostgreSQL: docker start|stop|restart $DB_CONTAINER_NAME" +log " PostgreSQL: docker start|stop|restart ${DB_CONTAINER_NAME}" log " Backend: systemctl {start|stop|restart|status} nginx-love-backend" log " Frontend: systemctl {start|stop|restart|status} nginx-love-frontend" log " Nginx: systemctl {start|stop|restart|status} nginx" log "" log "📊 View Logs:" -log " PostgreSQL: docker logs -f $DB_CONTAINER_NAME" +log " PostgreSQL: docker logs -f ${DB_CONTAINER_NAME}" log " Backend: tail -f /var/log/nginx-love-backend.log" log " Frontend: tail -f /var/log/nginx-love-frontend.log" log " Nginx: tail -f /var/log/nginx/error.log" @@ -493,7 +493,7 @@ log "🔐 Default Credentials:" log " Username: admin" log " Password: admin123" log "" -log "🌐 Access the portal at: http://$PUBLIC_IP:8080" +log "🌐 Access the portal at: http://${PUBLIC_IP}:8080" log "" # Save credentials to file @@ -502,31 +502,31 @@ cat > /root/.nginx-love-credentials < "$INSTALL_STATUS_FILE" + echo "{\"step\":\"${step}\",\"status\":\"${status}\",\"message\":\"${message}\",\"timestamp\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"}" > "${INSTALL_STATUS_FILE}" } # Error handler @@ -44,7 +44,7 @@ error_exit() { } # Check if running as root -if [[ $EUID -ne 0 ]]; then +if [[ "${EUID}" -ne 0 ]]; then error_exit "This script must be run as root" fi @@ -56,7 +56,7 @@ log "================================================" log "Step 1/8: Installing dependencies..." update_status "dependencies" "running" "Installing required packages..." -apt-get update >> "$INSTALL_LOG" 2>&1 || error_exit "Failed to update package list" +apt-get update >> "${INSTALL_LOG}" 2>&1 || error_exit "Failed to update package list" apt-get install -y \ build-essential \ @@ -77,7 +77,7 @@ apt-get install -y \ autoconf \ git \ wget \ - >> "$INSTALL_LOG" 2>&1 || error_exit "Failed to install dependencies" + >> "${INSTALL_LOG}" 2>&1 || error_exit "Failed to install dependencies" log "Dependencies installed successfully" update_status "dependencies" "completed" "All dependencies installed" @@ -88,7 +88,7 @@ update_status "modsecurity_download" "running" "Downloading ModSecurity..." cd /usr/local/src if [ ! -d "ModSecurity" ]; then - git clone --depth 1 -b v${MODSECURITY_VERSION} --single-branch https://github.com/SpiderLabs/ModSecurity >> "$INSTALL_LOG" 2>&1 || error_exit "Failed to clone ModSecurity" + git clone --depth 1 -b v${MODSECURITY_VERSION} --single-branch https://github.com/SpiderLabs/ModSecurity >> "${INSTALL_LOG}" 2>&1 || error_exit "Failed to clone ModSecurity" fi log "ModSecurity downloaded successfully" @@ -99,12 +99,12 @@ log "Step 3/8: Building ModSecurity..." update_status "modsecurity_build" "running" "Compiling ModSecurity (this may take 10-15 minutes)..." cd ModSecurity -git submodule init >> "$INSTALL_LOG" 2>&1 -git submodule update >> "$INSTALL_LOG" 2>&1 -./build.sh >> "$INSTALL_LOG" 2>&1 || error_exit "Failed to build ModSecurity" -./configure >> "$INSTALL_LOG" 2>&1 || error_exit "Failed to configure ModSecurity" -make -j$(nproc) >> "$INSTALL_LOG" 2>&1 || error_exit "Failed to compile ModSecurity" -make install >> "$INSTALL_LOG" 2>&1 || error_exit "Failed to install ModSecurity" +git submodule init >> "${INSTALL_LOG}" 2>&1 +git submodule update >> "${INSTALL_LOG}" 2>&1 +./build.sh >> "${INSTALL_LOG}" 2>&1 || error_exit "Failed to build ModSecurity" +./configure >> "${INSTALL_LOG}" 2>&1 || error_exit "Failed to configure ModSecurity" +make -j$(nproc) >> "${INSTALL_LOG}" 2>&1 || error_exit "Failed to compile ModSecurity" +make install >> "${INSTALL_LOG}" 2>&1 || error_exit "Failed to install ModSecurity" log "ModSecurity built and installed successfully" update_status "modsecurity_build" "completed" "ModSecurity compiled and installed" @@ -115,7 +115,7 @@ update_status "connector_download" "running" "Downloading ModSecurity-nginx conn cd /usr/local/src if [ ! -d "ModSecurity-nginx" ]; then - git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git >> "$INSTALL_LOG" 2>&1 || error_exit "Failed to clone ModSecurity-nginx" + git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git >> "${INSTALL_LOG}" 2>&1 || error_exit "Failed to clone ModSecurity-nginx" fi log "ModSecurity-nginx connector downloaded" @@ -127,8 +127,8 @@ update_status "nginx_download" "running" "Downloading Nginx..." cd /usr/local/src if [ ! -f "nginx-${NGINX_VERSION}.tar.gz" ]; then - wget http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz >> "$INSTALL_LOG" 2>&1 || error_exit "Failed to download Nginx" - tar -xzf nginx-${NGINX_VERSION}.tar.gz >> "$INSTALL_LOG" 2>&1 || error_exit "Failed to extract Nginx" + wget http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz >> "${INSTALL_LOG}" 2>&1 || error_exit "Failed to download Nginx" + tar -xzf nginx-${NGINX_VERSION}.tar.gz >> "${INSTALL_LOG}" 2>&1 || error_exit "Failed to extract Nginx" fi log "Nginx downloaded successfully" @@ -173,10 +173,10 @@ cd nginx-${NGINX_VERSION} --with-http_slice_module \ --with-file-aio \ --add-dynamic-module=/usr/local/src/ModSecurity-nginx \ - >> "$INSTALL_LOG" 2>&1 || error_exit "Failed to configure Nginx" + >> "${INSTALL_LOG}" 2>&1 || error_exit "Failed to configure Nginx" -make -j$(nproc) >> "$INSTALL_LOG" 2>&1 || error_exit "Failed to compile Nginx" -make install >> "$INSTALL_LOG" 2>&1 || error_exit "Failed to install Nginx" +make -j$(nproc) >> "${INSTALL_LOG}" 2>&1 || error_exit "Failed to compile Nginx" +make install >> "${INSTALL_LOG}" 2>&1 || error_exit "Failed to install Nginx" # Copy ModSecurity dynamic module to nginx modules directory mkdir -p /usr/lib/nginx/modules @@ -191,26 +191,26 @@ log "Step 7/8: Configuring ModSecurity..." update_status "modsecurity_config" "running" "Setting up ModSecurity configuration..." # Create ModSecurity directories -mkdir -p "$MODSECURITY_CONFIG_DIR" +mkdir -p "${MODSECURITY_CONFIG_DIR}" mkdir -p /var/log/modsec # Copy ModSecurity configuration -cp /usr/local/src/ModSecurity/modsecurity.conf-recommended "$MODSECURITY_CONFIG_DIR/modsecurity.conf" -cp /usr/local/src/ModSecurity/unicode.mapping "$MODSECURITY_CONFIG_DIR/" +cp /usr/local/src/ModSecurity/modsecurity.conf-recommended "${MODSECURITY_CONFIG_DIR}/modsecurity.conf" +cp /usr/local/src/ModSecurity/unicode.mapping "${MODSECURITY_CONFIG_DIR}/" # Enable ModSecurity -sed -i 's/SecRuleEngine DetectionOnly/SecRuleEngine On/' "$MODSECURITY_CONFIG_DIR/modsecurity.conf" +sed -i 's/SecRuleEngine DetectionOnly/SecRuleEngine On/' "${MODSECURITY_CONFIG_DIR}/modsecurity.conf" # Download OWASP Core Rule Set -cd "$MODSECURITY_CONFIG_DIR" +cd "${MODSECURITY_CONFIG_DIR}" if [ ! -d "coreruleset" ]; then - git clone https://github.com/coreruleset/coreruleset.git >> "$INSTALL_LOG" 2>&1 + git clone https://github.com/coreruleset/coreruleset.git >> "${INSTALL_LOG}" 2>&1 cd coreruleset mv crs-setup.conf.example crs-setup.conf fi # Create main ModSecurity configuration -cat > "$MODSECURITY_CONFIG_DIR/main.conf" << 'EOF' +cat > "${MODSECURITY_CONFIG_DIR}/main.conf" << 'EOF' Include /etc/nginx/modsec/modsecurity.conf Include /etc/nginx/modsec/coreruleset/crs-setup.conf Include /etc/nginx/modsec/coreruleset/rules/*.conf @@ -370,11 +370,11 @@ EOF # Enable and start nginx systemctl daemon-reload -systemctl enable nginx >> "$INSTALL_LOG" 2>&1 -systemctl start nginx >> "$INSTALL_LOG" 2>&1 +systemctl enable nginx >> "${INSTALL_LOG}" 2>&1 +systemctl start nginx >> "${INSTALL_LOG}" 2>&1 # Test nginx -if nginx -t >> "$INSTALL_LOG" 2>&1; then +if nginx -t >> "${INSTALL_LOG}" 2>&1; then log "Nginx configuration test passed" else error_exit "Nginx configuration test failed" diff --git a/scripts/quickstart.sh b/scripts/quickstart.sh index 6fdd9f4..a4de69f 100755 --- a/scripts/quickstart.sh +++ b/scripts/quickstart.sh @@ -14,9 +14,9 @@ NC='\033[0m' # Paths SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" -BACKEND_DIR="$PROJECT_DIR/apps/api" -FRONTEND_DIR="$PROJECT_DIR/apps/web" +PROJECT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" +BACKEND_DIR="${PROJECT_DIR}/apps/api" +FRONTEND_DIR="${PROJECT_DIR}/apps/web" # Database config DB_NAME="nginx_love_db" @@ -32,13 +32,13 @@ echo "" USE_DOCKER=false if command -v docker &> /dev/null && command -v docker-compose &> /dev/null; then read -p "Use Docker for PostgreSQL? (y/n, default: y): " USE_DOCKER_INPUT - if [ "$USE_DOCKER_INPUT" != "n" ]; then + if [ "${USE_DOCKER_INPUT}" != "n" ]; then USE_DOCKER=true fi fi # Setup PostgreSQL -if [ "$USE_DOCKER" = true ]; then +if [ "${USE_DOCKER}" = true ]; then echo "🐳 Starting PostgreSQL with Docker..." # Stop existing container if any @@ -48,56 +48,56 @@ if [ "$USE_DOCKER" = true ]; then # Start PostgreSQL docker run -d \ --name nginx-love-postgres \ - -e POSTGRES_DB=$DB_NAME \ - -e POSTGRES_USER=$DB_USER \ - -e POSTGRES_PASSWORD=$DB_PASSWORD \ - -p $DB_PORT:5432 \ + -e POSTGRES_DB="${DB_NAME}" \ + -e POSTGRES_USER="${DB_USER}" \ + -e POSTGRES_PASSWORD="${DB_PASSWORD}" \ + -p "${DB_PORT}":5432 \ postgres:15-alpine > /dev/null echo "✅ PostgreSQL started in Docker" echo " Waiting for database to be ready..." sleep 3 - DATABASE_URL="postgresql://$DB_USER:$DB_PASSWORD@localhost:$DB_PORT/$DB_NAME?schema=public" + DATABASE_URL="postgresql://${DB_USER}:${DB_PASSWORD}@localhost:${DB_PORT}/${DB_NAME}?schema=public" else echo "📋 Please ensure PostgreSQL is running and update DATABASE_URL in backend/.env" DATABASE_URL=${DATABASE_URL:-"postgresql://user:password@localhost:5432/nginx_love_db?schema=public"} fi # Create backend .env from .env.example -if [ ! -f "$BACKEND_DIR/.env" ]; then +if [ ! -f "${BACKEND_DIR}/.env" ]; then echo "⚠️ Backend .env not found. Creating from .env.example..." - cp "$BACKEND_DIR/.env.example" "$BACKEND_DIR/.env" + cp "${BACKEND_DIR}/.env.example" "${BACKEND_DIR}/.env" # Replace with actual values - sed -i.bak "s|DATABASE_URL=.*|DATABASE_URL=\"$DATABASE_URL\"|g" "$BACKEND_DIR/.env" - sed -i.bak "s|CORS_ORIGIN=.*|CORS_ORIGIN=\"http://localhost:8080,http://localhost:5173\"|g" "$BACKEND_DIR/.env" - sed -i.bak "s|NODE_ENV=.*|NODE_ENV=development|g" "$BACKEND_DIR/.env" - rm -f "$BACKEND_DIR/.env.bak" + sed -i.bak "s|DATABASE_URL=.*|DATABASE_URL=\"${DATABASE_URL}\"|g" "${BACKEND_DIR}/.env" + sed -i.bak "s|CORS_ORIGIN=.*|CORS_ORIGIN=\"http://localhost:8080,http://localhost:5173\"|g" "${BACKEND_DIR}/.env" + sed -i.bak "s|NODE_ENV=.*|NODE_ENV=development|g" "${BACKEND_DIR}/.env" + rm -f "${BACKEND_DIR}/.env.bak" - echo "✅ Created $BACKEND_DIR/.env" + echo "✅ Created ${BACKEND_DIR}/.env" fi # Create frontend .env from .env.example -if [ ! -f "$FRONTEND_DIR/.env" ]; then +if [ ! -f "${FRONTEND_DIR}/.env" ]; then echo "⚠️ Frontend .env not found. Creating from .env.example..." - cp "$FRONTEND_DIR/.env.example" "$FRONTEND_DIR/.env" + cp "${FRONTEND_DIR}/.env.example" "${FRONTEND_DIR}/.env" # Replace with actual values - sed -i.bak "s|VITE_API_URL=.*|VITE_API_URL=http://localhost:3001/api|g" "$FRONTEND_DIR/.env" - sed -i.bak "s|VITE_DEMO_MODE=.*|VITE_DEMO_MODE=true|g" "$FRONTEND_DIR/.env" - rm -f "$FRONTEND_DIR/.env.bak" + sed -i.bak "s|VITE_API_URL=.*|VITE_API_URL=http://localhost:3001/api|g" "${FRONTEND_DIR}/.env" + sed -i.bak "s|VITE_DEMO_MODE=.*|VITE_DEMO_MODE=true|g" "${FRONTEND_DIR}/.env" + rm -f "${FRONTEND_DIR}/.env.bak" - echo "✅ Created $FRONTEND_DIR/.env" + echo "✅ Created ${FRONTEND_DIR}/.env" fi # Install dependencies echo "📦 Installing dependencies..." -cd "$PROJECT_DIR" && pnpm install +cd "${PROJECT_DIR}" && pnpm install # Setup database echo "🗄️ Setting up database..." -cd "$BACKEND_DIR" +cd "${BACKEND_DIR}" pnpm prisma:generate pnpm exec prisma migrate deploy pnpm prisma:seed 2>/dev/null || echo "Database already seeded" @@ -107,20 +107,20 @@ echo "🎯 Starting services..." echo "" # Start backend in background -cd "$BACKEND_DIR" && pnpm dev > /tmp/backend.log 2>&1 & +cd "${BACKEND_DIR}" && pnpm dev > /tmp/backend.log 2>&1 & BACKEND_PID=$! -echo "✅ Backend started (PID: $BACKEND_PID) - http://localhost:3001" +echo "✅ Backend started (PID: ${BACKEND_PID}) - http://localhost:3001" # Store the process group ID for better signal handling -BACKEND_PGID=$(ps -o pgid= -p $BACKEND_PID | tr -d ' ') +BACKEND_PGID=$(ps -o pgid= -p "${BACKEND_PID}" | tr -d ' ') # Start frontend in background -cd "$FRONTEND_DIR" && pnpm dev > /tmp/frontend.log 2>&1 & +cd "${FRONTEND_DIR}" && pnpm dev > /tmp/frontend.log 2>&1 & FRONTEND_PID=$! -echo "✅ Frontend started (PID: $FRONTEND_PID) - http://localhost:8080" +echo "✅ Frontend started (PID: ${FRONTEND_PID}) - http://localhost:8080" # Store the process group ID for better signal handling -FRONTEND_PGID=$(ps -o pgid= -p $FRONTEND_PID | tr -d ' ') +FRONTEND_PGID=$(ps -o pgid= -p "${FRONTEND_PID}" | tr -d ' ') echo "" echo "================================" @@ -140,10 +140,10 @@ echo " Backend: tail -f /tmp/backend.log" echo " Frontend: tail -f /tmp/frontend.log" echo "" echo "🛑 Stop:" -if [ "$USE_DOCKER" = true ]; then - echo " kill $BACKEND_PID $FRONTEND_PID && docker stop nginx-love-postgres" +if [ "${USE_DOCKER}" = true ]; then + echo " kill ${BACKEND_PID} ${FRONTEND_PID} && docker stop nginx-love-postgres" else - echo " kill $BACKEND_PID $FRONTEND_PID" + echo " kill ${BACKEND_PID} ${FRONTEND_PID}" fi echo "" @@ -169,19 +169,19 @@ cleanup() { # Method 1: Kill by port (most reliable for Node.js processes) echo "🔍 Stopping backend on port 3001..." BACKEND_PORT_PIDS=$(lsof -ti:3001 2>/dev/null) - if [ -n "$BACKEND_PORT_PIDS" ]; then - echo "🔍 Found backend processes: $BACKEND_PORT_PIDS" - for pid in $BACKEND_PORT_PIDS; do + if [ -n "${BACKEND_PORT_PIDS}" ]; then + echo "🔍 Found backend processes: ${BACKEND_PORT_PIDS}" + for pid in ${BACKEND_PORT_PIDS}; do # Get the full command to verify it's our Node.js process - CMD=$(ps -p $pid -o cmd= 2>/dev/null) - if [[ "$CMD" == *"node"* ]]; then - echo "🔍 Stopping Node.js process $pid..." - kill -TERM $pid 2>/dev/null + CMD=$(ps -p "${pid}" -o cmd= 2>/dev/null) + if [[ "${CMD}" == *"node"* ]]; then + echo "🔍 Stopping Node.js process ${pid}..." + kill -TERM "${pid}" 2>/dev/null sleep 1 # Check if still running and force kill if needed - if kill -0 $pid 2>/dev/null; then + if kill -0 "${pid}" 2>/dev/null; then echo "🔍 Process still running, sending SIGKILL..." - kill -KILL $pid 2>/dev/null + kill -KILL "${pid}" 2>/dev/null fi fi done @@ -190,50 +190,50 @@ cleanup() { echo "🔍 Stopping frontend on port 8080..." FRONTEND_PORT_PIDS=$(lsof -ti:8080 2>/dev/null) - if [ -n "$FRONTEND_PORT_PIDS" ]; then - for pid in $FRONTEND_PORT_PIDS; do - kill -TERM $pid 2>/dev/null + if [ -n "${FRONTEND_PORT_PIDS}" ]; then + for pid in ${FRONTEND_PORT_PIDS}; do + kill -TERM "${pid}" 2>/dev/null sleep 1 - if kill -0 $pid 2>/dev/null; then - kill -KILL $pid 2>/dev/null + if kill -0 "${pid}" 2>/dev/null; then + kill -KILL "${pid}" 2>/dev/null fi done echo "✅ Frontend on port 8080 stopped" fi # Method 2: Kill process groups (as backup) - if [ -n "$BACKEND_PGID" ]; then - echo "🔍 Stopping backend process group (PGID: $BACKEND_PGID)..." - kill -TERM -$BACKEND_PGID 2>/dev/null + if [ -n "${BACKEND_PGID}" ]; then + echo "🔍 Stopping backend process group (PGID: ${BACKEND_PGID})..." + kill -TERM -"${BACKEND_PGID}" 2>/dev/null sleep 1 - if kill -0 -$BACKEND_PGID 2>/dev/null; then - kill -KILL -$BACKEND_PGID 2>/dev/null + if kill -0 -"${BACKEND_PGID}" 2>/dev/null; then + kill -KILL -"${BACKEND_PGID}" 2>/dev/null fi fi - if [ -n "$FRONTEND_PGID" ]; then - echo "🔍 Stopping frontend process group (PGID: $FRONTEND_PGID)..." - kill -TERM -$FRONTEND_PGID 2>/dev/null + if [ -n "${FRONTEND_PGID}" ]; then + echo "🔍 Stopping frontend process group (PGID: ${FRONTEND_PGID})..." + kill -TERM -"${FRONTEND_PGID}" 2>/dev/null sleep 1 - if kill -0 -$FRONTEND_PGID 2>/dev/null; then - kill -KILL -$FRONTEND_PGID 2>/dev/null + if kill -0 -"${FRONTEND_PGID}" 2>/dev/null; then + kill -KILL -"${FRONTEND_PGID}" 2>/dev/null fi fi # Method 3: Kill parent PIDs (as final backup) - if [ -n "$BACKEND_PID" ]; then - kill -TERM $BACKEND_PID 2>/dev/null + if [ -n "${BACKEND_PID}" ]; then + kill -TERM "${BACKEND_PID}" 2>/dev/null sleep 1 - if kill -0 $BACKEND_PID 2>/dev/null; then - kill -KILL $BACKEND_PID 2>/dev/null + if kill -0 "${BACKEND_PID}" 2>/dev/null; then + kill -KILL "${BACKEND_PID}" 2>/dev/null fi fi - if [ -n "$FRONTEND_PID" ]; then - kill -TERM $FRONTEND_PID 2>/dev/null + if [ -n "${FRONTEND_PID}" ]; then + kill -TERM "${FRONTEND_PID}" 2>/dev/null sleep 1 - if kill -0 $FRONTEND_PID 2>/dev/null; then - kill -KILL $FRONTEND_PID 2>/dev/null + if kill -0 "${FRONTEND_PID}" 2>/dev/null; then + kill -KILL "${FRONTEND_PID}" 2>/dev/null fi fi @@ -241,21 +241,21 @@ cleanup() { sleep 1 REMAINING_BACKEND=$(lsof -ti:3001 2>/dev/null) REMAINING_FRONTEND=$(lsof -ti:8080 2>/dev/null) - if [ -n "$REMAINING_BACKEND" ] || [ -n "$REMAINING_FRONTEND" ]; then + if [ -n "${REMAINING_BACKEND}" ] || [ -n "${REMAINING_FRONTEND}" ]; then echo "⚠️ Warning: Some processes still running:" - [ -n "$REMAINING_BACKEND" ] && echo " Backend on port 3001: $REMAINING_BACKEND" - [ -n "$REMAINING_FRONTEND" ] && echo " Frontend on port 8080: $REMAINING_FRONTEND" + [ -n "${REMAINING_BACKEND}" ] && echo " Backend on port 3001: ${REMAINING_BACKEND}" + [ -n "${REMAINING_FRONTEND}" ] && echo " Frontend on port 8080: ${REMAINING_FRONTEND}" echo "🔍 Force killing all remaining processes..." - for pid in $REMAINING_BACKEND; do - kill -KILL $pid 2>/dev/null + for pid in ${REMAINING_BACKEND}; do + kill -KILL "${pid}" 2>/dev/null done - for pid in $REMAINING_FRONTEND; do - kill -KILL $pid 2>/dev/null + for pid in ${REMAINING_FRONTEND}; do + kill -KILL "${pid}" 2>/dev/null done fi # Stop Docker PostgreSQL if used - if [ "$USE_DOCKER" = true ]; then + if [ "${USE_DOCKER}" = true ]; then docker stop nginx-love-postgres 2>/dev/null && echo "✅ PostgreSQL stopped" fi diff --git a/scripts/start.sh b/scripts/start.sh index 875fb93..6160596 100755 --- a/scripts/start.sh +++ b/scripts/start.sh @@ -15,22 +15,22 @@ NC='\033[0m' # No Color # Paths SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" -BACKEND_DIR="$PROJECT_DIR/apps/api" -FRONTEND_DIR="$PROJECT_DIR/apps/web" +PROJECT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" +BACKEND_DIR="${PROJECT_DIR}/apps/api" +FRONTEND_DIR="${PROJECT_DIR}/apps/web" # Check if backend directory exists -if [ ! -d "$BACKEND_DIR" ]; then - echo "❌ Backend directory not found at $BACKEND_DIR!" +if [ ! -d "${BACKEND_DIR}" ]; then + echo "❌ Backend directory not found at ${BACKEND_DIR}!" exit 1 fi echo -e "${BLUE}📦 Installing dependencies...${NC}" -cd "$PROJECT_DIR" && pnpm install +cd "${PROJECT_DIR}" && pnpm install echo "" echo -e "${BLUE}🗄️ Setting up database...${NC}" -cd "$BACKEND_DIR" +cd "${BACKEND_DIR}" pnpm prisma:generate pnpm exec prisma migrate deploy pnpm prisma:seed @@ -59,22 +59,22 @@ echo "🚀 Starting services..." echo "================================================" echo "" echo -e "${YELLOW}Starting backend on port 3001...${NC}" -cd "$BACKEND_DIR" +cd "${BACKEND_DIR}" pnpm dev & BACKEND_PID=$! # Store the process group ID for better signal handling -BACKEND_PGID=$(ps -o pgid= -p $BACKEND_PID | tr -d ' ') +BACKEND_PGID=$(ps -o pgid= -p "${BACKEND_PID}" | tr -d ' ') sleep 3 echo -e "${YELLOW}Starting frontend on port 5173...${NC}" -cd "$FRONTEND_DIR" +cd "${FRONTEND_DIR}" pnpm dev & FRONTEND_PID=$! # Store the process group ID for better signal handling -FRONTEND_PGID=$(ps -o pgid= -p $FRONTEND_PID | tr -d ' ') +FRONTEND_PGID=$(ps -o pgid= -p "${FRONTEND_PID}" | tr -d ' ') echo "" echo "================================================" @@ -95,19 +95,19 @@ cleanup() { # Method 1: Kill by port (most reliable for Node.js processes) echo "🔍 Stopping backend on port 3001..." BACKEND_PORT_PIDS=$(lsof -ti:3001 2>/dev/null) - if [ -n "$BACKEND_PORT_PIDS" ]; then - echo "🔍 Found backend processes: $BACKEND_PORT_PIDS" - for pid in $BACKEND_PORT_PIDS; do + if [ -n "${BACKEND_PORT_PIDS}" ]; then + echo "🔍 Found backend processes: ${BACKEND_PORT_PIDS}" + for pid in ${BACKEND_PORT_PIDS}; do # Get the full command to verify it's our Node.js process - CMD=$(ps -p $pid -o cmd= 2>/dev/null) - if [[ "$CMD" == *"node"* ]]; then - echo "🔍 Stopping Node.js process $pid..." - kill -TERM $pid 2>/dev/null + CMD=$(ps -p "${pid}" -o cmd= 2>/dev/null) + if [[ "${CMD}" == *"node"* ]]; then + echo "🔍 Stopping Node.js process ${pid}..." + kill -TERM "${pid}" 2>/dev/null sleep 1 # Check if still running and force kill if needed - if kill -0 $pid 2>/dev/null; then + if kill -0 "${pid}" 2>/dev/null; then echo "🔍 Process still running, sending SIGKILL..." - kill -KILL $pid 2>/dev/null + kill -KILL "${pid}" 2>/dev/null fi fi done @@ -116,61 +116,61 @@ cleanup() { echo "🔍 Stopping frontend on port 5173..." FRONTEND_PORT_PIDS=$(lsof -ti:5173 2>/dev/null) - if [ -n "$FRONTEND_PORT_PIDS" ]; then - for pid in $FRONTEND_PORT_PIDS; do - kill -TERM $pid 2>/dev/null + if [ -n "${FRONTEND_PORT_PIDS}" ]; then + for pid in ${FRONTEND_PORT_PIDS}; do + kill -TERM "${pid}" 2>/dev/null sleep 1 - if kill -0 $pid 2>/dev/null; then - kill -KILL $pid 2>/dev/null + if kill -0 "${pid}" 2>/dev/null; then + kill -KILL "${pid}" 2>/dev/null fi done echo "✅ Frontend on port 5173 stopped" fi # Method 2: Kill process groups (as backup) - if [ -n "$BACKEND_PGID" ]; then - echo "🔍 Stopping backend process group (PGID: $BACKEND_PGID)..." - kill -TERM -$BACKEND_PGID 2>/dev/null + if [ -n "${BACKEND_PGID}" ]; then + echo "🔍 Stopping backend process group (PGID: ${BACKEND_PGID})..." + kill -TERM -"${BACKEND_PGID}" 2>/dev/null sleep 1 - if kill -0 -$BACKEND_PGID 2>/dev/null; then - kill -KILL -$BACKEND_PGID 2>/dev/null + if kill -0 -"${BACKEND_PGID}" 2>/dev/null; then + kill -KILL -"${BACKEND_PGID}" 2>/dev/null fi fi - if [ -n "$FRONTEND_PGID" ]; then - echo "🔍 Stopping frontend process group (PGID: $FRONTEND_PGID)..." - kill -TERM -$FRONTEND_PGID 2>/dev/null + if [ -n "${FRONTEND_PGID}" ]; then + echo "🔍 Stopping frontend process group (PGID: ${FRONTEND_PGID})..." + kill -TERM -"${FRONTEND_PGID}" 2>/dev/null sleep 1 - if kill -0 -$FRONTEND_PGID 2>/dev/null; then - kill -KILL -$FRONTEND_PGID 2>/dev/null + if kill -0 -"${FRONTEND_PGID}" 2>/dev/null; then + kill -KILL -"${FRONTEND_PGID}" 2>/dev/null fi fi # Method 3: Kill parent PIDs (as final backup) - if [ -n "$BACKEND_PID" ]; then - kill -TERM $BACKEND_PID 2>/dev/null + if [ -n "${BACKEND_PID}" ]; then + kill -TERM "${BACKEND_PID}" 2>/dev/null sleep 1 - if kill -0 $BACKEND_PID 2>/dev/null; then - kill -KILL $BACKEND_PID 2>/dev/null + if kill -0 "${BACKEND_PID}" 2>/dev/null; then + kill -KILL "${BACKEND_PID}" 2>/dev/null fi fi - if [ -n "$FRONTEND_PID" ]; then - kill -TERM $FRONTEND_PID 2>/dev/null + if [ -n "${FRONTEND_PID}" ]; then + kill -TERM "${FRONTEND_PID}" 2>/dev/null sleep 1 - if kill -0 $FRONTEND_PID 2>/dev/null; then - kill -KILL $FRONTEND_PID 2>/dev/null + if kill -0 "${FRONTEND_PID}" 2>/dev/null; then + kill -KILL "${FRONTEND_PID}" 2>/dev/null fi fi # Final verification sleep 1 REMAINING_BACKEND=$(lsof -ti:3001 2>/dev/null) - if [ -n "$REMAINING_BACKEND" ]; then - echo "⚠️ Warning: Some processes still running on port 3001: $REMAINING_BACKEND" + if [ -n "${REMAINING_BACKEND}" ]; then + echo "⚠️ Warning: Some processes still running on port 3001: ${REMAINING_BACKEND}" echo "🔍 Force killing all remaining processes..." - for pid in $REMAINING_BACKEND; do - kill -KILL $pid 2>/dev/null + for pid in ${REMAINING_BACKEND}; do + kill -KILL "${pid}" 2>/dev/null done fi @@ -182,4 +182,4 @@ cleanup() { trap cleanup SIGINT SIGTERM # Wait for user to stop -wait $BACKEND_PID $FRONTEND_PID \ No newline at end of file +wait "${BACKEND_PID}" "${FRONTEND_PID}" \ No newline at end of file