167eeaa271
Seven findings, all verified against the code before applying.
- The built-in backup system wrote nowhere. Migrations 029/030 seed
/backup/picpeak and /backup/database as destinations, and this image neither
created nor mounted /backup — so backups failed, and anything written there
would have died with the container. /backup is now a symlink into
/data/backup, so the seeded defaults work and the archives land on the volume
like everything else.
- Database backups need the sqlite3 CLI. DatabaseBackupService spawns it for
.backup and PRAGMA integrity_check; the npm module does not provide the
binary. The compose image omits it because it always runs Postgres — this one
defaults to SQLite, so it failed with ENOENT. Added.
- Every AIO install served literal ${BRAND_TITLE}. index.html carries
placeholders that frontend/docker-entrypoint.sh substitutes at start, and
this image runs no nginx and never invoked it. Rendered at build with the
same defaults that entrypoint applies, and the build now fails if any
${BRAND_*} token survives. Browser testing missed this because the SPA
rewrites document.title at runtime — the og:/twitter: cards and view-source
still showed the raw token.
- The SPA fallback swallowed backend file-route 404s. nginx gives /api,
/photos, /thumbnails and /health their own location blocks, so try_files
never applies to them; excluding only /api/ made the fallback strictly
broader than the behaviour it claimed parity with, turning a missing photo
into a 200 HTML body under an image URL. Now excludes the same set.
- Docs claimed DB_* alone switches the engine. It does not: the image declares
DATABASE_CLIENT=sqlite3 and the resolver treats a declared client as
explicit, so DATABASE_CLIENT=pg is required. Corrected, and /data/backup
added to the documented layout.
- The AIO Trivy upload reused the backend's SARIF category, so the two scans
replaced each other's results instead of both being retained.
- The AIO build reused the backend's buildx cache scope, so two concurrent jobs
wrote the same cache object from different Dockerfiles.
Verified on a rebuilt image: sqlite3 3.53.2 present, <title>PicPeak</title>,
/backup -> /data/backup with both seeded subdirectories, /photos + /thumbnails
+ /api back to 404 while /setup /impressum /gallery/x /admin/login stay 200.