mirror of
https://github.com/Xevion/xevion.dev.git
synced 2026-01-31 02:26:38 -06:00
- Migrate Docker entrypoint from inline shell script to TypeScript for better maintainability - Add exponential backoff DB connection retry (prod only, dev fails fast) - Increase healthcheck start-period to account for DB warmup
89 lines
1.9 KiB
TypeScript
89 lines
1.9 KiB
TypeScript
import { spawn, type Subprocess } from "bun";
|
|
import { unlinkSync, existsSync } from "fs";
|
|
|
|
const BUN_SOCKET = "/tmp/bun.sock";
|
|
const API_SOCKET = "/tmp/api.sock";
|
|
const PORT = process.env.PORT || "8080";
|
|
const LOG_JSON = process.env.LOG_JSON || "true";
|
|
|
|
function cleanup() {
|
|
try {
|
|
unlinkSync(BUN_SOCKET);
|
|
} catch {}
|
|
try {
|
|
unlinkSync(API_SOCKET);
|
|
} catch {}
|
|
}
|
|
|
|
// Cleanup on signals
|
|
process.on("SIGTERM", () => {
|
|
cleanup();
|
|
process.exit(0);
|
|
});
|
|
process.on("SIGINT", () => {
|
|
cleanup();
|
|
process.exit(0);
|
|
});
|
|
|
|
// Start Bun SSR
|
|
console.log("Starting Bun SSR...");
|
|
const bunProc = spawn({
|
|
cmd: ["bun", "--preload", "/app/web/console-logger.js", "index.js"],
|
|
cwd: "/app/web/build",
|
|
env: {
|
|
...process.env,
|
|
SOCKET_PATH: BUN_SOCKET,
|
|
LOG_JSON,
|
|
UPSTREAM_URL: API_SOCKET,
|
|
},
|
|
stdout: "inherit",
|
|
stderr: "inherit",
|
|
});
|
|
|
|
// Wait for Bun socket (5s timeout)
|
|
const startTime = Date.now();
|
|
while (!existsSync(BUN_SOCKET)) {
|
|
if (Date.now() - startTime > 5000) {
|
|
console.error("ERROR: Bun failed to create socket within 5s");
|
|
bunProc.kill();
|
|
cleanup();
|
|
process.exit(1);
|
|
}
|
|
await Bun.sleep(100);
|
|
}
|
|
|
|
// Start Rust server
|
|
console.log("Starting Rust API...");
|
|
const rustProc = spawn({
|
|
cmd: [
|
|
"/app/api",
|
|
"--listen",
|
|
`[::]:${PORT}`,
|
|
"--listen",
|
|
API_SOCKET,
|
|
"--downstream",
|
|
BUN_SOCKET,
|
|
],
|
|
stdout: "inherit",
|
|
stderr: "inherit",
|
|
});
|
|
|
|
// Monitor both processes - exit if either dies
|
|
async function monitor(name: string, proc: Subprocess) {
|
|
const exitCode = await proc.exited;
|
|
console.error(`${name} exited with code ${exitCode}`);
|
|
return { name, exitCode };
|
|
}
|
|
|
|
const result = await Promise.race([
|
|
monitor("Bun", bunProc),
|
|
monitor("Rust", rustProc),
|
|
]);
|
|
|
|
// Kill the other process
|
|
console.error(`${result.name} died, shutting down...`);
|
|
bunProc.kill();
|
|
rustProc.kill();
|
|
cleanup();
|
|
process.exit(result.exitCode || 1);
|