Fix #760: chown /app/storage to PUID on every start (album-bundle staging EACCES)

The album-bundle staging area /app/storage is baked into the image owned by the
build-time soulsync UID. The entrypoint only re-chowned it to the runtime PUID
inside the GATED recursive chown (entrypoint.sh:43), which is skipped whenever
/app/data is already owned correctly — and /app/storage was missing from the
UNCONDITIONAL per-start chown (line 85). So on installs whose PUID differs from
the build UID and whose /app/data is already correct, /app/storage kept its
build ownership and wasn't writable, and the Soulseek album-bundle flow died
with:

  PermissionError: [Errno 13] Permission denied: 'storage/album_bundle_staging'

(/app/Stream was added to the unconditional chown after this exact bug;
/app/storage slipped through.)

Add /app/storage — plus /app/MusicVideos and /app/scripts, which were also
missing — to the unconditional mkdir+chown (lines 84-85) and the writability
audit (line 92), matching the Dockerfile's pre-baked dir list. /app/storage is
now chowned to the runtime PUID on every start regardless of the gated
recursive chown. Verified with bash -n; all four dir lists are now consistent.
pull/761/head
BoulderBadgeDad 1 week ago
parent cea0e365c2
commit aabf1c0e6a

@ -81,15 +81,15 @@ chown soulsync:soulsync /app/config/settings.py 2>/dev/null || true
# Pre-mid-2026 the chown line had `|| true` but mkdir didn't — combined
# with `set -e`, a permission-denied mkdir crashed the container into a
# restart loop. Both lines are now best-effort.
mkdir -p /app/config /app/data /app/logs /app/downloads /app/Transfer /app/Staging /app/Stream 2>/dev/null || true
chown soulsync:soulsync /app/config /app/data /app/logs /app/downloads /app/Transfer /app/Staging /app/Stream 2>/dev/null || true
mkdir -p /app/config /app/data /app/logs /app/downloads /app/Transfer /app/Staging /app/Stream /app/storage /app/MusicVideos /app/scripts 2>/dev/null || true
chown soulsync:soulsync /app/config /app/data /app/logs /app/downloads /app/Transfer /app/Staging /app/Stream /app/storage /app/MusicVideos /app/scripts 2>/dev/null || true
# Writability audit — surface a loud warning if any bind-mounted dir
# isn't writable by the soulsync user. The restart-loop fix above makes
# the container start regardless, but a non-writable Staging / downloads
# / Transfer will fail silently inside the app (auto-import quarantine,
# download writes). Better to log now than to debug missing files later.
for dir in /app/config /app/data /app/logs /app/downloads /app/Transfer /app/Staging /app/Stream /app/MusicVideos /app/scripts; do
for dir in /app/config /app/data /app/logs /app/downloads /app/Transfer /app/Staging /app/Stream /app/storage /app/MusicVideos /app/scripts; do
if [ -d "$dir" ] && ! gosu soulsync test -w "$dir" 2>/dev/null; then
echo "⚠️ WARNING: $dir is not writable by soulsync (uid $(id -u soulsync))."
echo " Host bind-mount perms likely mismatch the PUID/PGID env vars."

Loading…
Cancel
Save