#!/usr/bin/env bash ############################################################################### # backup.sh — Backup all persistent data for the home-server stack # # Usage: # ./scripts/backup.sh [backup-directory] # # Default backup directory: ./backups/ # Creates a timestamped tar.gz archive of all service data. ############################################################################### set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_DIR="$(dirname "$SCRIPT_DIR")" BACKUP_DIR="${1:-$PROJECT_DIR/backups}" TIMESTAMP="$(date +%Y%m%d_%H%M%S)" BACKUP_FILE="$BACKUP_DIR/home-server-backup_${TIMESTAMP}.tar.gz" # Colors for output GREEN='\033[0;32m' YELLOW='\033[1;33m' RED='\033[0;31m' NC='\033[0m' # No Color echo -e "${YELLOW}=== Home Server Backup ===${NC}" echo "Timestamp: $TIMESTAMP" echo "Project: $PROJECT_DIR" echo "Backup to: $BACKUP_FILE" echo "" # Create backup directory if it doesn't exist mkdir -p "$BACKUP_DIR" # Check if services are running and warn if command -v docker &> /dev/null; then RUNNING=$(docker compose -f "$PROJECT_DIR/docker-compose.yml" ps --status running -q 2>/dev/null | wc -l) if [ "$RUNNING" -gt 0 ]; then echo -e "${YELLOW}WARNING: $RUNNING container(s) are running.${NC}" echo "For a consistent backup, consider stopping services first:" echo " docker compose down" echo "" read -p "Continue anyway? (y/N) " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then echo "Backup cancelled." exit 0 fi fi fi # Directories to back up DIRS_TO_BACKUP=( "nginx-proxy-manager" "homeassistant" "gitea" "wireguard" ".env" ) # Build tar arguments — only include directories/files that exist TAR_ARGS=() for item in "${DIRS_TO_BACKUP[@]}"; do if [ -e "$PROJECT_DIR/$item" ]; then TAR_ARGS+=("$item") echo -e " ${GREEN}✓${NC} Including: $item" else echo -e " ${YELLOW}⊘${NC} Skipping (not found): $item" fi done if [ ${#TAR_ARGS[@]} -eq 0 ]; then echo -e "${RED}ERROR: No data directories found to back up.${NC}" exit 1 fi echo "" echo "Creating archive..." tar -czf "$BACKUP_FILE" -C "$PROJECT_DIR" "${TAR_ARGS[@]}" BACKUP_SIZE=$(du -h "$BACKUP_FILE" | cut -f1) echo "" echo -e "${GREEN}=== Backup complete ===${NC}" echo "File: $BACKUP_FILE" echo "Size: $BACKUP_SIZE" echo "" echo "To restore, run:" echo " ./scripts/restore.sh $BACKUP_FILE"