feat: add graceful shutdown handling (SIGTERM/SIGINT)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@ import Fastify from 'fastify';
|
|||||||
import cors from '@fastify/cors';
|
import cors from '@fastify/cors';
|
||||||
import cookie from '@fastify/cookie';
|
import cookie from '@fastify/cookie';
|
||||||
import rateLimit from '@fastify/rate-limit';
|
import rateLimit from '@fastify/rate-limit';
|
||||||
|
import path from 'path';
|
||||||
import { config } from './config/env';
|
import { config } from './config/env';
|
||||||
import { securityHeaders } from './middleware/security';
|
import { securityHeaders } from './middleware/security';
|
||||||
|
|
||||||
@@ -129,6 +130,23 @@ async function start() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Frontend: static file serving (production) ---
|
||||||
|
if (config.isProduction) {
|
||||||
|
const fastifyStatic = (await import('@fastify/static')).default;
|
||||||
|
await app.register(fastifyStatic, {
|
||||||
|
root: path.join(__dirname, '..', 'dist-client'),
|
||||||
|
prefix: '/',
|
||||||
|
wildcard: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
app.setNotFoundHandler((request, reply) => {
|
||||||
|
if (request.url.startsWith('/api/')) {
|
||||||
|
return reply.status(404).send({ success: false, error: 'Not found' });
|
||||||
|
}
|
||||||
|
return reply.sendFile('index.html');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// --- Start ---
|
// --- Start ---
|
||||||
const port = config.isProduction ? config.port : 3000;
|
const port = config.isProduction ? config.port : 3000;
|
||||||
try {
|
try {
|
||||||
@@ -138,6 +156,23 @@ async function start() {
|
|||||||
app.log.error(err);
|
app.log.error(err);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const shutdown = async (signal: string) => {
|
||||||
|
app.log.info(`${signal} received, shutting down gracefully...`);
|
||||||
|
try {
|
||||||
|
await app.close();
|
||||||
|
const { default: prisma } = await import('./config/database');
|
||||||
|
await prisma.$disconnect();
|
||||||
|
app.log.info('Server shut down successfully');
|
||||||
|
process.exit(0);
|
||||||
|
} catch (err) {
|
||||||
|
app.log.error(err, 'Error during shutdown');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
||||||
|
process.on('SIGINT', () => shutdown('SIGINT'));
|
||||||
}
|
}
|
||||||
|
|
||||||
start();
|
start();
|
||||||
|
|||||||
Reference in New Issue
Block a user