fix
This commit is contained in:
@@ -1,32 +1,89 @@
|
||||
import { Pool } from 'pg';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { dirname, join } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import bcrypt from 'bcryptjs';
|
||||
import { config } from './config.js';
|
||||
import pg from 'pg';
|
||||
|
||||
export const pool = new Pool({ connectionString: config.databaseUrl });
|
||||
const { Pool } = pg;
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
export const pool = new Pool({
|
||||
connectionString: process.env.DATABASE_URL,
|
||||
});
|
||||
|
||||
export async function initDb(): Promise<void> {
|
||||
const migration = await readFile(join(__dirname, '../migrations/001_init.sql'), 'utf8').catch(async () => {
|
||||
return readFile(join(process.cwd(), 'migrations/001_init.sql'), 'utf8');
|
||||
});
|
||||
await pool.query(migration);
|
||||
|
||||
await pool.query(
|
||||
`INSERT INTO nodes(name, hostname, is_current)
|
||||
VALUES($1, $2, true)
|
||||
ON CONFLICT (name) DO UPDATE SET hostname = EXCLUDED.hostname, is_current = true, updated_at = now()`,
|
||||
[config.nodeName, config.nodeHostname],
|
||||
);
|
||||
|
||||
const hash = await bcrypt.hash(config.adminPassword, 12);
|
||||
await pool.query(
|
||||
`INSERT INTO admin_users(email, password_hash, role)
|
||||
VALUES($1, $2, 'super_admin')
|
||||
ON CONFLICT (email) DO NOTHING`,
|
||||
[config.adminEmail.toLowerCase(), hash],
|
||||
);
|
||||
function sleep(ms: number) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
export async function initDb() {
|
||||
const maxAttempts = 30;
|
||||
|
||||
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
||||
try {
|
||||
await pool.query('SELECT 1');
|
||||
console.log(`✓ PostgreSQL connected`);
|
||||
|
||||
await pool.query(`
|
||||
CREATE TABLE IF NOT EXISTS nodes (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name TEXT UNIQUE NOT NULL,
|
||||
hostname TEXT NOT NULL,
|
||||
created_at TIMESTAMPTZ DEFAULT now()
|
||||
);
|
||||
`);
|
||||
|
||||
await pool.query(`
|
||||
CREATE TABLE IF NOT EXISTS domains (
|
||||
id SERIAL PRIMARY KEY,
|
||||
domain TEXT UNIQUE NOT NULL,
|
||||
node_name TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'active',
|
||||
first_seen_at TIMESTAMPTZ DEFAULT now(),
|
||||
last_seen_at TIMESTAMPTZ DEFAULT now()
|
||||
);
|
||||
`);
|
||||
|
||||
await pool.query(`
|
||||
CREATE TABLE IF NOT EXISTS mailboxes (
|
||||
id SERIAL PRIMARY KEY,
|
||||
email_address TEXT UNIQUE NOT NULL,
|
||||
domain TEXT NOT NULL,
|
||||
node_name TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'active',
|
||||
used_bytes BIGINT DEFAULT 0,
|
||||
last_usage_scan_at TIMESTAMPTZ,
|
||||
first_seen_at TIMESTAMPTZ DEFAULT now(),
|
||||
last_seen_at TIMESTAMPTZ DEFAULT now()
|
||||
);
|
||||
`);
|
||||
|
||||
await pool.query(`
|
||||
CREATE TABLE IF NOT EXISTS admin_users (
|
||||
id SERIAL PRIMARY KEY,
|
||||
email TEXT UNIQUE NOT NULL,
|
||||
password_hash TEXT NOT NULL,
|
||||
role TEXT NOT NULL DEFAULT 'super_admin',
|
||||
created_at TIMESTAMPTZ DEFAULT now()
|
||||
);
|
||||
`);
|
||||
|
||||
await pool.query(`
|
||||
CREATE TABLE IF NOT EXISTS audit_log (
|
||||
id SERIAL PRIMARY KEY,
|
||||
actor_email TEXT,
|
||||
action TEXT NOT NULL,
|
||||
target TEXT,
|
||||
details JSONB,
|
||||
created_at TIMESTAMPTZ DEFAULT now()
|
||||
);
|
||||
`);
|
||||
|
||||
return;
|
||||
} catch (err: any) {
|
||||
console.warn(
|
||||
`PostgreSQL not ready yet (${attempt}/${maxAttempts}): ${err.message}`
|
||||
);
|
||||
|
||||
if (attempt === maxAttempts) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
await sleep(2000);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,15 +2,19 @@ services:
|
||||
mailadmin-db:
|
||||
image: postgres:16
|
||||
container_name: mailadmin-db
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_DB: mailadmin
|
||||
POSTGRES_USER: mailadmin
|
||||
POSTGRES_PASSWORD: ${MAILADMIN_DB_PASSWORD:-change-me}
|
||||
POSTGRES_PASSWORD: ${MAILADMIN_DB_PASSWORD}
|
||||
volumes:
|
||||
- ./data/postgres:/var/lib/postgresql/data
|
||||
networks:
|
||||
- mail_network
|
||||
- mailadmin-db-data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U mailadmin -d mailadmin"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 20
|
||||
start_period: 10s
|
||||
restart: unless-stopped
|
||||
|
||||
mailadmin:
|
||||
build:
|
||||
@@ -19,7 +23,8 @@ services:
|
||||
container_name: mailadmin
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- mailadmin-db
|
||||
mailadmin-db:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
NODE_ENV: production
|
||||
PORT: 3000
|
||||
|
||||
Reference in New Issue
Block a user