From ca29bc8b7497ad2859b9a4b0839aae869286d8ce Mon Sep 17 00:00:00 2001 From: Jim Lancaster <40281233+zoltan57@users.noreply.github.com> Date: Wed, 26 Aug 2026 14:26:15 -0500 Subject: [PATCH] Continued work on backup script, methodology --- .gitignore | 1 + deploy/backup/mount_synology_cifs.example.sh | 36 ++++++++++++++++++++ docs/backup_restore.md | 19 +++++++++++ docs/production-runbook.md | 1 + 4 files changed, 57 insertions(+) create mode 100644 deploy/backup/mount_synology_cifs.example.sh diff --git a/.gitignore b/.gitignore index f06a874..e81e291 100644 --- a/.gitignore +++ b/.gitignore @@ -29,4 +29,5 @@ data-migration-test/* # Cloudflare tunnel local runtime files deploy/cloudflared/config.yml +deploy/cloudflared/config.yaml deploy/cloudflared/credentials.json diff --git a/deploy/backup/mount_synology_cifs.example.sh b/deploy/backup/mount_synology_cifs.example.sh new file mode 100644 index 0000000..7b35575 --- /dev/null +++ b/deploy/backup/mount_synology_cifs.example.sh @@ -0,0 +1,36 @@ +#!/usr/bin/env sh +set -eu + +# Example only. Copy to a local script and replace placeholder values. +# Do NOT commit secrets. + +SHARE="//nas-host-or-ip/share-name" +MOUNT_POINT="/mnt/nas-backups" +CREDENTIALS_FILE="/etc/samba/credentials/nas-share-credentials" +USERNAME="replace-with-nas-user" +PASSWORD="replace-with-nas-password" + +if [ "${USERNAME}" = "replace-with-nas-user" ] || [ "${PASSWORD}" = "replace-with-nas-password" ]; then + echo "Edit USERNAME and PASSWORD placeholders before running this script." + exit 1 +fi + +mkdir -p "${MOUNT_POINT}" +mkdir -p "$(dirname "${CREDENTIALS_FILE}")" + +cat > "${CREDENTIALS_FILE}" <<'EOF' +username=__USERNAME__ +password=__PASSWORD__ +EOF +sed -i "s|__USERNAME__|${USERNAME}|g" "${CREDENTIALS_FILE}" +sed -i "s|__PASSWORD__|${PASSWORD}|g" "${CREDENTIALS_FILE}" +chmod 600 "${CREDENTIALS_FILE}" + +mount -t cifs "${SHARE}" "${MOUNT_POINT}" \ + -o "credentials=${CREDENTIALS_FILE},vers=3.0,iocharset=utf8,uid=0,gid=0,file_mode=0600,dir_mode=0700" + +echo "" +echo "Mounted ${SHARE} at ${MOUNT_POINT}" +echo "" +echo "To persist across reboot, add this line to /etc/fstab:" +echo "${SHARE} ${MOUNT_POINT} cifs credentials=${CREDENTIALS_FILE},vers=3.0,iocharset=utf8,uid=0,gid=0,file_mode=0600,dir_mode=0700,_netdev,nofail,x-systemd.automount 0 0" diff --git a/docs/backup_restore.md b/docs/backup_restore.md index 96a4a38..bd7181d 100644 --- a/docs/backup_restore.md +++ b/docs/backup_restore.md @@ -33,6 +33,25 @@ Example with Synology mount: SYNOLOGY_BACKUP_DIR=/mnt/synology/transcription-backups sh deploy/backup/create_postgres_backup.sh ``` +## 2.1 Persisting Synology mount (LXC) + +The backup copy step depends on a mounted NAS path. Manual `mount` commands are lost after reboot unless persisted. + +Use the template (copy, edit placeholders, then run): + +```bash +cp deploy/backup/mount_synology_cifs.example.sh /root/mount_synology_cifs.sh +nano /root/mount_synology_cifs.sh +sh /root/mount_synology_cifs.sh +``` + +Then add the printed `/etc/fstab` line (with your real values) so the mount survives reboot. + +Recommended pattern: + +- Keep NAS credentials in a local file like `/etc/samba/credentials/transcription-synology` with `chmod 600`. +- Keep `SYNOLOGY_BACKUP_DIR` in `.env.production` aligned to that mount point (for example `/mnt/synology-backups`). + ## 3. Restoring from backup Restore requires downtime for app + worker writes. diff --git a/docs/production-runbook.md b/docs/production-runbook.md index 25d6da9..8bd2615 100644 --- a/docs/production-runbook.md +++ b/docs/production-runbook.md @@ -109,6 +109,7 @@ This runbook is the operational checklist for releasing and monitoring the trans 2. Confirm dump file exists and is non-zero size. 3. Re-run backup/restore scripts with explicit `ENV_FILE` and `COMPOSE_FILE` if using non-default paths. 4. If Synology copy fails, keep local backup and resolve mount/network before next backup cycle. + - For LXC setups, use `deploy/backup/mount_synology_cifs.example.sh` as the persistent mount template. ## 6. Dependency upgrade policy