Files
kita-planer/scripts/initialize-production.mjs
T

28 lines
1.8 KiB
JavaScript

import { mkdirSync, existsSync, readFileSync, writeFileSync, chmodSync, chownSync } from 'node:fs';
import { randomBytes } from 'node:crypto';
import { spawnSync } from 'node:child_process';
const passwordFile = process.env.APP_DATABASE_PASSWORD_FILE;
if (!passwordFile) throw new Error('Runtime password file is required.');
const directory = passwordFile.slice(0, passwordFile.lastIndexOf('/'));
mkdirSync(directory, { recursive: true, mode: 0o700 });
const password = existsSync(passwordFile) ? readFileSync(passwordFile, 'utf8').trim() : randomBytes(32).toString('hex');
if (!/^[a-f0-9]{64}$/.test(password)) throw new Error('Invalid runtime password file.');
if (!existsSync(passwordFile)) writeFileSync(passwordFile, password + '\n', { flag: 'wx', mode: 0o400 });
chmodSync(passwordFile, 0o400);
chownSync(passwordFile, 1001, 1001);
chownSync(directory, 1001, 1001);
const ownerUrl = new URL('postgresql://postgres:5432/' + encodeURIComponent(process.env.POSTGRES_DB || 'kita_planer'));
ownerUrl.username = process.env.POSTGRES_USER || 'kita_planer';
ownerUrl.password = process.env.POSTGRES_PASSWORD || '';
if (!ownerUrl.password) throw new Error('Database owner password is required.');
const environment = { ...process.env, DATABASE_URL: ownerUrl.toString(), APP_DATABASE_PASSWORD: password };
for (const args of [['node_modules/prisma/build/index.js', 'migrate', 'deploy'], ['scripts/provision-runtime-role.mjs']]) {
const result = spawnSync(process.execPath, args, { env: environment, stdio: 'inherit' });
if (result.status !== 0) process.exit(result.status || 1);
}
for (const path of ['/app/uploads', '/app/uploads/announcements', '/app/uploads/announcements/announcements', '/app/runtime-cache']) {
mkdirSync(path, { recursive: true, mode: 0o700 });
chownSync(path, 1001, 1001);
}
console.log('Database initialized; restricted application access and volumes are ready.');