#!/bin/bash # Self-removing recovery: fires whenever a process slot is free. # Kills stray spincraft npm/node, ensures ONE node runs with the socket DB URL, # resets passwords to admin123, then deletes its own cron and marks done. APP=/home/erpsolution26/public_html/spincraft.erpsolution26.com FLAG=$APP/.recovered [ -f "$FLAG" ] && exit 0 # serialize: only one recover runs mkdir "$APP/.recover.lock" 2>/dev/null || exit 0 NODEBIN=/opt/alt/alt-nodejs22/root/usr/bin export PATH=$NODEBIN:$PATH export HOME=/home/erpsolution26 export NODE_ENV=production DBU=erpsolution26_spincraft DBP='y61JTjJiBBNqnwRPJTCg6wJl' DBN=erpsolution26_spincraft { echo "===== RECOVER $(date) =====" echo "-- procs before --"; ps -u erpsolution26 --no-headers | wc -l # free slots pkill -9 -u erpsolution26 -f "npm install" 2>/dev/null pkill -9 -u erpsolution26 -f "npm exec" 2>/dev/null pkill -9 -u erpsolution26 -f "prisma" 2>/dev/null pkill -9 -u erpsolution26 -f "next start" 2>/dev/null pkill -9 -u erpsolution26 -f "next-server" 2>/dev/null sleep 2 echo "-- procs after kill --"; ps -u erpsolution26 --no-headers | wc -l cd "$APP" || { rm -rf "$APP/.recover.lock"; exit 1; } # detect mysql socket SOCK=$(mysql -u "$DBU" -p"$DBP" "$DBN" -N -e "SHOW VARIABLES LIKE 'socket';" 2>/dev/null | awk '{print $2}') # prefer the detected socket; fall back to the standard cPanel socket path, # NOT tcp (tcp is exactly what was broken). if [ -z "$SOCK" ] || [ ! -S "$SOCK" ]; then for cand in /var/lib/mysql/mysql.sock /tmp/mysql.sock /var/run/mysqld/mysqld.sock; do [ -S "$cand" ] && SOCK="$cand" && break done fi URL="mysql://$DBU:$DBP@localhost/$DBN?socket=$SOCK" echo "db url uses socket: ${SOCK:-NONE-FOUND}" cat > .env < admin123 mysql -u "$DBU" -p"$DBP" "$DBN" -e "UPDATE User SET passwordHash='$2a$10$3MgCkAocwuzVcxHjY6GSNOcihoCIDmcfDo.qWroTBaFRhKxxaHpt6';" 2>&1 echo "pw reset rc=$?" # proxy (idempotent) cat > .htaccess <<'HTEOF' RewriteEngine On DirectoryIndex disabled RewriteRule ^/?$ http://127.0.0.1:3100/ [P,L,QSA] RewriteRule ^(.+)$ http://127.0.0.1:3100/$1 [P,L,QSA] PassengerEnabled off HTEOF # start exactly one node : > node.log setsid nohup ./node_modules/.bin/next start -p 3100 >> node.log 2>&1 & echo $! > node.pid echo "node pid $(cat node.pid)" # wait + verify DB path via a real login CODE=000 for i in $(seq 1 30); do sleep 3 CODE=$(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:3100/login 2>/dev/null) [ "$CODE" = "200" ] && break done echo "local /login -> $CODE" LOGIN=$(curl -s -X POST http://127.0.0.1:3100/api/auth/login -H 'Content-Type: application/json' \ --data '{"email":"admin@spincraft.com","password":"admin123"}' -w ' HTTP=%{http_code}') echo "login test: $LOGIN" if echo "$LOGIN" | grep -q 'HTTP=200'; then echo "HEALTHY — installing permanent keepalive + removing recover cron" # permanent keepalive so node auto-restarts if it dies cat > keepalive.sh </dev/null && exit 0 export PATH=$NODEBIN:\$PATH; export HOME=/home/erpsolution26; export NODE_ENV=production setsid nohup ./node_modules/.bin/next start -p 3100 >> node.log 2>&1 & echo \$! > node.pid KAEOF chmod +x keepalive.sh touch "$FLAG" # remove the recover cron line, add keepalive cron crontab -l 2>/dev/null | grep -v 'recover.txt' | { cat; echo "* * * * * /bin/bash $APP/keepalive.sh >/dev/null 2>&1"; } | crontab - echo "cron updated" else echo "NOT healthy yet; leaving recover cron to retry" fi echo "===== DONE $(date) =====" } >> "$APP/recover.log" 2>&1 rm -rf "$APP/.recover.lock"