mirror of
https://github.com/andwati/dokploy.git
synced 2026-11-08 13:05:17 +00:00
Merge pull request #3647 from Dokploy/2659-upgrading-dokploy-admin-resulted-in-bad-gateway-500-consistently
feat(dokploy): add wait-for-postgres script and update Dockerfile and…
This commit is contained in:
+5
-1
@@ -65,4 +65,8 @@ RUN curl -sSL https://railpack.com/install.sh | bash
|
|||||||
COPY --from=buildpacksio/pack:0.39.1 /usr/local/bin/pack /usr/local/bin/pack
|
COPY --from=buildpacksio/pack:0.39.1 /usr/local/bin/pack /usr/local/bin/pack
|
||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
CMD [ "pnpm", "start" ]
|
|
||||||
|
HEALTHCHECK --interval=10s --timeout=3s --retries=10 \
|
||||||
|
CMD curl -fs http://localhost:3000/api/trpc/settings.health || exit 1
|
||||||
|
|
||||||
|
CMD ["sh", "-c", "pnpm run wait-for-postgres && exec pnpm start"]
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ try {
|
|||||||
entryPoints: {
|
entryPoints: {
|
||||||
server: "server/server.ts",
|
server: "server/server.ts",
|
||||||
migration: "migration.ts",
|
migration: "migration.ts",
|
||||||
|
"wait-for-postgres": "wait-for-postgres.ts",
|
||||||
"reset-password": "reset-password.ts",
|
"reset-password": "reset-password.ts",
|
||||||
"reset-2fa": "reset-2fa.ts",
|
"reset-2fa": "reset-2fa.ts",
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
"build-server": "tsx esbuild.config.ts",
|
"build-server": "tsx esbuild.config.ts",
|
||||||
"build-next": "next build --webpack",
|
"build-next": "next build --webpack",
|
||||||
"setup": "tsx -r dotenv/config setup.ts && sleep 5 && pnpm run migration:run",
|
"setup": "tsx -r dotenv/config setup.ts && sleep 5 && pnpm run migration:run",
|
||||||
|
"wait-for-postgres": "node -r dotenv/config dist/wait-for-postgres.mjs",
|
||||||
|
"wait-for-postgres-dev": "tsx -r dotenv/config wait-for-postgres.ts",
|
||||||
"reset-password": "node -r dotenv/config dist/reset-password.mjs",
|
"reset-password": "node -r dotenv/config dist/reset-password.mjs",
|
||||||
"reset-2fa": "node -r dotenv/config dist/reset-2fa.mjs",
|
"reset-2fa": "node -r dotenv/config dist/reset-2fa.mjs",
|
||||||
"dev": "tsx -r dotenv/config ./server/server.ts --project tsconfig.server.json ",
|
"dev": "tsx -r dotenv/config ./server/server.ts --project tsconfig.server.json ",
|
||||||
|
|||||||
@@ -764,16 +764,13 @@ export const settingsRouter = createTRPCRouter({
|
|||||||
return haveServers.length > 0 || haveProjects.length > 0;
|
return haveServers.length > 0 || haveProjects.length > 0;
|
||||||
}),
|
}),
|
||||||
health: publicProcedure.query(async () => {
|
health: publicProcedure.query(async () => {
|
||||||
if (IS_CLOUD) {
|
try {
|
||||||
try {
|
await db.execute(sql`SELECT 1`);
|
||||||
await db.execute(sql`SELECT 1`);
|
return { status: "ok" };
|
||||||
return { status: "ok" };
|
} catch (error) {
|
||||||
} catch (error) {
|
console.error("Database connection error:", error);
|
||||||
console.error("Database connection error:", error);
|
throw error;
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return { status: "not_cloud" };
|
|
||||||
}),
|
}),
|
||||||
setupGPU: adminProcedure
|
setupGPU: adminProcedure
|
||||||
.input(
|
.input(
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
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);
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user