← back to Homesonspec
pm2(homesonspec): node-direct next start so pm2 owns the port-holder PID (TK-10499)
7d5c17e690c4ea1aa00720a3403eaf77c34e07fc · 2026-08-27 10:23:25 -0700 · Steve
Convert homesonspec-web/admin from 'pnpm --filter ... start' (pm2 owns the
wrapper; orphaned next-server squats the port -> restart EADDRINUSE-crash-loops,
TK-10001 / usre 186519x) to node-direct 'next start -p <port>' in BOTH the
committed ecosystem.config.js and the authoritative deploy-kamatera.sh. Also
correct ecosystem ports 3100/3101 -> real prod 9975/9976. Local source only;
Kamatera re-register is drafted+gated (pending-approval/TK-10499-*).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
M deploy-kamatera.shM ecosystem.config.js
Diff
commit 7d5c17e690c4ea1aa00720a3403eaf77c34e07fc
Author: Steve <steve@designerwallcoverings.com>
Date: Thu Aug 27 10:23:25 2026 -0700
pm2(homesonspec): node-direct next start so pm2 owns the port-holder PID (TK-10499)
Convert homesonspec-web/admin from 'pnpm --filter ... start' (pm2 owns the
wrapper; orphaned next-server squats the port -> restart EADDRINUSE-crash-loops,
TK-10001 / usre 186519x) to node-direct 'next start -p <port>' in BOTH the
committed ecosystem.config.js and the authoritative deploy-kamatera.sh. Also
correct ecosystem ports 3100/3101 -> real prod 9975/9976. Local source only;
Kamatera re-register is drafted+gated (pending-approval/TK-10499-*).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
deploy-kamatera.sh | 9 +++++++--
ecosystem.config.js | 30 ++++++++++++++++++++++--------
2 files changed, 29 insertions(+), 10 deletions(-)
diff --git a/deploy-kamatera.sh b/deploy-kamatera.sh
index 03b03e3a..b36d4dc7 100755
--- a/deploy-kamatera.sh
+++ b/deploy-kamatera.sh
@@ -82,8 +82,13 @@ pm2 delete homesonspec-web homesonspec-admin homesonspec-workers 2>/dev/null ||
# Free the ports from any ORPHANED next-server not managed by pm2 (a stale process squatting
# on :$WEB_PORT/:$ADMIN_PORT makes 'next start' EADDRINUSE-crash-loop forever — TK-10001 incident).
for P in $WEB_PORT $ADMIN_PORT; do fuser -k \$P/tcp 2>/dev/null || true; done; sleep 2
-PORT=$WEB_PORT pm2 start 'pnpm --filter @homesonspec/web start' --name homesonspec-web --time
-PORT=$ADMIN_PORT pm2 start 'pnpm --filter @homesonspec/admin start' --name homesonspec-admin --time
+# node-direct start: pm2 must own the REAL next-server port-holder PID, not a pnpm/sh
+# wrapper. With the wrapper, a pm2 restart signals the wrapper while the orphaned
+# next-server keeps squatting the port -> the respawn EADDRINUSE-crash-loops (TK-10001 /
+# usre 186519x). `next start -p <port>` binds the port itself, so pm2 restart frees it
+# cleanly and the deploy-time fuser -k stops being load-bearing. TK-10499.
+PORT=$WEB_PORT pm2 start apps/web/node_modules/.bin/next --name homesonspec-web --time --cwd $REMOTE/apps/web -- start -p $WEB_PORT
+PORT=$ADMIN_PORT pm2 start apps/admin/node_modules/.bin/next --name homesonspec-admin --time --cwd $REMOTE/apps/admin -- start -p $ADMIN_PORT
cd $REMOTE/apps/workers; pm2 start src/index.ts --name homesonspec-workers --interpreter node --interpreter-args='--env-file=$REMOTE/.env --import tsx' --time
pm2 save; sleep 8
echo -n ' web '; curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:$WEB_PORT/
diff --git a/ecosystem.config.js b/ecosystem.config.js
index 7de9e25d..c1f2d981 100644
--- a/ecosystem.config.js
+++ b/ecosystem.config.js
@@ -2,18 +2,32 @@
module.exports = {
apps: [
{
+ // node-direct so pm2 owns the real next-server port-holder PID (NOT a pnpm/sh
+ // wrapper). Launching via `pnpm --filter ... start` made pm2 own the wrapper;
+ // on crash/restart the orphaned next-server kept squatting :9975 and the
+ // respawn's `next start` EADDRINUSE-crash-looped forever (TK-10001 / usre
+ // 186519x, TK-10496 be669fc). `next start -p <port>` binds the port itself so
+ // `pm2 restart` cleanly frees it. Port 9975/9976 are the REAL prod ports the
+ // nginx vhost proxies to (was mislabeled 3100/3101 here — deploy-kamatera.sh
+ // is authoritative). TK-10499.
name: "homesonspec-web",
- cwd: __dirname,
- script: "pnpm",
- args: "--filter @homesonspec/web start",
- env: { NODE_ENV: "production", PORT: "3100" },
+ cwd: __dirname + "/apps/web",
+ script: "node_modules/.bin/next",
+ args: "start -p 9975",
+ exec_mode: "fork",
+ instances: 1,
+ autorestart: true,
+ env: { NODE_ENV: "production", PORT: "9975" },
},
{
name: "homesonspec-admin",
- cwd: __dirname,
- script: "pnpm",
- args: "--filter @homesonspec/admin start",
- env: { NODE_ENV: "production", PORT: "3101" },
+ cwd: __dirname + "/apps/admin",
+ script: "node_modules/.bin/next",
+ args: "start -p 9976",
+ exec_mode: "fork",
+ instances: 1,
+ autorestart: true,
+ env: { NODE_ENV: "production", PORT: "9976" },
},
{
// tsx-run daemon (pg-boss queue consumer). Unlike the Next apps it does
← 7312ce4b docs(homesonspec): STEP 1 APPLIED on prod — record actual me
·
back to Homesonspec
·
snapshot store: store storagePath relative + resolver for vo 0a7e6b34 →