Files
Termix/src/backend/starter.ts
T

186 lines
5.5 KiB
TypeScript
Raw Normal View History

2025-10-01 15:40:10 -05:00
import dotenv from "dotenv";
import { promises as fs } from "fs";
import { readFileSync } from "fs";
import path from "path";
import { fileURLToPath } from "url";
import { AutoSSLSetup } from "./utils/auto-ssl-setup.js";
import { AuthManager } from "./utils/auth-manager.js";
import { DataCrypto } from "./utils/data-crypto.js";
import { SystemCrypto } from "./utils/system-crypto.js";
2025-09-12 14:42:00 -05:00
import { systemLogger, versionLogger } from "./utils/logger.js";
2025-08-07 02:20:27 -05:00
(async () => {
+4
2026-02-12 22:28:13 -06:00
const initStartTime = Date.now();
2025-09-12 14:42:00 -05:00
try {
2025-10-01 15:40:10 -05:00
dotenv.config({ quiet: true });
const dataDir = process.env.DATA_DIR || "./db/data";
const envPath = path.join(dataDir, ".env");
try {
await fs.access(envPath);
const persistentConfig = dotenv.config({ path: envPath, quiet: true });
if (persistentConfig.parsed) {
Object.assign(process.env, persistentConfig.parsed);
}
2025-11-17 09:46:05 -06:00
} catch (error) {}
2025-10-01 15:40:10 -05:00
+4
2026-02-12 22:28:13 -06:00
systemLogger.info("Termix backend initialization started", {
operation: "backend_init_start",
nodeEnv: process.env.NODE_ENV || "production",
port: process.env.PORT || 4090,
});
2025-10-01 15:40:10 -05:00
let version = "unknown";
const versionSources = [
() => process.env.VERSION,
() => {
try {
const packageJsonPath = path.join(process.cwd(), "package.json");
const packageJson = JSON.parse(
readFileSync(packageJsonPath, "utf-8"),
);
return packageJson.version;
} catch {
return null;
}
},
() => {
try {
const __filename = fileURLToPath(import.meta.url);
const packageJsonPath = path.join(
path.dirname(__filename),
"../../../package.json",
);
const packageJson = JSON.parse(
readFileSync(packageJsonPath, "utf-8"),
);
return packageJson.version;
} catch {
return null;
}
},
() => {
try {
const packageJsonPath = path.join("/app", "package.json");
const packageJson = JSON.parse(
readFileSync(packageJsonPath, "utf-8"),
);
return packageJson.version;
} catch {
return null;
}
},
];
for (const getVersion of versionSources) {
try {
const foundVersion = getVersion();
if (foundVersion && foundVersion !== "unknown") {
version = foundVersion;
break;
}
+7
2025-11-05 10:36:16 -06:00
} catch {
2025-10-01 15:40:10 -05:00
continue;
}
}
2025-09-12 14:42:00 -05:00
versionLogger.info(`Termix Backend starting - Version: ${version}`, {
operation: "startup",
version: version,
});
2025-08-07 02:20:27 -05:00
2025-10-01 15:40:10 -05:00
const systemCrypto = SystemCrypto.getInstance();
await systemCrypto.initializeJWTSecret();
await systemCrypto.initializeDatabaseKey();
await systemCrypto.initializeInternalAuthToken();
2025-08-07 02:20:27 -05:00
2025-10-01 15:40:10 -05:00
await AutoSSLSetup.initialize();
+4
2026-02-12 22:28:13 -06:00
systemLogger.success("SSL setup completed", {
operation: "backend_init_ssl",
sslEnabled: process.env.SSL_ENABLED === "true",
});
2025-10-01 15:40:10 -05:00
const dbModule = await import("./database/db/index.js");
await dbModule.initializeDatabase();
+4
2026-02-12 22:28:13 -06:00
systemLogger.success("Database initialized", {
operation: "backend_init_db",
});
2025-10-01 15:40:10 -05:00
const authManager = AuthManager.getInstance();
await authManager.initialize();
DataCrypto.initialize();
+4
2026-02-12 22:28:13 -06:00
const { OPKSSHBinaryManager } =
await import("./utils/opkssh-binary-manager.js");
try {
await OPKSSHBinaryManager.ensureBinary();
} catch (error) {
const dataDir =
process.env.DATA_DIR || path.join(process.cwd(), "db", "data");
systemLogger.warn(
"Failed to initialize OPKSSH binary - OPKSSH authentication will not be available",
{
operation: "opkssh_binary_init_failed",
error: error instanceof Error ? error.message : "Unknown error",
stack: error instanceof Error ? error.stack : undefined,
platform: process.platform,
arch: process.arch,
dataDir,
},
);
}
2025-10-01 15:40:10 -05:00
await import("./database/database.js");
await import("./ssh/terminal.js");
await import("./ssh/tunnel.js");
await import("./ssh/file-manager.js");
await import("./ssh/server-stats.js");
+1
2025-12-31 22:20:12 -06:00
await import("./ssh/docker.js");
await import("./ssh/docker-console.js");
+7
2025-11-05 10:36:16 -06:00
await import("./dashboard.js");
2025-09-12 14:42:00 -05:00
+4
2026-02-12 22:28:13 -06:00
systemLogger.success("Termix backend started successfully", {
operation: "backend_init_complete",
port: process.env.PORT || 4090,
ssl: process.env.SSL_ENABLED === "true",
duration: Date.now() - initStartTime,
});
2025-09-12 14:42:00 -05:00
process.on("SIGINT", () => {
systemLogger.info(
"Received SIGINT signal, initiating graceful shutdown...",
{ operation: "shutdown" },
);
process.exit(0);
});
process.on("SIGTERM", () => {
systemLogger.info(
"Received SIGTERM signal, initiating graceful shutdown...",
{ operation: "shutdown" },
);
process.exit(0);
});
process.on("uncaughtException", (error) => {
systemLogger.error("Uncaught exception occurred", error, {
operation: "error_handling",
});
process.exit(1);
});
+7
2025-11-05 10:36:16 -06:00
process.on("unhandledRejection", (reason) => {
2025-09-12 14:42:00 -05:00
systemLogger.error("Unhandled promise rejection", reason, {
operation: "error_handling",
});
process.exit(1);
});
} catch (error) {
systemLogger.error("Failed to initialize backend services", error, {
operation: "startup_failed",
});
process.exit(1);
}
})();