feat: add Docker image, production server and health check

- Multi-stage Dockerfile on node:24-slim, non-root, healthcheck, /app/data volume
- server.mjs wraps the Astro handler with brotli/gzip compression,
  security headers and graceful SIGTERM shutdown (npm start)
- GET /api/health/ reports server and view-counter DB status
- Move build-only packages to devDependencies (smaller runtime image)
- docker-compose.yml as an alternative for Dokploy Compose

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-16 02:58:45 +03:00
parent 7d8fcce2e1
commit 91cb337c03
10 changed files with 446 additions and 28 deletions
+10
View File
@@ -64,3 +64,13 @@ export function clientIp(request: Request, fallback: string): string {
export const isBot = (ua: string | null) =>
!ua || /bot|crawl|spider|slurp|preview|facebookexternalhit|headless|lighthouse/i.test(ua);
/** Health probe: the database opens and answers a trivial query. */
export function dbHealthy(): boolean {
try {
open().prepare('SELECT 1').get();
return true;
} catch {
return false;
}
}
+13
View File
@@ -0,0 +1,13 @@
import type { APIRoute } from 'astro';
import { dbHealthy } from '../../lib/views';
export const prerender = false;
// GET /api/health — Docker HEALTHCHECK / Dokploy. 503 if the view-counter DB is unavailable.
export const GET: APIRoute = () => {
const db = dbHealthy();
return Response.json(
{ status: db ? 'ok' : 'degraded', db },
{ status: db ? 200 : 503, headers: { 'Cache-Control': 'no-store' } },
);
};