From ba5ad005a68abb3d2b2d0470e5b3557d85ffb50d Mon Sep 17 00:00:00 2001 From: oliver Date: Tue, 21 Apr 2026 12:45:18 -0300 Subject: [PATCH] Backup --- app/backup | 70 +++++++++++++++++++++++++++++++++++------------------- app/update | 7 +++--- 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/app/backup b/app/backup index b0e8339..28988a5 100755 --- a/app/backup +++ b/app/backup @@ -2,42 +2,64 @@ set -euo pipefail # === CONFIG === -REPO="/backups/borgrepo" -HOSTS_FILE="host_vars/hosts" -ARCHIVE_NAME="backup-$(date +%Y-%m-%d)" +REPO="/backup/borgrepo" +export BORG_PASSPHRASE +BORG_PASSPHRASE="$(cat /app/host_vars/repokey)" +HOSTS_FILE="$(dirname "$0")/host_vars/hosts" +TIMESTAMP="$(date +%Y-%m-%dT%H%M%S)" # === BUILD SOURCE LIST === SOURCES=() while read -r host; do [[ -z "$host" || "$host" =~ ^# ]] && continue - SOURCES+=("${host}:/") + SOURCES+=("${host}:/BACKUP/") done < "$HOSTS_FILE" +if [[ ${#SOURCES[@]} -eq 0 ]]; then + echo "ERROR: No hosts found in $HOSTS_FILE" + exit 1 +fi + echo "Backing up hosts:" printf ' - %s\n' "${SOURCES[@]}" -# === CREATE BACKUP (ONLY current*) === -borg create \ - "$REPO::$ARCHIVE_NAME" \ - "${SOURCES[@]}" \ - --patterns-from <(cat <<'EOF' -R sh:** -+ sh:**/current* -- sh:** -EOF -) \ - --stats \ - --compression lz4 +# === CREATE BACKUP PER HOST === +FAILED_HOSTS=() -# === RETENTION POLICY === +for src in "${SOURCES[@]}"; do + HOST="${src%%:*}" + ARCHIVE="${HOST}-backup-${TIMESTAMP}" + echo "--- Backing up $HOST ---" + + borg create \ + "$REPO::$ARCHIVE" \ + "$src" \ + --stats \ + --compression lz4 || { + echo "WARNING: Failed to back up $HOST" + FAILED_HOSTS+=("$HOST") + } +done + +# === RETENTION POLICY (per host) === echo "Applying retention policy..." -borg prune \ - "$REPO" \ - --keep-daily=7 \ - --keep-weekly=8 \ - --prefix "backup-" \ - --stats +for src in "${SOURCES[@]}"; do + HOST="${src%%:*}" + borg prune \ + "$REPO" \ + --keep-daily=7 \ + --keep-weekly=8 \ + --glob-archives "${HOST}-backup-*" \ + --stats +done -echo "Done: $ARCHIVE_NAME" +# === FINAL REPORT === +if [[ ${#FAILED_HOSTS[@]} -gt 0 ]]; then + echo "DONE WITH ERRORS — Failed hosts:" + printf ' - %s\n' "${FAILED_HOSTS[@]}" + exit 1 +fi + +echo "Done: all hosts backed up at $TIMESTAMP" diff --git a/app/update b/app/update index 220393c..6f782c4 100755 --- a/app/update +++ b/app/update @@ -23,9 +23,9 @@ rex doas chown 4server:4server /4server/tmp template templates/.profile /home/4server/.profile ### PACKAGES -template templates/repositories /etc/apk/repositories +template templates/repositories /etc/apk/repositories rex "doas apk update && doas apk upgrade" -rex doas apk add iperf linux-lts openssh ufw python3 build-base python3-dev linux-headers py3-pip gcc g++ musl-dev libffi-dev make jq rsync mc vim docker docker-compose htop linux-lts sqlite bash postgresql16-client +rex doas apk add borgbackup iperf linux-lts openssh ufw python3 build-base python3-dev linux-headers py3-pip gcc g++ musl-dev libffi-dev make jq rsync mc vim docker docker-compose htop linux-lts sqlite bash postgresql16-client rex doas pip install --root-user-action ignore --break-system-packages --no-cache-dir "uvicorn[standard]" fastapi pydantic psutil gdown @@ -92,6 +92,5 @@ rex mkdir -p /4server/data/traefik/etc/certs echo "prsync traefik certs" prsync -h "/app/host_vars/hosts" -avz ./etc/traefik/certs/* /4server/data/traefik/etc/certs/ -template templates/docker-compose.yml /4server/docker-compose.yml +template templates/docker-compose.yml /4server/docker-compose.yml rex doas docker-compose -f /4server/docker-compose.yml up -d --force-recreate -