#!/bin/bash # Bible Chat App Maintenance Script # This script performs routine maintenance tasks set -e echo "🔧 Starting Bible Chat App maintenance..." # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # Configuration BACKUP_DIR="/var/backups/bible-chat" LOG_FILE="/var/log/bible-chat-maintenance.log" COMPOSE_FILE="docker-compose.prod.yml" # Function to log messages log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" } # Function to run database maintenance run_db_maintenance() { echo -e "${YELLOW}📊 Running database maintenance...${NC}" # Run optimization script docker-compose -f "$COMPOSE_FILE" exec -T postgres psql -U bible_admin -d bible_chat -f /docker-entrypoint-initdb.d/optimize-db.sql # Run cleanup function docker-compose -f "$COMPOSE_FILE" exec -T postgres psql -U bible_admin -d bible_chat -c "SELECT cleanup_old_data();" # Analyze performance docker-compose -f "$COMPOSE_FILE" exec -T postgres psql -U bible_admin -d bible_chat -c "SELECT analyze_query_performance();" log "Database maintenance completed" } # Function to create backup create_backup() { echo -e "${YELLOW}💾 Creating database backup...${NC}" # Create backup directory if it doesn't exist mkdir -p "$BACKUP_DIR" # Generate backup filename with timestamp BACKUP_FILE="$BACKUP_DIR/bible-chat-$(date +%Y%m%d_%H%M%S).sql" # Create database backup docker-compose -f "$COMPOSE_FILE" exec -T postgres pg_dump -U bible_admin -d bible_chat > "$BACKUP_FILE" # Compress backup gzip "$BACKUP_FILE" # Remove backups older than 30 days find "$BACKUP_DIR" -name "*.sql.gz" -mtime +30 -delete log "Backup created: ${BACKUP_FILE}.gz" } # Function to update containers update_containers() { echo -e "${YELLOW}🐳 Updating containers...${NC}" # Pull latest images docker-compose -f "$COMPOSE_FILE" pull # Restart services with zero downtime docker-compose -f "$COMPOSE_FILE" up -d --remove-orphans # Remove unused images docker image prune -f log "Containers updated" } # Function to check disk space check_disk_space() { echo -e "${YELLOW}💽 Checking disk space...${NC}" # Check available disk space (warn if less than 10% free) DISK_USAGE=$(df / | awk 'NR==2{printf "%.0f", $5}') if [ "$DISK_USAGE" -gt 90 ]; then echo -e "${RED}⚠️ Warning: Disk usage is ${DISK_USAGE}%${NC}" log "WARNING: High disk usage - ${DISK_USAGE}%" else echo -e "${GREEN}✅ Disk usage is ${DISK_USAGE}%${NC}" log "Disk usage check passed - ${DISK_USAGE}%" fi } # Function to check service health check_service_health() { echo -e "${YELLOW}🏥 Checking service health...${NC}" # Check if containers are running if docker-compose -f "$COMPOSE_FILE" ps | grep -q "Up"; then echo -e "${GREEN}✅ Services are running${NC}" # Check application health endpoint if curl -f -s http://localhost/api/health > /dev/null; then echo -e "${GREEN}✅ Application health check passed${NC}" log "Health check passed" else echo -e "${RED}❌ Application health check failed${NC}" log "ERROR: Application health check failed" return 1 fi else echo -e "${RED}❌ Some services are not running${NC}" log "ERROR: Services not running properly" return 1 fi } # Function to rotate logs rotate_logs() { echo -e "${YELLOW}📋 Rotating logs...${NC}" # Rotate application logs docker-compose -f "$COMPOSE_FILE" exec app sh -c "find /app/.next -name '*.log' -size +100M -delete" 2>/dev/null || true # Rotate docker logs docker-compose -f "$COMPOSE_FILE" logs --tail=1000 app > /var/log/bible-chat-app.log 2>/dev/null || true # Compress old maintenance logs find /var/log -name "bible-chat-maintenance.log.*" -size +10M -exec gzip {} \; 2>/dev/null || true log "Log rotation completed" } # Function to generate performance report generate_performance_report() { echo -e "${YELLOW}📈 Generating performance report...${NC}" REPORT_FILE="/var/log/bible-chat-performance-$(date +%Y%m%d).log" { echo "=== Bible Chat Performance Report - $(date) ===" echo "" echo "=== Database Statistics ===" docker-compose -f "$COMPOSE_FILE" exec -T postgres psql -U bible_admin -d bible_chat -c "SELECT * FROM get_database_stats();" echo "" echo "=== Container Statistics ===" docker stats --no-stream echo "" echo "=== Disk Usage ===" df -h echo "" } > "$REPORT_FILE" log "Performance report generated: $REPORT_FILE" } # Main execution main() { log "Maintenance started" # Parse command line arguments case "${1:-all}" in "backup") create_backup ;; "cleanup") run_db_maintenance rotate_logs ;; "update") update_containers ;; "health") check_service_health ;; "report") generate_performance_report ;; "all") check_disk_space check_service_health create_backup run_db_maintenance rotate_logs generate_performance_report ;; *) echo "Usage: $0 {backup|cleanup|update|health|report|all}" echo "" echo " backup - Create database backup" echo " cleanup - Run database maintenance and log rotation" echo " update - Update and restart containers" echo " health - Check service health" echo " report - Generate performance report" echo " all - Run all maintenance tasks (default)" exit 1 ;; esac echo -e "${GREEN}✅ Maintenance completed successfully!${NC}" log "Maintenance completed successfully" } # Ensure script is run as root or with sudo if [[ $EUID -ne 0 ]] && [[ -z "$SUDO_USER" ]]; then echo -e "${RED}This script must be run as root or with sudo${NC}" exit 1 fi # Run main function main "$@"