Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 16 additions & 9 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,33 @@ COPY static/ static/

RUN npm run build

# Production stage — minimal runtime with native module support
# Production stage — minimal runtime
FROM node:22-slim

RUN apt-get update && apt-get install -y --no-install-recommends \
python3 make g++ && rm -rf /var/lib/apt/lists/*

WORKDIR /app

COPY package.json package-lock.json ./
RUN npm ci --omit=dev

RUN apt-get remove -y python3 make g++ && apt-get autoremove -y && rm -rf /var/lib/apt/lists/*

COPY --from=builder /app/node_modules node_modules/
COPY --from=builder /app/build build/

RUN mkdir -p /app/data/viirs /app/data/gan

# Handle bind mount creating a directory when SQLite file does not exist.
# Docker bind mounts a non-existent file as a directory, which breaks better-sqlite3.
# This entrypoint script checks and fixes the mismatch before starting.
RUN printf '#!/bin/sh\n\
DB_PATH="/app/duskmeter.sqlite"\n\
if [ -d "$DB_PATH" ]; then\n\
rmdir "$DB_PATH" 2>/dev/null && touch "$DB_PATH"\n\
fi\n\
if [ ! -e "$DB_PATH" ]; then\n\
touch "$DB_PATH"\n\
fi\n\
exec node build/index.js\n' > /entrypoint.sh && chmod +x /entrypoint.sh

ENV NODE_ENV=production
ENV PORT=3000

EXPOSE 3000

CMD ["node", "build"]
ENTRYPOINT ["/entrypoint.sh"]
2 changes: 2 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ services:
- ./data/viirs:/app/data/viirs
- ./data/gan:/app/data/gan
- ./duskmeter.sqlite:/app/duskmeter.sqlite
extra_hosts:
- "host.docker.internal:host-gateway"
restart: unless-stopped
Binary file modified duskmeter-dev.sqlite-wal
Binary file not shown.
4 changes: 2 additions & 2 deletions src/hooks.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ export const handle: Handle = async ({ event, resolve }) => {

const csp = [
"default-src 'self'",
"script-src 'self'",
"style-src 'self' 'unsafe-inline'",
"script-src 'self' 'unsafe-inline'",
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com",
"img-src 'self' data: https:",
"font-src 'self' https://fonts.gstatic.com",
"connect-src 'self' https://fonts.googleapis.com",
Expand Down
10 changes: 10 additions & 0 deletions src/lib/server/scheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import db from "./db";
import { logger } from "./logger";

let timer: NodeJS.Timeout | null = null;
let currentLockId: string | null = null;

const LOCK_KEY = "scheduler_lock";
const LOCK_TTL_MS = 30 * 60 * 1000;
Expand Down Expand Up @@ -60,6 +61,7 @@ async function runScheduledTasks() {
logger.info("scheduler", "skipped: lock held by another instance");
return;
}
currentLockId = lockId;

logger.info("scheduler", "running assessment + alert check", { instanceId: lockId });
try {
Expand All @@ -70,5 +72,13 @@ async function runScheduledTasks() {
logger.error("scheduler", e, { instanceId: lockId });
} finally {
releaseLock(lockId);
currentLockId = null;
}
}

process.on("sveltekit:shutdown", () => {
if (currentLockId) {
releaseLock(currentLockId);
currentLockId = null;
}
});
Loading