// Production entry: wraps Astro's Node handler with compression, security headers and graceful shutdown. // Run after `npm run build`: node server.mjs (env: HOST, PORT, DATA_DIR) import http from 'node:http'; import compression from 'compression'; process.env.ASTRO_NODE_AUTOSTART = 'disabled'; const { handler } = await import('./dist/server/entry.mjs'); const HOST = process.env.HOST ?? '0.0.0.0'; const PORT = Number(process.env.PORT ?? 4321); const compress = compression({ threshold: 1024 }); const securityHeaders = { 'X-Content-Type-Options': 'nosniff', 'Referrer-Policy': 'strict-origin-when-cross-origin', 'X-Frame-Options': 'SAMEORIGIN', 'Permissions-Policy': 'camera=(), microphone=(), geolocation=(), interest-cohort=()', }; const server = http.createServer((req, res) => { for (const [k, v] of Object.entries(securityHeaders)) res.setHeader(k, v); compress(req, res, () => handler(req, res)); }); server.listen(PORT, HOST, () => console.log(`ta1sph.info listening on http://${HOST}:${PORT}`)); // Docker/Dokploy send SIGTERM on redeploy: finish in-flight requests, then exit. for (const signal of ['SIGTERM', 'SIGINT']) { process.on(signal, () => { server.close(() => process.exit(0)); setTimeout(() => process.exit(0), 10_000).unref(); }); }