Files
infra-borgbackup-docker/borg-pull-backup.sh
T
2026-05-31 15:13:44 +00:00

182 lines
5.3 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# =============================================================================
# BorgBackup Pull-Script läuft auf dem Raspberry Pi
# Zieht Daten vom Docker-Host per sshfs und sichert sie lokal
# =============================================================================
set -euo pipefail
# =============================================================================
# KONFIGURATION hier anpassen
# =============================================================================
REMOTE_HOST="docker1.lan" # IP oder Hostname des Docker-Hosts
REMOTE_USER="borgbackup" # SSH-User auf dem Docker-Host
SSH_KEY="/home/borg/.ssh/borg_pull" # SSH-Key des borg-Users auf dem Pi
MOUNT_POINT="/mnt/borg-pull/${REMOTE_HOST}" # Temporärer sshfs-Mountpunkt
BORG_REPO="/srv/borg/${REMOTE_HOST}" # Lokales Borg-Repository auf dem Pi
export BORG_PASSPHRASE="W8fCiB0occvcFO" # Borg-Verschlüsselungspasswort
# Was vom Docker-Host gesichert werden soll (Pfade auf dem Remote-Host)
BACKUP_PATHS=(
"etc"
"/mnt/"
"var/lib/docker/volumes"
)
# Ausschlüsse (relativ zum Mountpunkt)
EXCLUDES=(
"--exclude" "${MOUNT_POINT}/var/lib/docker/volumes/*/tmp"
"--exclude" "${MOUNT_POINT}/proc"
"--exclude" "${MOUNT_POINT}/sys"
"--exclude" "${MOUNT_POINT}/dev"
"--exclude" "${MOUNT_POINT}/run"
"--exclude" "${MOUNT_POINT}/tmp"
"--exclude" "${MOUNT_POINT}/var/cache"
"--exclude" "*.pyc"
"--exclude" "*.log"
)
# Aufbewahrungsrichtlinie
KEEP_DAILY=7
KEEP_WEEKLY=4
KEEP_MONTHLY=6
LOG="/var/log/borg-pull-backup.log"
# =============================================================================
# FUNKTIONEN
# =============================================================================
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG"
}
error_exit() {
log "FEHLER: $*"
cleanup
exit 1
}
cleanup() {
log "Aufräumen..."
if mountpoint -q "$MOUNT_POINT" 2>/dev/null; then
log "Unmounte ${MOUNT_POINT}..."
fusermount -u "$MOUNT_POINT" || umount "$MOUNT_POINT" || true
fi
}
# Cleanup auch bei unerwarteten Fehlern
trap cleanup ERR
# =============================================================================
# HAUPTPROGRAMM
# =============================================================================
log "============================================"
log "Starte Pull-Backup von ${REMOTE_USER}@${REMOTE_HOST}"
log "============================================"
# --- 1. Voraussetzungen prüfen ---
for cmd in borg sshfs fusermount ssh; do
command -v "$cmd" &>/dev/null || error_exit "Programm nicht gefunden: $cmd"
done
[ -f "$SSH_KEY" ] || error_exit "SSH-Key nicht gefunden: $SSH_KEY"
[ -d "$BORG_REPO" ] || error_exit "Borg-Repo nicht gefunden: $BORG_REPO erst initialisieren!"
# --- 2. Mountpunkt vorbereiten ---
mkdir -p "$MOUNT_POINT"
if mountpoint -q "$MOUNT_POINT"; then
log "Vorheriger Mount gefunden, unmounte zuerst..."
fusermount -u "$MOUNT_POINT" || true
sleep 2
fi
# --- 3. Docker-Host mounten (read-only!) ---
log "Mounte ${REMOTE_HOST} nach ${MOUNT_POINT} (read-only)..."
sshfs \
-o ro \
-o allow_other \
-o StrictHostKeyChecking=no \
-o IdentityFile="${SSH_KEY}" \
-o ServerAliveInterval=30 \
-o ServerAliveCountMax=3 \
-o reconnect \
"${REMOTE_USER}@${REMOTE_HOST}:/" \
"$MOUNT_POINT" \
|| error_exit "sshfs-Mount fehlgeschlagen"
log "Mount erfolgreich."
# --- 4. Backup-Pfade zusammenbauen ---
FULL_PATHS=()
for p in "${BACKUP_PATHS[@]}"; do
full="${MOUNT_POINT}/${p}"
if [ -d "$full" ]; then
FULL_PATHS+=("$full")
log " Pfad gefunden: $full"
else
log " WARNUNG: Pfad nicht gefunden, wird übersprungen: $full"
fi
done
[ ${#FULL_PATHS[@]} -gt 0 ] || error_exit "Keine gültigen Backup-Pfade gefunden!"
# --- 5. Borg-Backup erstellen ---
ARCHIVE_NAME="${REMOTE_HOST}-$(date '+%Y-%m-%dT%H-%M-%S')"
log "Erstelle Archiv: ${ARCHIVE_NAME}"
# set -e kurz deaktivieren damit rc 1 (Warnung) den Script nicht abbricht
set +e
borg create \
--verbose \
--filter AME \
--list \
--stats \
--show-rc \
--compression lz4 \
--exclude-caches \
"${EXCLUDES[@]}" \
"${BORG_REPO}::${ARCHIVE_NAME}" \
"${FULL_PATHS[@]}" \
2>&1 | tee -a "$LOG"
BORG_EXIT=${PIPESTATUS[0]}
set -e
case $BORG_EXIT in
0) log "Backup erfolgreich abgeschlossen." ;;
1) log "WARNUNG: Backup mit Warnungen abgeschlossen (rc 1 geänderte Dateien o.ä., kein Fehler)." ;;
*) error_exit "Backup fehlgeschlagen (Exit ${BORG_EXIT})." ;;
esac
# --- 6. Unmounten ---
#trap - EXIT ERR
log "Unmounte ${MOUNT_POINT}..."
fusermount -u "$MOUNT_POINT"
log "Unmount erfolgreich."
# --- 7. Alte Archive bereinigen ---
log "Bereinige alte Archive (daily=${KEEP_DAILY}, weekly=${KEEP_WEEKLY}, monthly=${KEEP_MONTHLY})..."
borg prune \
--list \
--glob-archives "${REMOTE_HOST}-*" \
--keep-daily "$KEEP_DAILY" \
--keep-weekly "$KEEP_WEEKLY" \
--keep-monthly "$KEEP_MONTHLY" \
"$BORG_REPO" \
2>&1 | tee -a "$LOG"
# --- 8. Repo komprimieren ---
log "Komprimiere Repository..."
borg compact "$BORG_REPO" 2>&1 | tee -a "$LOG"
log "============================================"
log "Pull-Backup abgeschlossen: ${ARCHIVE_NAME}"
log "============================================"