- Created OPERATIONAL_RUNBOOK.md: comprehensive step-by-step procedures for both Docker and Standalone deployment modes covering deployment, daily ops, troubleshooting, backup/restore, disaster recovery, scaling, and updates - Created HEALTH_MONITORING_CHECKLIST.md: daily/weekly/monthly health check procedures with alert thresholds and quick troubleshooting reference - Created DISASTER_RECOVERY_PLAN.md: detailed procedures for 6 failure scenarios (database corruption, hardware failure, data center failure, app crash, disk full, network isolation) with RTO/RPO targets - Created CONFIGURATION_REFERENCE.md: complete documentation of all inventory.env parameters for both deployment modes with common scenarios and troubleshooting - Created EMERGENCY_PROCEDURES.md: quick-reference incident response playbook with 7 critical scenarios, decision tree, escalation path, and printable cheat sheet - Created scripts/backup.sh: automated backup script supporting both Docker and Standalone with integrity verification and retention management - Created scripts/restore.sh: restore script with triple confirmation, safety backups, and validation tests for both deployment modes - Created config/backup-cron.sh: installer for daily/weekly automated backup cron jobs (2 AM daily, 3 AM Sunday) All documentation covers dual-deployment modes with shared configuration files. Documentation is operator-ready with copy-paste commands and clear expected outputs.
141 lines
4.3 KiB
Bash
141 lines
4.3 KiB
Bash
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
# Phase 6, Plan 02, Task 2: Restore from Backup
|
|
# Supports both Docker and Standalone deployment modes
|
|
# Usage: ./restore.sh <backup_file> [--validate]
|
|
|
|
BACKUP_FILE="${1:-}"
|
|
VALIDATE="${2:---validate}"
|
|
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m'
|
|
|
|
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
|
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
|
log_error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }
|
|
|
|
# Validate input
|
|
[[ -z "$BACKUP_FILE" ]] && log_error "Usage: ./restore.sh <backup_file>"
|
|
[[ ! -f "$BACKUP_FILE" ]] && log_error "Backup file not found: $BACKUP_FILE"
|
|
|
|
log_info "Restoring from: $BACKUP_FILE"
|
|
|
|
# Triple confirmation (security requirement)
|
|
echo "⚠️ WARNING: This will overwrite current data!"
|
|
read -p "Type 'RESTORE' to confirm (1/3): " confirm1
|
|
[[ "$confirm1" != "RESTORE" ]] && log_error "Restore cancelled"
|
|
|
|
read -p "Type 'RESTORE' again to confirm (2/3): " confirm2
|
|
[[ "$confirm2" != "RESTORE" ]] && log_error "Restore cancelled"
|
|
|
|
read -p "Type 'RESTORE' one more time to confirm (3/3): " confirm3
|
|
[[ "$confirm3" != "RESTORE" ]] && log_error "Restore cancelled"
|
|
|
|
log_warn "Proceeding with restore..."
|
|
|
|
# Determine deployment mode
|
|
if command -v docker-compose &> /dev/null; then
|
|
log_info "Docker deployment mode detected"
|
|
IS_DOCKER=true
|
|
|
|
# 1. Stop services
|
|
log_info "Stopping services..."
|
|
docker-compose down
|
|
|
|
# 2. Backup current data (safety copy)
|
|
log_info "Creating safety backup of current data..."
|
|
mkdir -p data/backups_before_restore
|
|
tar -czf "data/backups_before_restore/backup-before-restore-$(date +%s).tar.gz" \
|
|
data/inventory.db data/inventory.db-* 2>/dev/null || true
|
|
|
|
# 3. Extract backup
|
|
log_info "Extracting backup..."
|
|
tar -xzf "$BACKUP_FILE" -C . || log_error "Backup extraction failed"
|
|
|
|
# 4. Verify essential files
|
|
log_info "Verifying restored files..."
|
|
[[ -f "data/inventory.db" ]] || log_error "Database not found in backup"
|
|
[[ -f "inventory.env" ]] || log_error "inventory.env not found in backup"
|
|
|
|
# 5. Restart services
|
|
log_info "Restarting services..."
|
|
docker-compose up -d
|
|
|
|
# 6. Wait for health
|
|
log_info "Waiting for services to be healthy..."
|
|
max_attempts=30
|
|
attempt=0
|
|
while [[ $attempt -lt $max_attempts ]]; do
|
|
if curl -sf "http://localhost:8000/health" > /dev/null 2>&1; then
|
|
log_info "Services healthy!"
|
|
break
|
|
fi
|
|
attempt=$((attempt + 1))
|
|
sleep 2
|
|
done
|
|
|
|
if [[ $attempt -eq $max_attempts ]]; then
|
|
log_warn "Services did not become healthy within 60 seconds"
|
|
docker-compose logs backend
|
|
exit 1
|
|
fi
|
|
|
|
# 7. Validation tests (if requested)
|
|
if [[ "$VALIDATE" == "--validate" ]]; then
|
|
log_info "Running validation tests..."
|
|
|
|
# Test 1: Database accessible
|
|
DB_ITEMS=$(docker-compose exec backend sqlite3 /app/data/inventory.db \
|
|
"SELECT COUNT(*) FROM items" 2>/dev/null || echo "0")
|
|
log_info "✓ Database has $DB_ITEMS items"
|
|
|
|
# Test 2: API responsive
|
|
if curl -sf "http://localhost:8000/health" > /dev/null; then
|
|
log_info "✓ API health check passed"
|
|
else
|
|
log_error "API health check failed"
|
|
fi
|
|
|
|
# Test 3: Frontend loads
|
|
if curl -sf "http://localhost:3000" > /dev/null 2>&1; then
|
|
log_info "✓ Frontend loads"
|
|
else
|
|
log_warn "⚠ Frontend check failed (normal on first startup)"
|
|
fi
|
|
fi
|
|
|
|
else
|
|
log_info "Standalone deployment mode detected"
|
|
IS_DOCKER=false
|
|
|
|
# 1. Kill any running servers
|
|
log_info "Stopping running services..."
|
|
pkill -f "next start" || true
|
|
pkill -f "uvicorn" || true
|
|
sleep 2
|
|
|
|
# 2. Backup current data
|
|
log_info "Creating safety backup of current data..."
|
|
mkdir -p data/backups_before_restore
|
|
tar -czf "data/backups_before_restore/backup-before-restore-$(date +%s).tar.gz" \
|
|
data/inventory.db data/inventory.db-* 2>/dev/null || true
|
|
|
|
# 3. Extract backup
|
|
log_info "Extracting backup..."
|
|
tar -xzf "$BACKUP_FILE" -C . || log_error "Backup extraction failed"
|
|
|
|
# 4. Verify essential files
|
|
log_info "Verifying restored files..."
|
|
[[ -f "data/inventory.db" ]] || log_error "Database not found in backup"
|
|
[[ -f "inventory.env" ]] || log_error "inventory.env not found in backup"
|
|
|
|
log_info "✓ Restore complete"
|
|
log_warn "Remember to start services: ./start_server.sh"
|
|
fi
|
|
|
|
log_info "Restore complete!"
|
|
log_warn "Remember to verify data in the application before returning to production"
|