feat(F-054): completed feature
This commit is contained in:
@@ -15,6 +15,7 @@ FRONTEND_PORT="${FRONTEND_PORT:-3003}"
|
||||
ADMIN_PORT="${ADMIN_PORT:-3004}"
|
||||
STOREFRONT_PORT="${STOREFRONT_PORT:-3005}"
|
||||
START_TIMEOUT="${START_TIMEOUT:-90}"
|
||||
WATCH_INTERVAL="${WATCH_INTERVAL:-5}"
|
||||
|
||||
SERVICES=(backend frontend admin storefront)
|
||||
|
||||
@@ -29,6 +30,7 @@ Commands:
|
||||
stop Gracefully stop every managed HTTP process
|
||||
logs Follow all service logs (Ctrl-C exits without stopping services)
|
||||
urls Print localhost and LAN URLs
|
||||
watch Auto-respawn any dead service every WATCH_INTERVAL seconds
|
||||
|
||||
Environment overrides:
|
||||
LAN_IP, BACKEND_PORT, FRONTEND_PORT, ADMIN_PORT, STOREFRONT_PORT
|
||||
@@ -41,7 +43,7 @@ if [[ "$MODE" != "dev" && "$MODE" != "prod" ]]; then
|
||||
exit 2
|
||||
fi
|
||||
case "$ACTION" in
|
||||
start|restart|status|stop|logs|urls) ;;
|
||||
start|restart|status|stop|logs|urls|watch) ;;
|
||||
*) usage >&2; exit 2 ;;
|
||||
esac
|
||||
|
||||
@@ -238,28 +240,28 @@ spawn_service() {
|
||||
|
||||
case "$MODE:$service" in
|
||||
dev:backend)
|
||||
(cd "$dir" && nohup env HOST=0.0.0.0 PORT="$port" NODE_ENV=development node --env-file=.env node_modules/tsx/dist/cli.mjs watch src/infrastructure/http/server.ts >"$log" 2>&1 & echo $! >"$pidfile")
|
||||
(cd "$dir" && nohup env HOST=0.0.0.0 PORT="$port" NODE_ENV=development node --env-file=.env node_modules/tsx/dist/cli.mjs watch src/infrastructure/http/server.ts >"$log" 2>&1 < /dev/null & disown; echo $! >"$pidfile")
|
||||
;;
|
||||
prod:backend)
|
||||
(cd "$dir" && nohup env HOST=0.0.0.0 PORT="$port" NODE_ENV=production node --env-file=.env dist/infrastructure/http/server.js >"$log" 2>&1 & echo $! >"$pidfile")
|
||||
(cd "$dir" && nohup env HOST=0.0.0.0 PORT="$port" NODE_ENV=production node --env-file=.env dist/infrastructure/http/server.js >"$log" 2>&1 < /dev/null & disown; echo $! >"$pidfile")
|
||||
;;
|
||||
dev:admin)
|
||||
(cd "$PROJECT_DIR/apps/admin" && nohup env NEXT_PUBLIC_API_URL="$API_PUBLIC_URL" node node_modules/next/dist/bin/next dev --hostname 0.0.0.0 --port "$port" >"$log" 2>&1 & echo $! >"$pidfile")
|
||||
(cd "$PROJECT_DIR/apps/admin" && nohup env NEXT_PUBLIC_API_URL="$API_PUBLIC_URL" node node_modules/next/dist/bin/next dev --hostname 0.0.0.0 --port "$port" >"$log" 2>&1 < /dev/null & disown; echo $! >"$pidfile")
|
||||
;;
|
||||
prod:admin)
|
||||
(cd "$PROJECT_DIR/apps/admin" && nohup env NEXT_PUBLIC_API_URL="$API_PUBLIC_URL" node node_modules/next/dist/bin/next start --hostname 0.0.0.0 --port "$port" >"$log" 2>&1 & echo $! >"$pidfile")
|
||||
(cd "$PROJECT_DIR/apps/admin" && nohup env NEXT_PUBLIC_API_URL="$API_PUBLIC_URL" node node_modules/next/dist/bin/next start --hostname 0.0.0.0 --port "$port" >"$log" 2>&1 < /dev/null & disown; echo $! >"$pidfile")
|
||||
;;
|
||||
dev:frontend)
|
||||
(cd "$PROJECT_DIR/frontend" && nohup env NEXT_PUBLIC_API_URL="$API_PUBLIC_URL" node node_modules/next/dist/bin/next dev --hostname 0.0.0.0 --port "$port" >"$log" 2>&1 & echo $! >"$pidfile")
|
||||
(cd "$PROJECT_DIR/frontend" && nohup env NEXT_PUBLIC_API_URL="$API_PUBLIC_URL" node node_modules/next/dist/bin/next dev --hostname 0.0.0.0 --port "$port" >"$log" 2>&1 < /dev/null & disown; echo $! >"$pidfile")
|
||||
;;
|
||||
prod:frontend)
|
||||
(cd "$PROJECT_DIR/frontend" && nohup env NEXT_PUBLIC_API_URL="$API_PUBLIC_URL" node node_modules/next/dist/bin/next start --hostname 0.0.0.0 --port "$port" >"$log" 2>&1 & echo $! >"$pidfile")
|
||||
(cd "$PROJECT_DIR/frontend" && nohup env NEXT_PUBLIC_API_URL="$API_PUBLIC_URL" node node_modules/next/dist/bin/next start --hostname 0.0.0.0 --port "$port" >"$log" 2>&1 < /dev/null & disown; echo $! >"$pidfile")
|
||||
;;
|
||||
dev:storefront)
|
||||
(cd "$PROJECT_DIR/storefront" && nohup env API_BASE_URL="$API_PUBLIC_URL" NEXT_PUBLIC_API_URL="$API_PUBLIC_URL" node node_modules/next/dist/bin/next dev --hostname 0.0.0.0 --port "$port" >"$log" 2>&1 & echo $! >"$pidfile")
|
||||
(cd "$PROJECT_DIR/storefront" && nohup env API_BASE_URL="$API_PUBLIC_URL" NEXT_PUBLIC_API_URL="$API_PUBLIC_URL" node node_modules/next/dist/bin/next dev --hostname 0.0.0.0 --port "$port" >"$log" 2>&1 < /dev/null & disown; echo $! >"$pidfile")
|
||||
;;
|
||||
prod:storefront)
|
||||
(cd "$PROJECT_DIR/storefront" && nohup env API_BASE_URL="$API_PUBLIC_URL" NEXT_PUBLIC_API_URL="$API_PUBLIC_URL" node node_modules/next/dist/bin/next start --hostname 0.0.0.0 --port "$port" >"$log" 2>&1 & echo $! >"$pidfile")
|
||||
(cd "$PROJECT_DIR/storefront" && nohup env API_BASE_URL="$API_PUBLIC_URL" NEXT_PUBLIC_API_URL="$API_PUBLIC_URL" node node_modules/next/dist/bin/next start --hostname 0.0.0.0 --port "$port" >"$log" 2>&1 < /dev/null & disown; echo $! >"$pidfile")
|
||||
;;
|
||||
esac
|
||||
sleep 1
|
||||
@@ -319,6 +321,7 @@ stop_all() {
|
||||
}
|
||||
|
||||
status_all() {
|
||||
ensure_alive silent
|
||||
local service pid state code url lan_url failed=0
|
||||
printf '%-11s %-8s %-10s %-6s %s\n' SERVICE PID PROCESS HTTP URL
|
||||
for service in "${SERVICES[@]}"; do
|
||||
@@ -338,6 +341,38 @@ status_all() {
|
||||
return "$failed"
|
||||
}
|
||||
|
||||
# ensure_alive [silent|verbose]
|
||||
# Re-spawn any service whose tracked PID is not running. Used by `status`
|
||||
# so an operator who runs `monolith.sh status` always sees live processes
|
||||
# even after a backend crash with no error trace.
|
||||
ensure_alive() {
|
||||
local verbose="${1:-silent}" service pid
|
||||
[[ "$verbose" == "verbose" ]] || verbose='silent'
|
||||
for service in "${SERVICES[@]}"; do
|
||||
pid="$(read_pid "$service")"
|
||||
if [[ -n "$pid" ]] && kill -0 "$pid" 2>/dev/null; then
|
||||
continue
|
||||
fi
|
||||
if [[ "$verbose" == "verbose" ]]; then
|
||||
echo "[WATCHDOG] $service not running (last PID: ${pid:-none}); respawning..."
|
||||
fi
|
||||
rm -f "$(pid_file "$service")"
|
||||
# Only respawn if infrastructure is reachable; otherwise let `start` handle it.
|
||||
if (cd "$PROJECT_DIR" && docker ps --format '{{.Names}}' 2>/dev/null | grep -qE '^(mdv-dev-postgres|mdv-dev-redis)$'); then
|
||||
spawn_service "$service" || true
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
watch_loop() {
|
||||
echo "[WATCHDOG] watching services every ${WATCH_INTERVAL}s (Ctrl+C to stop)"
|
||||
ensure_alive verbose
|
||||
while true; do
|
||||
sleep "$WATCH_INTERVAL"
|
||||
ensure_alive verbose
|
||||
done
|
||||
}
|
||||
|
||||
print_urls() {
|
||||
cat <<EOF
|
||||
Mode: $MODE
|
||||
@@ -369,4 +404,5 @@ case "$ACTION" in
|
||||
stop) stop_all ;;
|
||||
logs) follow_logs ;;
|
||||
urls) print_urls ;;
|
||||
watch) watch_loop ;;
|
||||
esac
|
||||
|
||||
Reference in New Issue
Block a user