Files
homey/backup-nextcloud.sh
T
2026-04-15 16:49:18 +03:00

121 lines
4.0 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
BACKUP_DIR="$HOME/homey-backup"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
NAMESPACE="homey"
NODE="root@192.168.1.100"
NC_DATA_DEST="$BACKUP_DIR/nextcloud-data/backups/$TIMESTAMP"
NC_DB_DEST="$BACKUP_DIR/nextcloud-postgres/backups/$TIMESTAMP"
show_progress() {
local file="$1"
local label="$2"
local total="${3:-0}"
while [[ ! -f "$file" ]]; do
sleep 0.2
done
while kill -0 "$BACKUP_PID" 2>/dev/null; do
local size=$(stat -c%s "$file" 2>/dev/null || echo "0")
if [[ "$total" -gt 0 ]]; then
local pct=$((size * 100 / total))
local size_hr=$(numfmt --to=iec-i --suffix=B "$size" 2>/dev/null || echo "${size}B")
local total_hr=$(numfmt --to=iec-i --suffix=B "$total" 2>/dev/null || echo "${total}B")
printf "\r%s: %s / %s (%d%%) " "$label" "$size_hr" "$total_hr" "$pct"
else
local size_hr=$(numfmt --to=iec-i --suffix=B "$size" 2>/dev/null || echo "${size}B")
printf "\r%s: %s " "$label" "$size_hr"
fi
sleep 0.5
done
local final=$(stat -c%s "$file" 2>/dev/null || echo "0")
local final_hr=$(numfmt --to=iec-i --suffix=B "$final" 2>/dev/null || echo "${final}B")
printf "\r%s: %s - done! \n" "$label" "$final_hr"
}
wait_for_cluster() {
echo "Waiting for Kubernetes cluster..."
local max_wait=300
local start=$(date +%s)
while true; do
if kubectl get nodes &>/dev/null; then
echo "Cluster ready!"
return 0
fi
local now=$(date +%s)
if [[ $((now - start)) -ge $max_wait ]]; then
echo "ERROR: Cluster not available after ${max_wait}s"
return 1
fi
printf "\rWaiting... %ds " $((now - start))
sleep 5
done
}
echo "=== Nextcloud Backup ==="
echo "Started: $(date)"
mkdir -p "$NC_DATA_DEST"
mkdir -p "$NC_DB_DEST"
if ! wait_for_cluster; then
echo "Cluster unavailable. Cannot proceed."
exit 1
fi
echo ""
echo "--- Backing up PostgreSQL ---"
DB_POD=$(kubectl get pods -n "$NAMESPACE" -l app=nextcloud-postgres -o jsonpath='{.items[0].metadata.name}')
if [[ -z "$DB_POD" ]]; then
echo "ERROR: PostgreSQL pod not found"
exit 1
fi
DB_SIZE=$(kubectl exec -n "$NAMESPACE" "$DB_POD" -- psql -U postgres -d nextcloud_db -t -c "SELECT pg_database_size('nextcloud_db');" 2>/dev/null | tr -d ' ' || echo "0")
echo "Database size: $(numfmt --to=iec-i --suffix=B "$DB_SIZE" 2>/dev/null || echo "$DB_SIZE bytes")"
echo "Dumping database from $DB_POD..."
kubectl exec -n "$NAMESPACE" "$DB_POD" -- sh -c "pg_dump -U postgres nextcloud_db" | gzip > "$NC_DB_DEST/dump.sql.gz" &
BACKUP_PID=$!
show_progress "$NC_DB_DEST/dump.sql.gz" "Database" "$DB_SIZE"
wait $BACKUP_PID 2>/dev/null || true
echo "Database backup: $(du -sh "$NC_DB_DEST/dump.sql.gz" | cut -f1)"
echo ""
echo "--- Backing up Nextcloud data ---"
NC_POD=$(kubectl get pods -n "$NAMESPACE" -l app=nextcloud -o jsonpath='{.items[0].metadata.name}')
if [[ -z "$NC_POD" ]]; then
echo "ERROR: Nextcloud pod not found"
exit 1
fi
NC_SIZE=$(kubectl exec -n "$NAMESPACE" "$NC_POD" -- du -sb /var/www/html 2>/dev/null | awk '{print $1}' || echo "0")
echo "Data size: $(numfmt --to=iec-i --suffix=B "$NC_SIZE" 2>/dev/null || echo "$NC_SIZE bytes")"
echo "Creating tar archive from $NC_POD..."
kubectl exec -n "$NAMESPACE" "$NC_POD" -- tar cf - -C /var/www/html . 2>/dev/null | gzip > "$NC_DATA_DEST/data.tar.gz" &
BACKUP_PID=$!
show_progress "$NC_DATA_DEST/data.tar.gz" "Data" "$NC_SIZE"
wait $BACKUP_PID 2>/dev/null || true
echo "Data backup: $(du -sh "$NC_DATA_DEST/data.tar.gz" | cut -f1)"
echo ""
echo "--- Creating latest symlinks ---"
rm -f "$BACKUP_DIR/nextcloud-data/latest" "$BACKUP_DIR/nextcloud-postgres/latest"
ln -sf "backups/$TIMESTAMP" "$BACKUP_DIR/nextcloud-data/latest"
ln -sf "backups/$TIMESTAMP" "$BACKUP_DIR/nextcloud-postgres/latest"
echo ""
echo "=== Backup Complete ==="
echo "Timestamp: $TIMESTAMP"
echo "Finished: $(date)"
echo ""
du -sh "$NC_DATA_DEST" "$NC_DB_DEST"