diff --git a/.gitignore b/.gitignore index 557302f..46d3430 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ out/ medialore.db medialore.db-shm medialore.db-wal -tsconfig.tsbuildinfo \ No newline at end of file +tsconfig.tsbuildinfo +.session_secret \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 83b543b..547a279 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,13 +6,18 @@ services: environment: PORT: 3000 NODE_ENV: production + # CONFIG_PATH points db.ts and secret.ts at the config volume so medialore.db + # and .session_secret are created as files inside an existing directory mount. + # Without this Docker will create ./medialore.db on the host as an empty directory, + # which causes better-sqlite3 to fail with SQLITE_CANTOPEN. + CONFIG_PATH: /config + # Set to "true" only when serving over HTTPS (e.g. behind a TLS reverse proxy). + # Keeping this "false" allows the session cookie to be sent over plain HTTP. + COOKIE_SECURE: "false" volumes: - # Runtime data — must map to /app/ since process.cwd() = /app in the container - - ./medialore.db:/app/medialore.db - ./.thumbnails:/app/.thumbnails - # Library config — mounted as a directory so the atomic rename in the API works. - # A single-file bind-mount causes EBUSY on rename() because .tmp and the target - # end up on different devices. Initialize before first run: + # Library config, database, and session secret — all in one directory volume. + # Initialize before first run: # mkdir -p config && echo '[]' > config/libraries.json - ./config:/config diff --git a/src/lib/auth.ts b/src/lib/auth.ts index 2411436..3385ddf 100644 --- a/src/lib/auth.ts +++ b/src/lib/auth.ts @@ -17,7 +17,7 @@ export function getSessionOptions(): SessionOptions { cookieName: 'ml_session', ttl: 60 * 60 * 24 * 30, // 30 days cookieOptions: { - secure: process.env.NODE_ENV === 'production', + secure: process.env.COOKIE_SECURE === 'true', httpOnly: true, sameSite: 'lax', },