mirror of
https://github.com/Xevion/xevion.dev.git
synced 2026-01-31 04:26:43 -06:00
refactor: replace shell entrypoint with TypeScript, add DB retry logic
- 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
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
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);
|
||||
Reference in New Issue
Block a user