mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-06-15 20:25:23 +02:00
- Introduced a new script to wait for PostgreSQL to be ready before starting the application. - Updated the Dockerfile to include a health check for the application. - Modified the start script in package.json to run the wait-for-postgres script prior to starting the server and migration processes. - Added the wait-for-postgres TypeScript file to handle connection retries to the PostgreSQL database.
92 lines
2.1 KiB
TypeScript
92 lines
2.1 KiB
TypeScript
import net from "node:net";
|
|
import { URL } from "node:url";
|
|
import { dbUrl } from "@dokploy/server/db/constants";
|
|
|
|
const TIMEOUT_MS = Number(process.env.POSTGRES_WAIT_TIMEOUT || 120_000);
|
|
const RETRY_DELAY_MS = Number(process.env.POSTGRES_WAIT_RETRY || 2000);
|
|
|
|
function sleep(ms: number) {
|
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
}
|
|
|
|
function resolvePostgresTarget(): { host: string; port: number } {
|
|
const databaseUrl = dbUrl;
|
|
|
|
if (!databaseUrl) {
|
|
console.error("[wait-for-postgres] DATABASE_URL is not set");
|
|
process.exit(1);
|
|
}
|
|
|
|
try {
|
|
const url = new URL(databaseUrl);
|
|
|
|
const host = url.hostname;
|
|
const port = Number(url.port || 5432);
|
|
|
|
if (!host) {
|
|
throw new Error("DATABASE_URL has no hostname");
|
|
}
|
|
|
|
return { host, port };
|
|
} catch (err) {
|
|
console.error("[wait-for-postgres] Invalid DATABASE_URL:", databaseUrl);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
function checkTcpConnection(host: string, port: number): Promise<void> {
|
|
return new Promise((resolve, reject) => {
|
|
const socket = net.createConnection({ host, port });
|
|
|
|
socket.setTimeout(3000);
|
|
|
|
socket.on("connect", () => {
|
|
socket.end();
|
|
resolve();
|
|
});
|
|
|
|
socket.on("timeout", () => {
|
|
socket.destroy();
|
|
reject(new Error("Connection timeout"));
|
|
});
|
|
|
|
socket.on("error", reject);
|
|
});
|
|
}
|
|
|
|
async function waitForPostgres() {
|
|
const { host, port } = resolvePostgresTarget();
|
|
const start = Date.now();
|
|
|
|
console.log(
|
|
`[wait-for-postgres] Waiting for postgres at ${host}:${port} (timeout ${TIMEOUT_MS}ms)`,
|
|
);
|
|
|
|
while (true) {
|
|
try {
|
|
await checkTcpConnection(host, port);
|
|
console.log("[wait-for-postgres] Postgres is reachable ✅");
|
|
return;
|
|
} catch {
|
|
const elapsed = Date.now() - start;
|
|
|
|
if (elapsed > TIMEOUT_MS) {
|
|
console.error(
|
|
`[wait-for-postgres] Timeout after ${elapsed}ms. Postgres not reachable ❌`,
|
|
);
|
|
process.exit(1);
|
|
}
|
|
|
|
console.log(
|
|
`[wait-for-postgres] Postgres not ready yet, retrying in ${RETRY_DELAY_MS}ms...`,
|
|
);
|
|
await sleep(RETRY_DELAY_MS);
|
|
}
|
|
}
|
|
}
|
|
|
|
waitForPostgres().catch((err) => {
|
|
console.error("[wait-for-postgres] Fatal error:", err);
|
|
process.exit(1);
|
|
});
|