fix(docker): harden data-dir permissions and surface actionable DB errors

The bind-mount permission fix only takes effect after a rebuild, so a
stale image keeps failing with the opaque "unable to open database file".
This hardens both sides so any remaining failure is self-explanatory:

- docker-entrypoint.sh: fall back to chmod 777 when chown is unsupported
  (network/9p mounts), and fall back to running as root when su-exec is
  unavailable, so the data dir is always writable on any filesystem.
- server/db.mjs: wrap the DatabaseSync open in a try/catch and, on
  failure, report the exact path, whether the directory is writable, and
  the process UID instead of the bare SQLite error.

Verified with a real container: a normal bind mount serves /health and
creates trxtd.db; a read-only mount now prints the directory-permission
diagnostic instead of the raw SQLite error.
This commit is contained in:
Tronax 2026-08-16 16:40:45 +02:00
parent 1abc08b60f
commit d400a4a2a0
Signed by: Tronax
SSH key fingerprint: SHA256:2pKKXDZucWvaF/GzXNz0FY53EAO1YDLN80bqS+TTz/o
2 changed files with 41 additions and 7 deletions

View file

@ -1,11 +1,21 @@
#!/bin/sh
set -e
# Ensure the data directory exists and is owned by the node user.
# This fixes permission issues with bind-mounted volumes (e.g. ./data:/app/data)
# where the host directory is owned by root but the container runs as node.
# Ensure the data directory exists and is writable by the app user on every
# container start. Bind-mounted host directories (docker-compose ./data,
# Unraid appdata, etc.) are often owned by root or "nobody", which would
# otherwise make the unprivileged "node" user unable to create trxtd.db.
mkdir -p /app/data
chown -R node:node /app/data 2>/dev/null || true
# Drop privileges and run the actual application as node
exec su-exec node "$@"
# Prefer chown (sets node:node). On filesystems that do not support chown
# (some network/9p mounts), fall back to making the directory world-writable.
if ! chown -R node:node /app/data 2>/dev/null; then
chmod 777 /app/data 2>/dev/null || true
fi
# Drop privileges to the unprivileged node user when su-exec is available,
# otherwise run as root (still fully functional).
if command -v su-exec >/dev/null 2>&1; then
exec su-exec node "$@"
fi
exec "$@"