fix(deploy): free PORT before PM2 start to clear EADDRINUSE orphans

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
SimoandCursor committed 2026-07-30 18:40:42 +02:00
1 parent 749dc237f1
commit 540bce911f
1 file changed
+24 -4
+24 -4
View File
@@ -381,16 +381,35 @@ jobs:
# Next.js prefers an already-set process PORT over .env. PM2 may still
# have PORT=3000 from an older start, while .env (and nginx) expect 3002.
# Export PORT before reload so --update-env aligns the running process.
# Export PORT before start so the process matches health checks.
DEPLOY_PORT="$(grep -E '^[[:space:]]*PORT=' "${LIVE}/.env" 2>/dev/null | tail -1 | cut -d= -f2- || true)"
DEPLOY_PORT="$(printf '%s' "${DEPLOY_PORT}" | tr -cd '0-9')"
DEPLOY_PORT="${DEPLOY_PORT:-3002}"
export PORT="${DEPLOY_PORT}"
echo "PM2/health PORT=${PORT}"
echo "Starting PM2 (zero-downtime reload)..."
free_tcp_port() {
local port="$1"
[ -n "${port}" ] || return 0
if command -v fuser >/dev/null 2>&1; then
fuser -k "${port}/tcp" 2>/dev/null || true
elif command -v lsof >/dev/null 2>&1; then
# Portable fallback when fuser is unavailable.
lsof -tiTCP:"${port}" -sTCP:LISTEN 2>/dev/null | xargs -r kill -9 2>/dev/null || true
fi
}
echo "Starting PM2 with a clean PORT=${PORT} listener..."
cd "${LIVE}"
pm2 reload next --update-env || pm2 start pnpm --name next --update-env -- start
# Cutover already stopped the app, but failed deploys can leave orphans
# on 3002 (or an old PM2 env still bound to 3000).
pm2 stop next --kill-timeout 10000 2>/dev/null || true
free_tcp_port "${PORT}"
free_tcp_port 3000
sleep 1
pm2 delete next 2>/dev/null || true
PORT="${PORT}" pm2 start pnpm --name next -- start
pm2 save 2>/dev/null || true
sleep 3
if ! pm2 show next 2>/dev/null | grep -q 'online'; then
@@ -415,7 +434,8 @@ jobs:
if [ "${HEALTH_OK}" != "1" ]; then
echo "ERROR: Health check failed after deploy (${HEALTH_URL})" >&2
echo "Last body: ${BODY:-<empty>}" >&2
echo "PM2 env PORT (should match .env):" >&2
echo "Listeners on PORT ${PORT}:" >&2
ss -tlnp 2>/dev/null | grep ":${PORT} " >&2 || netstat -tlnp 2>/dev/null | grep ":${PORT} " >&2 || true
pm2 env 0 2>/dev/null | grep -E '^PORT=' >&2 || true
pm2 logs next --lines 40 --nostream >&2 || true
exit 1