feat(ecosystem): update PM2 configuration for control plane and web server
Deploy to Raspberry Pi / deploy (push) Successful in 52s
Deploy to Raspberry Pi / deploy (push) Successful in 52s
- Renamed the control process to `jflow-control` and updated the script path to `control.js`. - Introduced a new `jflow-web` process for the production UI, serving on port 8500. - Enhanced environment variable handling for both processes, ensuring proper port assignments. - Updated README to reflect new process architecture and usage instructions for starting the application.
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* Production UI server (:8500).
|
||||
* Serves packages/web/dist and proxies /api, /ops, /admin, /u like Vite in dev.
|
||||
* Always-on — survives Ops stop of jflow-http.
|
||||
*/
|
||||
import fs from "fs";
|
||||
import fastify from "fastify";
|
||||
import fastifyStatic from "@fastify/static";
|
||||
import { log } from "./logger.js";
|
||||
import { WEB_DIST } from "./paths.js";
|
||||
import {
|
||||
controlOrigin,
|
||||
httpOrigin,
|
||||
proxyToOrigin,
|
||||
} from "./ops-proxy.js";
|
||||
|
||||
if (!fs.existsSync(WEB_DIST)) {
|
||||
log.error(
|
||||
{ WEB_DIST },
|
||||
"web dist missing — run `pnpm build` before starting the UI server",
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const port = Number(process.env.JFLOW_UI_PORT ?? 8500);
|
||||
const control = controlOrigin();
|
||||
const http = httpOrigin();
|
||||
|
||||
const server = fastify({ loggerInstance: log });
|
||||
|
||||
/**
|
||||
* @param {import("fastify").FastifyRequest} req
|
||||
* @param {import("fastify").FastifyReply} reply
|
||||
*/
|
||||
async function proxyApi(req, reply) {
|
||||
const url = req.raw.url ?? "";
|
||||
// Match Vite: /api/auth → control (login works when HTTP is stopped).
|
||||
if (url === "/api/auth" || url.startsWith("/api/auth/") || url.startsWith("/api/auth?")) {
|
||||
return proxyToOrigin(req, reply, control, {
|
||||
unreachableMessage: "control plane unreachable",
|
||||
});
|
||||
}
|
||||
return proxyToOrigin(req, reply, http, {
|
||||
unreachableMessage: "HTTP API unreachable",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import("fastify").FastifyRequest} req
|
||||
* @param {import("fastify").FastifyReply} reply
|
||||
*/
|
||||
async function proxyOps(req, reply) {
|
||||
return proxyToOrigin(req, reply, control, {
|
||||
unreachableMessage: "control plane unreachable",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import("fastify").FastifyRequest} req
|
||||
* @param {import("fastify").FastifyReply} reply
|
||||
*/
|
||||
async function proxyHttp(req, reply) {
|
||||
return proxyToOrigin(req, reply, http, {
|
||||
unreachableMessage: "HTTP API unreachable",
|
||||
});
|
||||
}
|
||||
|
||||
server.all("/api", proxyApi);
|
||||
server.all("/api/*", proxyApi);
|
||||
server.all("/ops", proxyOps);
|
||||
server.all("/ops/*", proxyOps);
|
||||
server.all("/admin", proxyHttp);
|
||||
server.all("/admin/*", proxyHttp);
|
||||
server.all("/u", proxyHttp);
|
||||
server.all("/u/*", proxyHttp);
|
||||
|
||||
await server.register(fastifyStatic, {
|
||||
root: WEB_DIST,
|
||||
wildcard: false,
|
||||
});
|
||||
|
||||
server.setNotFoundHandler((req, reply) => {
|
||||
const url = req.raw.url ?? "";
|
||||
if (
|
||||
url.startsWith("/api") ||
|
||||
url.startsWith("/u/") ||
|
||||
url.startsWith("/admin") ||
|
||||
url.startsWith("/ops")
|
||||
) {
|
||||
return reply.code(404).send({ error: "not found" });
|
||||
}
|
||||
return reply.sendFile("index.html");
|
||||
});
|
||||
|
||||
async function shutdown() {
|
||||
try {
|
||||
await server.close();
|
||||
} catch (err) {
|
||||
log.error({ err }, "web-server shutdown error");
|
||||
}
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
process.on("SIGINT", shutdown);
|
||||
process.on("SIGTERM", shutdown);
|
||||
|
||||
try {
|
||||
await server.listen({ host: "0.0.0.0", port });
|
||||
log.info(
|
||||
{ port, WEB_DIST, control, http },
|
||||
"UI server listening (static + proxy)",
|
||||
);
|
||||
} catch (err) {
|
||||
log.error({ err }, "failed to start UI server");
|
||||
process.exit(1);
|
||||
}
|
||||
Reference in New Issue
Block a user