v0.5.178: graceful shutdown, CSRF_SECRET fail-fast, /ready probe

This commit is contained in:
2026-06-22 20:02:01 +04:00
parent d8f8c00f30
commit 73afce35bd
3 changed files with 29 additions and 4 deletions
+27 -2
View File
@@ -74,10 +74,22 @@ async function start() {
console.error('FATAL: DB_PASS не задан в production!');
process.exit(1);
}
if (!process.env.CSRF_SECRET || process.env.CSRF_SECRET === 'dev-csrf-secret-change-in-prod') {
console.error('FATAL: CSRF_SECRET не задан или равен дефолту в production!');
process.exit(1);
}
}
// k8s liveness probe — простая проверка что сервер жив
// k8s liveness + readiness probes
app.get('/healthz', (req, res) => res.send('OK'));
app.get('/ready', async (req, res) => {
try {
await pool.query('SELECT 1');
res.send('OK');
} catch (e) {
res.status(503).send('DB not ready');
}
});
// JWKS endpoint для валидации токенов внешними сервисами (только в mock-режиме)
if (auth.jwksHandler) app.get('/.well-known/jwks.json', auth.jwksHandler);
@@ -123,7 +135,20 @@ async function start() {
// Запускаем сервер только если файл запущен напрямую (не через require)
if (require.main === module) {
start()
.then(a => a.listen(PORT, () => console.log('Server on port ' + PORT)))
.then(a => {
const server = a.listen(PORT, () => console.log('Server on port ' + PORT));
// Graceful shutdown по SIGTERM (k8s)
process.on('SIGTERM', () => {
console.log('SIGTERM — shutting down...');
server.close(() => {
console.log('HTTP closed');
const { pool } = require('./src/db');
pool.end().then(() => { console.log('DB pool closed'); process.exit(0); });
});
setTimeout(() => { console.log('Forced exit'); process.exit(0); }, 10000);
});
return server;
})
.catch(e => { console.error('Startup error:', e); process.exit(1); });
}