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 cookie from '@fastify/cookie';
|
||||
import rateLimit from '@fastify/rate-limit';
|
||||
import path from 'path';
|
||||
import { config } from './config/env';
|
||||
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 ---
|
||||
const port = config.isProduction ? config.port : 3000;
|
||||
try {
|
||||
@@ -138,6 +156,23 @@ async function start() {
|
||||
app.log.error(err);
|
||||
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();
|
||||
|
||||
Reference in New Issue
Block a user