#!/bin/bash # Script de mantenimiento para HOST (fuera de Docker) # Instalación: sudo cp host-maintenance-cron.sh /usr/local/bin/ # Crontab: sudo crontab -e # 0 2 * * * /usr/local/bin/host-maintenance-cron.sh backup # 0 3 * * * /usr/local/bin/host-maintenance-cron.sh clean-logs # 0 * * * * /usr/local/bin/host-maintenance-cron.sh health-check set -e # Configuración DOCKER_COMPOSE_FILE="/ruta/a/tu/proyecto/docker-compose.dev.yml" PROJECT_DIR="/ruta/a/tu/proyecto" BACKUP_DIR="$PROJECT_DIR/backups" LOGS_DIR="$PROJECT_DIR/logs" # Colores para logs RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color log() { echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1" } error() { echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] ERROR:${NC} $1" } warning() { echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] WARNING:${NC} $1" } # Función: Backup de base de datos backup_database() { log "Iniciando backup de base de datos..." mkdir -p "$BACKUP_DIR/database" BACKUP_FILE="$BACKUP_DIR/database/backup_$(date +%Y%m%d_%H%M%S).sql.gz" # Ejecutar backup desde el contenedor MySQL if docker compose -f "$DOCKER_COMPOSE_FILE" exec -T mysql \ mariadb-dump \ --single-transaction \ --routines \ --triggers \ --events \ usite_whatsapp_bot | gzip > "$BACKUP_FILE"; then log "✅ Backup creado: $BACKUP_FILE" # Mostrar tamaño SIZE=$(du -h "$BACKUP_FILE" | cut -f1) log "Tamaño: $SIZE" # Eliminar backups antiguos (>7 días) find "$BACKUP_DIR/database" -name "backup_*.sql.gz" -mtime +7 -delete log "Backups antiguos eliminados" # Contar backups COUNT=$(find "$BACKUP_DIR/database" -name "backup_*.sql.gz" | wc -l) log "Backups disponibles: $COUNT" else error "Fallo al crear backup" return 1 fi } # Función: Limpieza de logs clean_logs() { log "Iniciando limpieza de logs..." if [ ! -d "$LOGS_DIR" ]; then warning "Directorio de logs no encontrado: $LOGS_DIR" return 0 fi # Contar archivos antes BEFORE=$(find "$LOGS_DIR" -name "*.log" | wc -l) log "Archivos de log: $BEFORE" # Eliminar logs >30 días find "$LOGS_DIR" -name "*.log" -mtime +30 -delete # Comprimir logs 7-30 días find "$LOGS_DIR" -name "*.log" -mtime +7 -mtime -30 -exec gzip {} \; 2>/dev/null || true # Eliminar .gz >30 días find "$LOGS_DIR" -name "*.log.gz" -mtime +30 -delete # Truncar logs muy grandes find "$LOGS_DIR" -name "*.log" -size +100M -exec sh -c 'echo "Log truncado el $(date)" > "$1"' _ {} \; AFTER=$(find "$LOGS_DIR" -name "*.log" -o -name "*.log.gz" | wc -l) SPACE=$(du -sh "$LOGS_DIR" | cut -f1) log "Archivos restantes: $AFTER" log "Espacio usado: $SPACE" log "✅ Limpieza completada" } # Función: Health Check health_check() { log "Verificando salud del sistema..." # Verificar contenedores CONTAINERS=$(docker compose -f "$DOCKER_COMPOSE_FILE" ps --services --filter "status=running" | wc -l) EXPECTED=7 # Ajustar según tus servicios if [ "$CONTAINERS" -ge "$EXPECTED" ]; then log "✅ Contenedores: $CONTAINERS activos" else warning "Solo $CONTAINERS/$EXPECTED contenedores activos" fi # Verificar espacio en disco DISK_USAGE=$(df -h "$PROJECT_DIR" | tail -1 | awk '{print $5}' | sed 's/%//') DISK_SPACE=$(df -h "$PROJECT_DIR" | tail -1 | awk '{print $4}') log "Espacio en disco: $DISK_USAGE% usado, $DISK_SPACE disponible" if [ "$DISK_USAGE" -gt 85 ]; then warning "⚠️ Espacio en disco mayor al 85%" fi # Verificar logs de Docker ERROR_COUNT=$(docker compose -f "$DOCKER_COMPOSE_FILE" logs --tail=100 2>&1 | grep -i "error" | wc -l) if [ "$ERROR_COUNT" -gt 0 ]; then warning "Se encontraron $ERROR_COUNT errores en logs recientes" else log "✅ No hay errores recientes" fi log "Verificación completada" } # Función: Restart services si es necesario auto_restart() { log "Verificando servicios para auto-restart..." # Verificar contenedores con reintentos excesivos UNHEALTHY=$(docker compose -f "$DOCKER_COMPOSE_FILE" ps --format json | \ jq -r 'select(.Health == "unhealthy") | .Service' 2>/dev/null || echo "") if [ -n "$UNHEALTHY" ]; then warning "Contenedores no saludables: $UNHEALTHY" log "Reiniciando servicios no saludables..." docker compose -f "$DOCKER_COMPOSE_FILE" restart $UNHEALTHY log "✅ Servicios reiniciados" else log "✅ Todos los servicios saludables" fi } # Menú principal case "$1" in backup) backup_database ;; clean-logs) clean_logs ;; health-check) health_check ;; auto-restart) auto_restart ;; all) backup_database clean_logs health_check ;; *) echo "Uso: $0 {backup|clean-logs|health-check|auto-restart|all}" echo "" echo "Comandos:" echo " backup - Backup de base de datos" echo " clean-logs - Limpieza de logs" echo " health-check - Verificación de salud" echo " auto-restart - Reiniciar servicios no saludables" echo " all - Ejecutar todas las tareas" exit 1 ;; esac exit 0