#!/bin/bash # Netbird Docker Compose Restore Script # This script restores a backup and recreates the full directory structure # Configuration COMPOSE_DIR="/home/Dejan/Docker/Netbird-compose" BACKUP_DIR="${COMPOSE_DIR}/backup" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Function to print colored messages print_msg() { echo -e "${GREEN}[INFO]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } print_question() { echo -e "${BLUE}[QUESTION]${NC} $1" } # Function to show usage show_usage() { echo "Usage: $0 " echo "" echo "Examples:" echo " $0 netbird-backup-20241127_161245.tar.gz" echo " $0 backup/netbird-backup-20241127_161245.tar.gz" echo " $0 /home/Dejan/Docker/Netbird-compose/backup/netbird-backup-20241127_161245.tar.gz" echo "" echo "Available backups:" if [ -d "$BACKUP_DIR" ]; then ls -1t "$BACKUP_DIR"/netbird-backup-*.tar.gz 2>/dev/null | head -n 10 else echo " No backup directory found" fi exit 1 } # Check if running as root if [ "$EUID" -ne 0 ]; then print_error "Please run as root" exit 1 fi # Check if backup file argument is provided if [ -z "$1" ]; then print_error "No backup file specified" show_usage fi BACKUP_FILE="$1" # Resolve backup file path if [ ! -f "$BACKUP_FILE" ]; then # Try in backup directory if [ -f "$BACKUP_DIR/$BACKUP_FILE" ]; then BACKUP_FILE="$BACKUP_DIR/$BACKUP_FILE" elif [ -f "$COMPOSE_DIR/$BACKUP_FILE" ]; then BACKUP_FILE="$COMPOSE_DIR/$BACKUP_FILE" else print_error "Backup file not found: $1" print_msg "Searched in:" echo " - $1" echo " - $BACKUP_DIR/$1" echo " - $COMPOSE_DIR/$1" echo "" show_usage fi fi print_msg "Restore Script for Netbird Docker Compose" print_msg "==========================================" print_msg "Backup file: $BACKUP_FILE" print_msg "Target directory: $COMPOSE_DIR" echo "" # Verify backup file if ! tar -tzf "$BACKUP_FILE" &>/dev/null; then print_error "Invalid or corrupted backup file" exit 1 fi BACKUP_SIZE=$(du -h "$BACKUP_FILE" | cut -f1) print_msg "Backup size: $BACKUP_SIZE" # Show what will be restored print_msg "Backup contents preview:" tar -tzf "$BACKUP_FILE" | head -n 20 if [ $(tar -tzf "$BACKUP_FILE" | wc -l) -gt 20 ]; then echo " ... and more files" fi echo "" # Warning and confirmation print_warning "WARNING: This will stop all services and replace current files!" print_warning "Current directory contents will be overwritten!" echo "" print_question "Do you want to create a safety backup before restoring? (recommended) [Y/n]" read -r SAFETY_BACKUP if [[ ! "$SAFETY_BACKUP" =~ ^[Nn]$ ]]; then SAFETY_TIMESTAMP=$(date +"%Y%m%d_%H%M%S") SAFETY_FILE="${BACKUP_DIR}/pre-restore-backup-${SAFETY_TIMESTAMP}.tar.gz" print_msg "Creating safety backup: $SAFETY_FILE" cd "$COMPOSE_DIR" || exit 1 # Stop services first if docker-compose.yml exists if [ -f "docker-compose.yml" ]; then print_msg "Stopping current services..." docker-compose down 2>/dev/null fi tar -czf "$SAFETY_FILE" \ --exclude='./backup' \ --exclude='./.git' \ -C "$COMPOSE_DIR" . 2>/dev/null if [ $? -eq 0 ]; then print_msg "Safety backup created successfully" else print_warning "Failed to create safety backup, but continuing..." fi fi echo "" print_question "Are you sure you want to restore from this backup? [y/N]" read -r CONFIRM if [[ ! "$CONFIRM" =~ ^[Yy]$ ]]; then print_msg "Restore cancelled by user" exit 0 fi print_msg "Starting restore process..." # Change to compose directory cd "$COMPOSE_DIR" || { print_error "Failed to change to directory: $COMPOSE_DIR" exit 1 } # Stop docker compose services if they exist if [ -f "docker-compose.yml" ]; then print_msg "Stopping Docker Compose services..." docker-compose down if [ $? -eq 0 ]; then print_msg "Services stopped successfully" else print_warning "Failed to stop services (they may not be running)" fi else print_msg "No docker-compose.yml found, skipping service stop" fi # Remove current files (except backup directory and this script) print_msg "Removing current files..." find "$COMPOSE_DIR" -mindepth 1 -maxdepth 1 ! -name 'backup' ! -name 'restore-netbird.sh' ! -name '.git' -exec rm -rf {} + 2>/dev/null # Extract backup print_msg "Extracting backup archive..." tar -xzf "$BACKUP_FILE" -C "$COMPOSE_DIR" if [ $? -eq 0 ]; then print_msg "Backup extracted successfully" else print_error "Failed to extract backup" exit 1 fi # Set proper permissions print_msg "Setting permissions..." chmod +x "$COMPOSE_DIR"/*.sh 2>/dev/null if [ -d "$COMPOSE_DIR/machinekey" ]; then chmod 777 "$COMPOSE_DIR/machinekey" fi chmod 600 "$COMPOSE_DIR/acme.json" 2>/dev/null # Verify critical files print_msg "Verifying restored files..." CRITICAL_FILES=("docker-compose.yml" ".env") ALL_GOOD=true for file in "${CRITICAL_FILES[@]}"; do if [ -f "$COMPOSE_DIR/$file" ]; then print_msg "✓ $file restored" else print_error "✗ $file missing" ALL_GOOD=false fi done if [ "$ALL_GOOD" = false ]; then print_error "Some critical files are missing!" exit 1 fi # Start docker compose services print_msg "Starting Docker Compose services..." docker-compose up -d if [ $? -eq 0 ]; then print_msg "Services started successfully" else print_error "Failed to start services" print_msg "You can try manually with: cd $COMPOSE_DIR && docker-compose up -d" exit 1 fi # Wait a moment and show service status sleep 3 print_msg "Current service status:" docker-compose ps print_msg "==========================================" print_msg "Restore completed successfully!" print_msg "Restored from: $BACKUP_FILE" if [[ ! "$SAFETY_BACKUP" =~ ^[Nn]$ ]] && [ -f "$SAFETY_FILE" ]; then print_msg "Safety backup saved at: $SAFETY_FILE" fi print_msg "==========================================" exit 0