Deploy: create the data directories instead of assuming Docker will

"Bind mount failed: '/volume1/docker/webmail/data/postgres' doesn't exists" on
Synology after the data directory was removed. Docker on ordinary Linux creates
a missing bind-mount source silently; DSM's daemon refuses and fails the
container. Every service mounted its own subdirectory, so every one of them
needed to already exist — including the `init` service whose whole job was to
create them, which could therefore never run.

- init now mounts DATA_ROOT itself, once, and creates postgres/blobs/backups/
  redis/meili/state inside it. Only DATA_ROOT has to pre-exist.
- postgres gained the init dependency it was missing, so its data directory is
  never demanded before init has made it.
- init only runs `chown -R` when ownership is actually wrong, rather than
  walking the whole blob store on every start.
- webmail.sh up creates DATA_ROOT and, if it cannot, says so with the mkdir to
  run rather than leaving the daemon to produce the error above.

Verified from an empty DATA_ROOT: init creates all six directories, postgres
starts after it, migrations apply, stack serves.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nux3LCu4zP9nih4BRhPyHw
This commit is contained in:
2026-09-14 20:41:09 +02:00
co-authored by Claude Opus 5
parent 8f96a1ecae
commit ff64a5dfe7
2 changed files with 24 additions and 12 deletions
+9 -4
View File
@@ -326,10 +326,15 @@ cmd_up() {
ylw "SEARCH_BACKEND=meili — starting the Meilisearch container too"
profile=(--profile meili)
}
# Best-effort only: Docker creates any missing bind-mount path itself, and
# the `init` service fixes ownership. This line must not be fatal, because
# DATA_ROOT is typically root-owned while you may be running as yourself.
mkdir -p "${DATA_ROOT}"/{postgres,blobs,redis,backups,meili,state} 2>/dev/null || true
# DATA_ROOT must exist before compose runs: Synology's Docker daemon will
# not create a missing bind-mount source, it just fails the container. The
# `init` service creates the subdirectories from there.
mkdir -p "${DATA_ROOT}" 2>/dev/null || true
if [ ! -d "${DATA_ROOT}" ]; then
die "cannot create ${DATA_ROOT} (running as $(id -un)). Create it first:
sudo mkdir -p ${DATA_ROOT}
then re-run this command."
fi
detect_compose
# shellcheck disable=SC2086
compose "${profile[@]}" up -d "${build[@]}" $COMPOSE_WAIT