195 lines
5.7 KiB
Bash
195 lines
5.7 KiB
Bash
#!/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"
|
||
)
|
||
|
||
|
||
# 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 EXIT 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 "============================================"
|
||
|