feat(deploy): make the all-in-one image installable without a shell (#1124)

The all-in-one image could not be installed from a GUI at all — the deployment it
exists for. validateEnv treats a missing JWT_SECRET as critical and exits, and the
documented run command supplies it with `openssl rand`, a shell command a Synology
Container Manager or QNAP Container Station form cannot run.

wait-for-db.sh now generates one on first start and persists it next to the database,
extending the existing /run/secrets hydration rather than adding a second mechanism.
Explicit env still wins, then /run/secrets, then the generated file. The write is
load-bearing: JWT_SECRET is exported only when the file actually persisted, because an
unpersisted secret would mint a new one every restart and sign every session out.

Creation writes to a private temp file and hard-links it into place — atomic, fails with
EEXIST when another container won, and the loser adopts the winner's value. Non-regular
paths are rejected before the link, since POSIX ln links INTO a directory rather than
failing, which would make a mistyped -v target unrecoverable.

Also repairs the onboarding paths a new install actually walks: the installer no longer
rotates the secrets of a running install on re-run, deprecates the dead scripts/install.sh
in place, corrects the CONTRIBUTING dev loop, and fixes the vite proxy target that had
been pointing at a stray local port since 0da45e69.

Reviewed over three rounds. Co-authored by @Luca-Timo.
This commit is contained in:
Luca
2026-08-22 18:37:12 +02:00
committed by GitHub
parent 8f23118782
commit 7223118b89
9 changed files with 475 additions and 45 deletions
+24
View File
@@ -1,6 +1,30 @@
#!/bin/bash
set -e
# DEPRECATED — do not use. Superseded by scripts/picpeak-setup.sh.
#
# This script predates the current deployment layout and no longer works. It
# refers to two files that do not exist (docker-compose.prod.yml and
# scripts/setup-ssl.sh), and its `sed` calls now match the COMMENTED lines in
# the current .env.example, so they produce `#JWT_SECRET=<random>` — still
# commented, so no secret is ever set. It fails silently rather than loudly,
# which is the worst outcome for an installer.
#
# Nothing in the repository references it. It is kept as a stub only so an old
# bookmark or copied command gets a signpost instead of a broken install; the
# body below is unreachable and can be deleted outright whenever convenient.
cat >&2 <<'DEPRECATED'
scripts/install.sh is deprecated and does nothing.
Use the current installer instead:
./scripts/picpeak-setup.sh
Or run the stack directly — see the Quick Start in README.md, or
docs/single-container.md for the single-container image.
DEPRECATED
exit 1
echo "Photo Sharing Platform - Docker Installation"
echo "==========================================="