a restarted process kept an environment the ecosystem file no longer had

startProcess used 'pm2 start <name>' for a process PM2 already knew, which
restarts it with the environment PM2 is holding and never re-reads the file. That
was harmless while an entry was a script path and a cwd. It stopped being
harmless the moment entries carried env.

Seen once, immediately: a plugin's allocated port was re-drawn, the installer
wrote PORT_SITE=34507 into ecosystem.config.cjs, the sidecar went on serving 3011,
and nothing anywhere reported the disagreement. The file and the process simply
disagreed, silently, which is the exact failure the port mechanism was supposed
to remove rather than introduce.

Now it restarts THROUGH the file - 'restart <file> --only <name> --update-env'.
The file is re-read, and --update-env replaces the stored environment rather than
merging into it, so a variable removed from an entry actually goes away.
This commit is contained in:
2026-09-06 11:00:19 +01:00
parent d9110c373d
commit f31aeb4f6e
+17 -1
View File
@@ -59,7 +59,23 @@ export async function isKnownToPm2(name: string, cwd: string): Promise<boolean>
*/ */
export async function startProcess(name: string, cwd: string): Promise<Pm2Result> { export async function startProcess(name: string, cwd: string): Promise<Pm2Result> {
const known = await isKnownToPm2(name, cwd); const known = await isKnownToPm2(name, cwd);
const args = known ? ['start', name] : ['start', ECOSYSTEM, '--only', name]; /*
Through the ECOSYSTEM FILE either way, and that is the whole point of this line.
`pm2 start <name>` restarts a known process with the environment PM2 already holds for it, and never
looks at the file again. That was fine while an entry was just a script path — it is not now that an
entry carries `env`, because a plugin whose allocated port changed would have its new number written
to the file and go on running with the old one.
Seen exactly once, on the day ports were added: the ecosystem said PORT_SITE=34507, the process was
serving 3011, and nothing anywhere reported a disagreement.
`restart <file> --only <name>` re-reads the entry; `--update-env` makes PM2 replace the stored
environment rather than merge into it, so a variable REMOVED from the entry actually goes away.
*/
const args = known
? ['restart', ECOSYSTEM, '--only', name, '--update-env']
: ['start', ECOSYSTEM, '--only', name];
const { code, out } = await pm2(args, cwd); const { code, out } = await pm2(args, cwd);
if (code !== 0) return { ok: false, error: out || `pm2 ${args.join(' ')} exited ${code}` }; if (code !== 0) return { ok: false, error: out || `pm2 ${args.join(' ')} exited ${code}` };