126 lines
3.9 KiB
JavaScript
126 lines
3.9 KiB
JavaScript
// app.js
|
|
const express = require("express");
|
|
const path = require("path");
|
|
const rootDir = require("./utils/path");
|
|
const { logger } = require('./utils/logger');
|
|
const log4js = require("log4js");
|
|
const fs = require('fs');
|
|
const fse = require('fs-extra');
|
|
|
|
const EXAMPLE_ENV = process.env.example || process.env.EXAMPLE;
|
|
console.log("Environment variable 'example' is set to:", EXAMPLE_ENV);
|
|
let example;
|
|
if (EXAMPLE_ENV === '1') {
|
|
example = "cvExample1";
|
|
logger.info("Selected example: cvExample1");
|
|
} else if (EXAMPLE_ENV === '2') {
|
|
example = "cvExample2";
|
|
logger.info("Selected example: cvExample2");
|
|
} else if (EXAMPLE_ENV === '3') {
|
|
example = "cvExampleMe";
|
|
logger.info("Selected example: cvExampleMe");
|
|
} else {
|
|
example = "cvExample1";
|
|
logger.info("Default example selected: cvExample1");
|
|
}
|
|
|
|
const source = path.join(rootDir, 'public', 'examples', example);
|
|
const dest = path.join(rootDir, 'public', 'ress', 'mountedRess');
|
|
const resumeFile = path.join(dest, 'me.json');
|
|
|
|
// A bind-mounted resume is never overwritten. For built-in examples, finish
|
|
// seeding before accepting traffic so the first request cannot race the copy.
|
|
function ensureResumeFiles() {
|
|
if (fs.existsSync(resumeFile)) {
|
|
logger.info("File 'me.json' already exists in destination.");
|
|
return;
|
|
}
|
|
|
|
if (!fs.existsSync(source)) {
|
|
throw new Error(`Selected example directory does not exist: ${source}`);
|
|
}
|
|
|
|
logger.info(`Seeding ${example} into ${dest}`);
|
|
fse.copySync(source, dest, { errorOnExist: false, overwrite: false });
|
|
|
|
const data = fs.readFileSync(resumeFile, 'utf8');
|
|
if (!data.trim()) {
|
|
throw new Error("The seeded resume file 'me.json' is empty.");
|
|
}
|
|
JSON.parse(data);
|
|
logger.info(`Seeded ${example} successfully.`);
|
|
}
|
|
|
|
try {
|
|
ensureResumeFiles();
|
|
} catch (error) {
|
|
logger.error('Unable to initialize resume data.', error);
|
|
console.error('Unable to initialize resume data:', error.message);
|
|
process.exit(1);
|
|
}
|
|
|
|
const homeRoute = require("./routes/home");
|
|
|
|
const app = express();
|
|
const PORT = Number(process.env.PORT) || 5555;
|
|
|
|
app.set("view engine", "ejs");
|
|
app.set("views", path.join(rootDir, 'views'));
|
|
|
|
// Static Files
|
|
app.use(express.static(path.join(rootDir, "public")));
|
|
app.use("/css", express.static(path.join(rootDir, "node_modules/bootstrap/dist/css")));
|
|
app.use("/fa", express.static(__dirname + "/node_modules/font-awesome/css"));
|
|
app.use("/fonts", express.static(__dirname + "/node_modules/font-awesome/fonts"));
|
|
app.use('/vendor/html2pdf', express.static(path.join(rootDir, 'node_modules', 'html2pdf.js', 'dist')));
|
|
|
|
app.use(log4js.connectLogger(logger, { level: "info" }));
|
|
|
|
app.get('/health', (req, res) => res.status(200).json({ status: 'ok' }));
|
|
|
|
// Routen
|
|
app.use(homeRoute);
|
|
|
|
// 404 handler
|
|
app.use((req, res) => {
|
|
logger.warn(`Not found: ${req.method} ${req.url}`);
|
|
res.status(404).send('Not Found');
|
|
});
|
|
|
|
// Error handler
|
|
// eslint-disable-next-line no-unused-vars
|
|
app.use((err, req, res, next) => {
|
|
logger.error('Unhandled error', err);
|
|
res.status(500).send('Internal Server Error');
|
|
});
|
|
|
|
// Request Logging
|
|
app.use((req, res, next) => {
|
|
console.log(`Incoming request: ${req.method} ${req.url}`);
|
|
logger.info(`Received ${req.method} request for ${req.url}`);
|
|
next();
|
|
});
|
|
|
|
// Server starten
|
|
const server = app.listen(PORT, () => {
|
|
console.log(`Server is listening on port ${PORT}`);
|
|
logger.info(`Server started and is listening on port ${PORT}`);
|
|
});
|
|
|
|
// Graceful shutdown
|
|
const shutdown = (signal) => {
|
|
console.log(`\nReceived ${signal}. Shutting down gracefully...`);
|
|
logger.info(`Received ${signal}. Shutting down.`);
|
|
server.close(() => {
|
|
logger.info('HTTP server closed.');
|
|
process.exit(0);
|
|
});
|
|
// Force exit if not closed in time
|
|
setTimeout(() => {
|
|
logger.error('Force exit after timeout.');
|
|
process.exit(1);
|
|
}, 10000).unref();
|
|
};
|
|
|
|
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
process.on('SIGTERM', () => shutdown('SIGTERM'));
|