Fix production deployment: SQLite DB, externals, static path
- Switch DB from PostgreSQL to SQLite (data.db) for now - Add better-sqlite3, pg, drizzle-orm/* to build externals - Fix serveStatic path resolution with cwd fallback - Fix import.meta issue in static.ts for CJS bundle - Rate limit whitelist for home subnet (192.168.x.x) - Relax dev rate limits: 500/15min general, 50/15min authmaster
parent
a03ae5b62c
commit
f019e4114f
|
|
@ -54,7 +54,7 @@ async function buildAll() {
|
|||
"process.env.NODE_ENV": '"production"',
|
||||
},
|
||||
minify: true,
|
||||
external: externals,
|
||||
external: [...externals, "better-sqlite3", "pg", "drizzle-orm/better-sqlite3", "drizzle-orm/node-postgres"],
|
||||
logLevel: "info",
|
||||
});
|
||||
}
|
||||
|
|
|
|||
35
server/db.ts
35
server/db.ts
|
|
@ -1,32 +1,31 @@
|
|||
import { drizzle } from "drizzle-orm/node-postgres";
|
||||
import { drizzle } from "drizzle-orm/better-sqlite3";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { users, User, NewUser } from "../shared/schema";
|
||||
import { Pool } from "pg";
|
||||
import Database from "better-sqlite3";
|
||||
import path from "node:path";
|
||||
import fs from "node:fs";
|
||||
|
||||
// Production PostgreSQL connection
|
||||
const pool = new Pool({
|
||||
host: process.env.DB_HOST || "10.136.95.120",
|
||||
port: parseInt(process.env.DB_PORT || "5432"),
|
||||
user: process.env.DB_USER || "gn_admin",
|
||||
password: process.env.DB_PASSWORD || "",
|
||||
database: process.env.DB_NAME || "gammanexus",
|
||||
ssl: (process.env.DB_SSL === "true" && process.env.NODE_ENV === "production") ? { rejectUnauthorized: false } : false,
|
||||
max: 20,
|
||||
idleTimeoutMillis: 30000,
|
||||
connectionTimeoutMillis: 5000,
|
||||
});
|
||||
// Use SQLite for production (PostgreSQL migration later)
|
||||
const dbPath = path.resolve(__dirname || ".", "..", "data.db");
|
||||
|
||||
export const db = drizzle(pool);
|
||||
// Ensure data directory exists
|
||||
const dbDir = path.dirname(dbPath);
|
||||
if (!fs.existsSync(dbDir)) {
|
||||
fs.mkdirSync(dbDir, { recursive: true });
|
||||
}
|
||||
|
||||
const sqlite = new Database(dbPath);
|
||||
export const db = drizzle(sqlite);
|
||||
|
||||
// Initialize users table if it doesn't exist (called at startup)
|
||||
export async function initDb(): Promise<void> {
|
||||
await db.execute(`
|
||||
sqlite.exec(`
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id SERIAL PRIMARY KEY,
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
email TEXT NOT NULL UNIQUE,
|
||||
password_hash TEXT NOT NULL,
|
||||
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
`);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,13 +2,20 @@ import express from 'express';
|
|||
import type { Express } from 'express';
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
export function serveStatic(app: Express) {
|
||||
const distPath = path.resolve(__dirname, "..", "dist", "public");
|
||||
// In production, dist/public is at the same level as index.cjs
|
||||
const distPath = path.resolve(__dirname, "..", "public");
|
||||
if (!fs.existsSync(distPath)) {
|
||||
// Fallback: check cwd
|
||||
const cwdPath = path.resolve(process.cwd(), "dist", "public");
|
||||
if (fs.existsSync(cwdPath)) {
|
||||
app.use(express.static(cwdPath));
|
||||
app.use("/{*path}", (_req, res) => {
|
||||
res.sendFile(path.resolve(cwdPath, "index.html"));
|
||||
});
|
||||
return;
|
||||
}
|
||||
throw new Error(
|
||||
`Could not find the build directory: ${distPath}, make sure to build the client first`,
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in New Issue