feat(db): make the SQLite journal mode configurable (#1675)

WAL was hardcoded, and on network-backed storage — Azure App Service Linux,
SMB/NFS volumes on NAS and PaaS — SQLite documents it as unsafe, because the
coordination runs through the -shm file and mmap. Operators had no way out.

TREK_DB_JOURNAL_MODE and TREK_DB_SYNCHRONOUS now set both pragmas, defaulting
to today's behaviour. The mode lives in the file header, so all three
processes that open travel.db read the same configuration — the server,
reset-admin.js and migrate-encryption.ts, which used to hard-set WAL and would
have silently reverted a deliberate DELETE setup on the first key rotation.

An invalid value falls back and warns rather than refusing to start, and the
mode that actually took effect is read back and logged, so an operator can see
whether the setting landed.
This commit is contained in:
Maurice
2026-07-29 16:42:59 +02:00
committed by Maurice
parent e62dceb4bb
commit 98ad2450a2
10 changed files with 430 additions and 4 deletions
+3
View File
@@ -43,6 +43,9 @@ DEMO_MODE=false # Demo mode - resets data hourly
# BACKUP_UPLOAD_LIMIT_MB=500 # Max size (MB) of a backup archive you can upload when restoring. Raise it if your backup exceeds 500 MB. If you sit behind a reverse proxy, raise its upload limit too (e.g. nginx client_max_body_size).
# TREK_DB_JOURNAL_MODE=WAL # SQLite journal mode (DELETE, TRUNCATE, PERSIST, MEMORY, WAL, OFF). WAL is fastest and the right choice on local disk. Set DELETE if the data directory lives on network storage (Azure App Service, an SMB/NFS volume on a NAS) — WAL coordinates writers through a shared-memory file that those filesystems do not implement reliably. The mode is stored inside the database file, so it survives a restart; changing this applies on the next boot.
# TREK_DB_SYNCHRONOUS=NORMAL # How hard SQLite flushes to disk (OFF, NORMAL, FULL, EXTRA). Defaults to NORMAL under WAL and FULL under any other journal mode — leave it alone unless you know why you want otherwise. Both variables fall back to their default (with a warning in the log) if the value is not a mode SQLite knows.
# MCP_RATE_LIMIT=300 # Max MCP API requests per user per minute (default: 300)
# MCP_MAX_SESSION_PER_USER=20 # Max concurrent MCP sessions per user (default: 20)