From 69f7289b4ab0a4afcccf7003021940f7aaf187e3 Mon Sep 17 00:00:00 2001 From: librelad Date: Sat, 23 May 2026 15:12:55 +0100 Subject: [PATCH] feat(backup): declare server databases + fail safe to stop on dump failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add libreportal.backup.db labels to the MariaDB/Postgres apps (nextcloud, owncloud, bookstack, mastodon, invidious) so they back up live + consistent. - If a declared dump cannot be taken (DB down, wrong path), the backup falls back to stop-snapshot-start for that run instead of snapshotting torn data — a misconfiguration degrades to 'safe with downtime', never to 'unsafe'. Co-Authored-By: Claude Opus 4.7 Signed-off-by: librelad --- containers/bookstack/docker-compose.yml | 1 + containers/invidious/docker-compose.yml | 1 + containers/mastodon/docker-compose.yml | 1 + containers/nextcloud/docker-compose.yml | 1 + containers/owncloud/docker-compose.yml | 1 + scripts/backup/app/backup_app_start.sh | 7 ++++++- scripts/backup/db/backup_db.sh | 7 ++++++- 7 files changed, 17 insertions(+), 2 deletions(-) diff --git a/containers/bookstack/docker-compose.yml b/containers/bookstack/docker-compose.yml index 5bb0f13..1c93a4d 100755 --- a/containers/bookstack/docker-compose.yml +++ b/containers/bookstack/docker-compose.yml @@ -32,6 +32,7 @@ services: labels: libreportal.category: "CATEGORY_DATA" #LIBREPORTAL|CATEGORY_TAG|CATEGORY_DATA libreportal.title: "TITLE_DATA" #LIBREPORTAL|TITLE_TAG|TITLE_DATA + libreportal.backup.db: "mariadb:bookstack_db:db:" traefik.enable: TRAEFIK_ENABLE_DATA #LIBREPORTAL|TRAEFIK_ENABLE_TAG|TRAEFIK_ENABLE_DATA # TRAEFIK_PORT_1_BEGIN traefik.http.routers.bookstack-service.entrypoints: web,websecure diff --git a/containers/invidious/docker-compose.yml b/containers/invidious/docker-compose.yml index 1aba516..2bbb4a2 100644 --- a/containers/invidious/docker-compose.yml +++ b/containers/invidious/docker-compose.yml @@ -42,6 +42,7 @@ services: labels: libreportal.category: "CATEGORY_DATA" #LIBREPORTAL|CATEGORY_TAG|CATEGORY_DATA libreportal.title: "TITLE_DATA" #LIBREPORTAL|TITLE_TAG|TITLE_DATA + libreportal.backup.db: "postgres:invidious-db:postgresdata:" traefik.enable: TRAEFIK_ENABLE_DATA #LIBREPORTAL|TRAEFIK_ENABLE_TAG|TRAEFIK_ENABLE_DATA # TRAEFIK_PORT_1_BEGIN traefik.http.routers.invidious-service.entrypoints: web,websecure diff --git a/containers/mastodon/docker-compose.yml b/containers/mastodon/docker-compose.yml index fcadaa0..0a0c70f 100755 --- a/containers/mastodon/docker-compose.yml +++ b/containers/mastodon/docker-compose.yml @@ -36,6 +36,7 @@ services: labels: libreportal.category: "CATEGORY_DATA" #LIBREPORTAL|CATEGORY_TAG|CATEGORY_DATA libreportal.title: "TITLE_DATA" #LIBREPORTAL|TITLE_TAG|TITLE_DATA + libreportal.backup.db: "postgres:mastodon-postgres:postgres:" traefik.enable: TRAEFIK_ENABLE_DATA #LIBREPORTAL|TRAEFIK_ENABLE_TAG|TRAEFIK_ENABLE_DATA # TRAEFIK_PORT_1_BEGIN traefik.http.routers.mastodon-service.entrypoints: web,websecure diff --git a/containers/nextcloud/docker-compose.yml b/containers/nextcloud/docker-compose.yml index c95492e..efb0c21 100644 --- a/containers/nextcloud/docker-compose.yml +++ b/containers/nextcloud/docker-compose.yml @@ -31,6 +31,7 @@ services: labels: libreportal.category: "CATEGORY_DATA" #LIBREPORTAL|CATEGORY_TAG|CATEGORY_DATA libreportal.title: "TITLE_DATA" #LIBREPORTAL|TITLE_TAG|TITLE_DATA + libreportal.backup.db: "mariadb:nextcloud-db:db_data:" traefik.enable: TRAEFIK_ENABLE_DATA #LIBREPORTAL|TRAEFIK_ENABLE_TAG|TRAEFIK_ENABLE_DATA # TRAEFIK_PORT_1_BEGIN traefik.http.routers.nextcloud-service.entrypoints: web,websecure diff --git a/containers/owncloud/docker-compose.yml b/containers/owncloud/docker-compose.yml index 3200e19..0f7fa55 100755 --- a/containers/owncloud/docker-compose.yml +++ b/containers/owncloud/docker-compose.yml @@ -32,6 +32,7 @@ services: labels: libreportal.category: "CATEGORY_DATA" #LIBREPORTAL|CATEGORY_TAG|CATEGORY_DATA libreportal.title: "TITLE_DATA" #LIBREPORTAL|TITLE_TAG|TITLE_DATA + libreportal.backup.db: "mariadb:owncloud-mariadb:mysql:" traefik.enable: TRAEFIK_ENABLE_DATA #LIBREPORTAL|TRAEFIK_ENABLE_TAG|TRAEFIK_ENABLE_DATA # TRAEFIK_PORT_1_BEGIN traefik.http.routers.owncloud-service.entrypoints: web,websecure diff --git a/scripts/backup/app/backup_app_start.sh b/scripts/backup/app/backup_app_start.sh index 2607a52..0de894c 100755 --- a/scripts/backup/app/backup_app_start.sh +++ b/scripts/backup/app/backup_app_start.sh @@ -41,7 +41,12 @@ backupAppStart() dockerComposePause "$stored_app_name" 2>/dev/null || dockerComposeDown "$stored_app_name" elif [[ "$strategy" == "live" ]]; then isNotice "Live strategy — containers stay running; databases dumped consistently" - backupDbDump "$stored_app_name" + if ! backupDbDump "$stored_app_name"; then + isError "Live database dump failed — falling back to stop-snapshot-start for safety" + sudo rm -rf "${containers_dir:?}$stored_app_name/.lp-backup" + strategy="stop-snapshot-start" + dockerComposeDown "$stored_app_name" + fi else dockerComposeDown "$stored_app_name" fi diff --git a/scripts/backup/db/backup_db.sh b/scripts/backup/db/backup_db.sh index eea222a..336cf4c 100644 --- a/scripts/backup/db/backup_db.sh +++ b/scripts/backup/db/backup_db.sh @@ -159,7 +159,12 @@ backupDbDump() isNotice "Dumping sqlite ($path) — live, consistent" local src="$app_dir/$path" if [[ ! -f "$src" ]]; then - isNotice "sqlite file $path not present yet — skipping" + # Declared but not found — could be a fresh app, or a wrong + # path. Treat as a dump failure so the caller falls back to + # the safe stop-snapshot-start rather than snapshotting a + # live sqlite file untorn. + isError "sqlite file $path not found — cannot dump" + rc=1 continue fi # .backup takes a consistent copy even while the app writes.