Files
descrybe/scripts/wait-postgres.mjs
T

78 lines
2.4 KiB
JavaScript
Raw Normal View History

#!/usr/bin/env node
/**
2026-08-10 01:12:21 +02:00
* Wait until DATABASE_URL Postgres accepts TCP connections.
* Works with native Postgres or Docker-mapped ports (no docker CLI required).
*
* Usage: node scripts/wait-postgres.mjs
*/
2026-08-10 01:12:21 +02:00
import net from "node:net";
import { setTimeout as delay } from "node:timers/promises";
2026-08-10 01:12:21 +02:00
import { loadRootEnv } from "./root-env.mjs";
const maxAttempts = Number(process.env.DESCRYBE_DB_WAIT_ATTEMPTS || 60);
const sleepMs = Number(process.env.DESCRYBE_DB_WAIT_MS || 1000);
2026-08-10 01:12:21 +02:00
const env = loadRootEnv(process.env);
const databaseUrl = env.DATABASE_URL;
if (!databaseUrl || !String(databaseUrl).trim()) {
console.error(
"[db] DATABASE_URL is required (root .env or shell; see .env.example)",
);
2026-08-10 01:12:21 +02:00
process.exit(1);
}
function parsePostgresTarget(urlStr) {
let u;
try {
u = new URL(urlStr);
} catch {
console.error("[db] DATABASE_URL is not a valid URL");
process.exit(1);
}
const protocol = (u.protocol || "").replace(/:$/, "");
if (protocol !== "postgres" && protocol !== "postgresql") {
console.error(`[db] DATABASE_URL must be postgres(ql)://… (got ${protocol})`);
process.exit(1);
}
const host = u.hostname || "127.0.0.1";
const port = Number(u.port || 5432);
if (!Number.isFinite(port) || port <= 0) {
console.error("[db] DATABASE_URL has an invalid port");
process.exit(1);
}
return { host, port };
}
function canConnect(host, port) {
return new Promise((resolve) => {
const socket = net.connect({ host, port });
const done = (ok) => {
socket.removeAllListeners();
socket.destroy();
resolve(ok);
};
socket.setTimeout(2000);
socket.once("connect", () => done(true));
socket.once("timeout", () => done(false));
socket.once("error", () => done(false));
});
}
const { host, port } = parsePostgresTarget(databaseUrl);
console.log(`[db] waiting for Postgres at ${host}:${port}`);
for (let i = 1; i <= maxAttempts; i++) {
if (await canConnect(host, port)) {
console.log(`[db] postgres ready (attempt ${i})`);
process.exit(0);
}
process.stdout.write(`[db] waiting for postgres… (${i}/${maxAttempts})\r`);
await delay(sleepMs);
}
console.error("\n[db] postgres did not become ready in time");
2026-08-10 01:12:21 +02:00
console.error(`Check: DATABASE_URL host ${host}:${port} is up and listening`);
console.error("Native: sudo systemctl status postgresql");
console.error("Docker (optional local): docker compose ps && docker compose logs postgres");
process.exit(1);