feat(pm2): update PM2 configuration and introduce new start script
Deploy to Raspberry Pi / deploy (push) Canceled after 37s
Deploy to Raspberry Pi / deploy (push) Canceled after 37s
- Updated PM2 version to 6.0.14 in package.json and pnpm-lock.yaml for improved stability. - Changed interpreter for PM2 processes to use `process.execPath` for consistency. - Added a new `start:pm2` script in package.json to streamline PM2 process management. - Updated README to reflect changes in PM2 usage and instructions for starting the application.
This commit is contained in:
@@ -168,8 +168,11 @@ pnpm install
|
||||
pnpm build
|
||||
# Redis must be reachable at REDIS_URL (set REDIS_PASS if Redis requires AUTH)
|
||||
# Put secrets in .env (JFLOW_JWT_SECRET, JFLOW_SECRETS_KEY, REDIS_URL, …)
|
||||
pm2 start ecosystem.config.cjs
|
||||
# Use in-tree PM2 6.x (same module control.js requires). A global `pm2` 7.x
|
||||
# against a 6.x daemon pegs CPU even when ls shows only 2 fork instances.
|
||||
pnpm start:pm2
|
||||
# UI: http://localhost:8500
|
||||
# If you already mixed versions: pnpm pm2 -- kill && pnpm start:pm2
|
||||
```
|
||||
|
||||
Or without the ecosystem file:
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
* Starts always-on processes only; HTTP (:8700) and workers are owned by
|
||||
* control.js via PM2 (same as `pnpm dev:pm2`).
|
||||
*
|
||||
* Use `pnpm start:pm2` (in-tree PM2 6.x). Do not use a global `pm2` 7.x —
|
||||
* a CLI/daemon version mismatch pegs CPU even with instances: 1.
|
||||
*
|
||||
* Prerequisites: `pnpm build` (packages/web/dist), Redis, .env secrets.
|
||||
*/
|
||||
const fs = require("fs");
|
||||
@@ -41,7 +44,7 @@ module.exports = {
|
||||
name: "jflow-control",
|
||||
cwd: root,
|
||||
script: "packages/server/control.js",
|
||||
interpreter: "node",
|
||||
interpreter: process.execPath,
|
||||
instances: 1,
|
||||
exec_mode: "fork",
|
||||
autorestart: true,
|
||||
@@ -55,7 +58,7 @@ module.exports = {
|
||||
name: "jflow-web",
|
||||
cwd: root,
|
||||
script: "packages/server/web-server.js",
|
||||
interpreter: "node",
|
||||
interpreter: process.execPath,
|
||||
instances: 1,
|
||||
exec_mode: "fork",
|
||||
autorestart: true,
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
"start:worker": "pnpm --filter @jerapah-flow/server start:worker",
|
||||
"start:control": "pnpm --filter @jerapah-flow/server start:control",
|
||||
"start:web": "pnpm --filter @jerapah-flow/server start:web",
|
||||
"pm2": "node scripts/pm2.mjs",
|
||||
"start:pm2": "node scripts/pm2.mjs start ecosystem.config.cjs",
|
||||
"migrate": "pnpm --filter @jerapah-flow/server migrate",
|
||||
"test": "pnpm --filter @jerapah-flow/shared test && pnpm --filter @jerapah-flow/web test",
|
||||
"lint": "pnpm --filter @jerapah-flow/web lint"
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"nodemailer": "^9.0.5",
|
||||
"pino": "^10.3.1",
|
||||
"pino-roll": "^4.0.0",
|
||||
"pm2": "^6.0.13",
|
||||
"pm2": "6.0.14",
|
||||
"rss-parser": "^3.13.0",
|
||||
"ssh2-sftp-client": "^12.1.1",
|
||||
"webdav": "^5.10.0",
|
||||
|
||||
Generated
+1
-1
@@ -77,7 +77,7 @@ importers:
|
||||
specifier: ^4.0.0
|
||||
version: 4.0.0
|
||||
pm2:
|
||||
specifier: ^6.0.13
|
||||
specifier: 6.0.14
|
||||
version: 6.0.14(supports-color@7.2.0)
|
||||
rss-parser:
|
||||
specifier: ^3.13.0
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Run the same PM2 binary control.js `require("pm2")` uses.
|
||||
* A global `pm2` 7.x talking to an in-memory 6.x daemon pegs CPU on start.
|
||||
*/
|
||||
import { spawn, spawnSync } from "node:child_process";
|
||||
import { createRequire } from "node:module";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const require = createRequire(
|
||||
path.join(root, "packages/server/package.json"),
|
||||
);
|
||||
const pm2Root = path.dirname(require.resolve("pm2/package.json"));
|
||||
const pm2Bin = path.join(pm2Root, "bin/pm2");
|
||||
const args = process.argv.slice(2);
|
||||
|
||||
function run(pm2Args, opts = {}) {
|
||||
return spawnSync(process.execPath, [pm2Bin, ...pm2Args], {
|
||||
cwd: root,
|
||||
encoding: "utf8",
|
||||
...opts,
|
||||
});
|
||||
}
|
||||
|
||||
const cmd = args[0];
|
||||
if (cmd === "start" || cmd === "restart" || cmd === "reload") {
|
||||
const probe = run(["ls"], { stdio: ["ignore", "pipe", "pipe"] });
|
||||
const text = `${probe.stdout ?? ""}${probe.stderr ?? ""}`;
|
||||
const mem = text.match(/In memory PM2 version:\s*(\S+)/);
|
||||
const loc = text.match(/Local PM2 version:\s*(\S+)/);
|
||||
if (mem && loc && mem[1] !== loc[1]) {
|
||||
console.error(
|
||||
`[jflow] PM2 daemon ${mem[1]} != CLI ${loc[1]}. Killing the daemon so control.js and the CLI share one version.`,
|
||||
);
|
||||
run(["kill"], { stdio: "inherit" });
|
||||
}
|
||||
}
|
||||
|
||||
const child = spawn(process.execPath, [pm2Bin, ...args], {
|
||||
cwd: root,
|
||||
stdio: "inherit",
|
||||
});
|
||||
child.on("exit", (code, signal) => {
|
||||
if (signal) process.kill(process.pid, signal);
|
||||
process.exit(code ?? 1);
|
||||
});
|
||||
Reference in New Issue
Block a user