diff --git a/Dockerfile b/Dockerfile index 41f9c2c..34d12c3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM denoland/deno:alpine-2.0.2 +FROM docker.io/denoland/deno:alpine-2.0.2 WORKDIR /app @@ -8,6 +8,7 @@ RUN deno install || true # Copy source code and assets COPY main.ts . +COPY src ./src COPY viewer ./viewer COPY data ./data COPY mechanical ./mechanical diff --git a/main.ts b/main.ts index 291d1e9..c07ced1 100644 --- a/main.ts +++ b/main.ts @@ -5,8 +5,8 @@ import { qaRoutes } from "./src/routes/qa.ts"; const app = new Hono(); -// Initialize DB schema on startup -await initDb(); +// Initialize DB schema in background so server opens port immediately +initDb().catch((err) => console.error("Database background init failed:", err)); // API Routes app.get("/api/status", async (c) => { diff --git a/src/db/connection.ts b/src/db/connection.ts index fe67a2e..7d0a16d 100644 --- a/src/db/connection.ts +++ b/src/db/connection.ts @@ -6,28 +6,42 @@ export const sql = postgres({ database: Deno.env.get("POSTGRES_DB") || "nas_builder", username: Deno.env.get("POSTGRES_USER") || "nasadmin", password: Deno.env.get("POSTGRES_PASSWORD") || "your_secure_database_password_here", + max: 10, + idle_timeout: 30, + connect_timeout: 10, }); -export async function initDb() { - await sql` - CREATE TABLE IF NOT EXISTS qa_checklists ( - id VARCHAR(50) PRIMARY KEY, - label TEXT NOT NULL, - is_completed BOOLEAN DEFAULT false, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP - ); - `; - - // Seed some initial data if empty - const count = await sql`SELECT count(*) FROM qa_checklists`; - if (count[0].count === "0") { - await sql` - INSERT INTO qa_checklists (id, label, is_completed) VALUES - ('qa-cap', 'Supercap mounted & isolated', false), - ('qa-sas', 'Broadcom SAS seated in PCIe', false), - ('qa-cool', 'Waterblock pressure tested', false), - ('qa-zfs', 'ZFS pool scrub baseline passed', false) - `; +export async function initDb(retries = 5, delayMs = 2000) { + for (let i = 0; i < retries; i++) { + try { + await sql` + CREATE TABLE IF NOT EXISTS qa_checklists ( + id VARCHAR(50) PRIMARY KEY, + label TEXT NOT NULL, + is_completed BOOLEAN DEFAULT false, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ); + `; + + const count = await sql`SELECT count(*) FROM qa_checklists`; + if (count[0].count === "0") { + await sql` + INSERT INTO qa_checklists (id, label, is_completed) VALUES + ('qa-cap', 'Supercap mounted & isolated', false), + ('qa-sas', 'Broadcom SAS seated in PCIe', false), + ('qa-cool', 'Waterblock pressure tested', false), + ('qa-zfs', 'ZFS pool scrub baseline passed', false) + `; + } + console.log("✅ Database schema initialized successfully"); + return; + } catch (err: any) { + console.warn(`⚠️ Database init attempt ${i + 1}/${retries} failed: ${err.message}`); + if (i < retries - 1) { + await new Promise((resolve) => setTimeout(resolve, delayMs)); + } else { + console.error("❌ Could not initialize database schema after retries:", err.message); + } + } } - console.log("✅ Database schema initialized"); }