Add entrypoint fallback for missing bind-mounted scripts

- scripts/entrypoint.sh (new): prefers the live bind-mounted backup-cron.sh, but falls back to a copy baked into the image at build time if the mount is missing. If neither exists, it stays up and idle (instead of crash-looping) so the container remains reachable via console/exec for diagnosis.
- scripts/backup-cron.sh (updated): resolves db-backup.sh the same live-or-fallback way, re-checked on every loop iteration, so if the bind mount comes back healthy later, this container picks up the live scripts on its next backup run with no restart needed.
- scripts/backup.Dockerfile (updated): bakes all three scripts into the image under /app/scripts-default/ as the fallback, and sets the new wrapper as ENTRYPOINT.
This commit is contained in:
2026-08-04 18:44:34 -07:00
parent a9b22f2add
commit 6c1dc7d45f
3 changed files with 82 additions and 6 deletions

43
scripts/entrypoint.sh Normal file
View File

@@ -0,0 +1,43 @@
#!/bin/sh
# Entrypoint for the `backup` sidecar. Prefers the live, bind-mounted copy of
# backup-cron.sh at /scripts (so it can be edited without a rebuild), and
# falls back to the copy baked into this image at build time if that bind
# mount is missing, empty, or stale.
#
# Why this exists: the previous entrypoint ran `/bin/sh /scripts/backup-cron.sh`
# directly. If that file wasn't there -- e.g. because the host directory
# backing the ./scripts bind mount hadn't been populated by whatever deploy
# process manages this stack -- the container failed instantly, and
# `restart: unless-stopped` retried in a tight crash loop forever: fast enough
# that the container was never "running" long enough for `docker exec` or
# Portainer's console to attach. That made the failure itself undiagnosable
# from inside the container -- you could only ever see it in the logs, and
# only by getting lucky with timing. This wrapper guarantees something always
# runs, and that the container always stays reachable, even in the worst case.
set -u
LIVE="/scripts/backup-cron.sh"
FALLBACK="/app/scripts-default/backup-cron.sh"
if [ -f "$LIVE" ]; then
echo "[entrypoint] using live scripts from /scripts (bind mount present)"
exec /bin/sh "$LIVE"
fi
echo "[entrypoint] WARNING: $LIVE not found." >&2
echo "[entrypoint] The ./scripts bind mount is missing, empty, or stale on the host." >&2
echo "[entrypoint] Check the directory backing that mount (see docker-compose.yml)." >&2
if [ -f "$FALLBACK" ]; then
echo "[entrypoint] Falling back to the scripts baked into this image at build time." >&2
echo "[entrypoint] Backups will still run, on whatever version was current when this" >&2
echo "[entrypoint] image was last built -- not any newer live edits to ./scripts." >&2
exec /bin/sh "$FALLBACK"
fi
echo "[entrypoint] FATAL: no backup-cron.sh in the bind mount or the image." >&2
echo "[entrypoint] Staying up (idle) instead of crash-looping, so this container" >&2
echo "[entrypoint] can still be reached via 'docker exec' / the Portainer console." >&2
while true; do
sleep 3600
done