====== Резервное копирование Evolution API ====== ===== Описание системы ===== Evolution API - это система для работы с WhatsApp Business API, развернутая в Docker контейнерах. Система состоит из: * **evolution-api** - основное приложение API * **evolution_postgres** - база данных PostgreSQL 15 * **redis** - кэш и хранилище сессий Данная инструкция предназначена для систем с Evolution API, развернутой через Docker Compose в директории `/opt/evolution-api/`. ===== Компоненты для резервного копирования ===== Скрипт создает резервные копии следующих компонентов: ^ Компонент ^ Описание ^ Расположение ^ | **store/** | Файлы и медиа сообщений | `/opt/evolution-api/store/` | | **instances/** | Конфигурации инстансов WhatsApp | `/opt/evolution-api/instances/` | | **postgres_data/** | Физические файлы базы данных | `/opt/evolution-api/postgres_data/` | | **redis_data/** | Данные Redis кэша | `/opt/evolution-api/redis_data/` | | **docker-compose.yml** | Конфигурация контейнеров | `/opt/evolution-api/docker-compose.yml` | | **database.sql** | SQL дамп базы данных | Создается автоматически | ===== Требования ===== ==== Системные требования ==== * **OS**: Linux (тестировано на Ubuntu 20.04+) * **Docker**: версия 20.10+ * **Docker Compose**: версия 1.29+ * **Свободное место**: минимум 2GB для бекапов * **Права**: root или пользователь в группе docker ==== Необходимые пакеты ==== # Ubuntu/Debian apt update && apt install -y curl tar gzip findutils # CentOS/RHEL yum install -y curl tar gzip findutils ===== Установка и настройка ===== ==== 1. Создание структуры директорий ==== # Создаем директории для скриптов и бекапов mkdir -p /opt/scripts mkdir -p /opt/backups/evolution-api # Устанавливаем права доступа chmod 750 /opt/scripts chmod 750 /opt/backups/evolution-api ==== 2. Установка скрипта ==== Создайте файл `/opt/scripts/evolution-backup.sh` и вставьте содержимое скрипта ниже. # Создаем скрипт nano /opt/scripts/evolution-backup.sh # Делаем исполняемым chmod +x /opt/scripts/evolution-backup.sh # Устанавливаем владельца (если нужно) chown root:root /opt/scripts/evolution-backup.sh **Содержимое скрипта `/opt/scripts/evolution-backup.sh`:** #!/bin/bash # Скрипт резервного копирования Evolution API # Запуск: /opt/scripts/evolution-backup.sh # Настройки COMPOSE_FILE="/opt/evolution-api/docker-compose.yml" EVOLUTION_DIR="/opt/evolution-api" BACKUP_DIR="/opt/backups/evolution-api" DATE=$(date +"%Y%m%d_%H%M%S") BACKUP_NAME="evolution_backup_${DATE}" RETENTION_DAYS=10 # Храним бекапы 10 дней # Настройки базы данных DB_CONTAINER="evolution_postgres" DB_USER="evolution_user" DB_PASSWORD="ВАШ_ПАРОЛЬ_БД" # ⚠️ Замените на реальный пароль! DB_NAME="evolution_db" # Логирование LOG_FILE="${BACKUP_DIR}/backup.log" # Функция логирования log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" } # Создаем директорию для бекапов если не существует mkdir -p "$BACKUP_DIR" log "=== Начало резервного копирования Evolution API ===" # Проверяем что compose файл существует if [ ! -f "$COMPOSE_FILE" ]; then log "ОШИБКА: Файл $COMPOSE_FILE не найден!" exit 1 fi # Переходим в директорию с Evolution cd "$EVOLUTION_DIR" || { log "ОШИБКА: Не удалось перейти в директорию $EVOLUTION_DIR" exit 1 } # Проверяем что контейнеры запущены log "Проверяем статус контейнеров..." if ! docker-compose -f "$COMPOSE_FILE" ps | grep -q "Up"; then log "ОШИБКА: Контейнеры не запущены! Запустите их перед созданием бекапа." exit 1 fi # Создаем дамп базы данных (пока контейнеры работают) log "Создаем дамп базы данных..." DB_DUMP_PATH="${BACKUP_DIR}/${BACKUP_NAME}_database.sql" # Экспортируем пароль для pg_dump export PGPASSWORD="$DB_PASSWORD" docker exec "$DB_CONTAINER" pg_dump -U "$DB_USER" -d "$DB_NAME" --no-password --verbose > "$DB_DUMP_PATH" 2>> "$LOG_FILE" if [ $? -eq 0 ] && [ -s "$DB_DUMP_PATH" ]; then log "Дамп базы данных создан: $DB_DUMP_PATH" # Получаем размер дампа DB_DUMP_SIZE=$(du -h "$DB_DUMP_PATH" | cut -f1) log "Размер дампа БД: $DB_DUMP_SIZE" else log "ОШИБКА: Не удалось создать дамп базы данных или файл пуст" rm -f "$DB_DUMP_PATH" exit 1 fi # Очищаем переменную окружения unset PGPASSWORD # Останавливаем контейнеры log "Останавливаем контейнеры Evolution API..." docker-compose -f "$COMPOSE_FILE" down if [ $? -eq 0 ]; then log "Контейнеры успешно остановлены" else log "ОШИБКА: Не удалось остановить контейнеры" exit 1 fi # Ждем пару секунд для полной остановки sleep 5 # Создаем архив с данными (включая дамп БД) log "Создаем архив данных..." BACKUP_PATH="${BACKUP_DIR}/${BACKUP_NAME}.tar.gz" tar -czf "$BACKUP_PATH" \ --exclude='*.log' \ --exclude='**/lost+found' \ -C "$BACKUP_DIR" "${BACKUP_NAME}_database.sql" \ -C "$EVOLUTION_DIR" \ store/ \ instances/ \ postgres_data/ \ redis_data/ \ docker-compose.yml if [ $? -eq 0 ]; then log "Архив создан: $BACKUP_PATH" # Получаем размер архива BACKUP_SIZE=$(du -h "$BACKUP_PATH" | cut -f1) log "Размер архива: $BACKUP_SIZE" # Удаляем отдельный файл дампа, так как он теперь в архиве rm -f "$DB_DUMP_PATH" log "Отдельный файл дампа БД удален (включен в архив)" else log "ОШИБКА: Не удалось создать архив" # Пытаемся запустить контейнеры даже при ошибке log "Запускаем контейнеры после ошибки..." docker-compose -f "$COMPOSE_FILE" up -d exit 1 fi # Запускаем контейнеры обратно log "Запускаем контейнеры Evolution API..." docker-compose -f "$COMPOSE_FILE" up -d if [ $? -eq 0 ]; then log "Контейнеры успешно запущены" else log "ОШИБКА: Не удалось запустить контейнеры" exit 1 fi # Ждем запуска сервисов sleep 15 # Проверяем что все контейнеры работают log "Проверяем статус контейнеров..." RUNNING_CONTAINERS=$(docker-compose -f "$COMPOSE_FILE" ps --services --filter "status=running" | wc -l) TOTAL_CONTAINERS=$(docker-compose -f "$COMPOSE_FILE" ps --services | wc -l) if [ "$RUNNING_CONTAINERS" -eq "$TOTAL_CONTAINERS" ]; then log "Все контейнеры ($RUNNING_CONTAINERS/$TOTAL_CONTAINERS) работают корректно" else log "ПРЕДУПРЕЖДЕНИЕ: Работают только $RUNNING_CONTAINERS из $TOTAL_CONTAINERS контейнеров" fi # Проверяем доступность базы данных log "Проверяем подключение к базе данных..." export PGPASSWORD="$DB_PASSWORD" if docker exec "$DB_CONTAINER" pg_isready -U "$DB_USER" -d "$DB_NAME" > /dev/null 2>&1; then log "База данных доступна и готова к работе" else log "ПРЕДУПРЕЖДЕНИЕ: База данных может быть недоступна" fi unset PGPASSWORD # Удаляем старые бекапы log "Удаляем бекапы старше $RETENTION_DAYS дней..." DELETED_COUNT=$(find "$BACKUP_DIR" -name "evolution_backup_*.tar.gz" -mtime +$RETENTION_DAYS -delete -print | wc -l) log "Удалено старых бекапов: $DELETED_COUNT" # Показываем статистику бекапов BACKUP_COUNT=$(ls -1 "${BACKUP_DIR}"/evolution_backup_*.tar.gz 2>/dev/null | wc -l) TOTAL_SIZE=$(du -sh "${BACKUP_DIR}" 2>/dev/null | cut -f1) log "Общее количество бекапов: $BACKUP_COUNT" log "Общий размер папки бекапов: $TOTAL_SIZE" # Получаем информацию о свободном месте на диске BACKUP_DISK_USAGE=$(df -h "$BACKUP_DIR" | awk 'NR==2 {print $4 " свободно из " $2 " (" $5 " занято)"}') ROOT_DISK_USAGE=$(df -h / | awk 'NR==2 {print $4 " свободно из " $2 " (" $5 " занято)"}') log "Свободное место на диске бекапов: $BACKUP_DISK_USAGE" if [ "$BACKUP_DIR" != "/" ] && [ "$(df "$BACKUP_DIR" | awk 'NR==2 {print $1}')" != "$(df / | awk 'NR==2 {print $1}')" ]; then log "Свободное место на корневом диске: $ROOT_DISK_USAGE" fi # Получаем процент заполнения диска с бекапами для предупреждений BACKUP_DISK_PERCENT=$(df "$BACKUP_DIR" | awk 'NR==2 {print $5}' | sed 's/%//') if [ "$BACKUP_DISK_PERCENT" -gt 90 ]; then log "⚠️ ПРЕДУПРЕЖДЕНИЕ: Диск заполнен более чем на 90%!" elif [ "$BACKUP_DISK_PERCENT" -gt 80 ]; then log "⚠️ ВНИМАНИЕ: Диск заполнен более чем на 80%" fi log "=== Резервное копирование завершено успешно ===" # Формируем сообщение для Telegram TELEGRAM_MESSAGE="✅ Evolution API backup completed 📁 Backup: $BACKUP_NAME ($BACKUP_SIZE) 💾 DB dump: $DB_DUMP_SIZE 📊 Total backups: $BACKUP_COUNT 💿 Disk space: $BACKUP_DISK_USAGE" # Добавляем предупреждение о месте, если нужно if [ "$BACKUP_DISK_PERCENT" -gt 90 ]; then TELEGRAM_MESSAGE="$TELEGRAM_MESSAGE ⚠️ WARNING: Disk >90% full!" elif [ "$BACKUP_DISK_PERCENT" -gt 80 ]; then TELEGRAM_MESSAGE="$TELEGRAM_MESSAGE ⚠️ ATTENTION: Disk >80% full" fi # Отправляем уведомление в Telegram (опционально) curl -s -X POST "https://api.telegram.org/botВАШ_ТОКЕН_БОТА/sendMessage" \ -d chat_id="ВАШ_CHAT_ID" \ -d text="$TELEGRAM_MESSAGE" > /dev/null exit 0 ==== 3. Настройка переменных ==== После создания скрипта обязательно отредактируйте следующие переменные: # Основные настройки (проверьте пути под вашу систему) COMPOSE_FILE="/opt/evolution-api/docker-compose.yml" # Путь к docker-compose.yml EVOLUTION_DIR="/opt/evolution-api" # Директория Evolution API BACKUP_DIR="/opt/backups/evolution-api" # Директория для бекапов RETENTION_DAYS=10 # Срок хранения бекапов # ⚠️ ОБЯЗАТЕЛЬНО ИЗМЕНИТЕ эти параметры безопасности: DB_PASSWORD="ВАШ_ПАРОЛЬ_БД" # Пароль от PostgreSQL (из docker-compose.yml) curl ... "botВАШ_ТОКЕН_БОТА" ... # Токен Telegram бота chat_id="ВАШ_CHAT_ID" # Ваш Telegram chat_id **Безопасность**: Обязательно замените все плейсхолдеры на реальные значения! Пароль должен совпадать с `POSTGRES_PASSWORD` из вашего `docker-compose.yml`. ==== 4. Настройка Telegram уведомлений (опционально) ==== Для получения уведомлений о результатах резервного копирования: - Создайте Telegram бота через [@BotFather](https://t.me/botfather) - Получите токен бота - Узнайте ваш chat_id (можно использовать [@userinfobot](https://t.me/userinfobot)) - Замените токен и chat_id в конце скрипта # Замените эти значения на свои curl -s -X POST "https://api.telegram.org/bot[ВАШ_ТОКЕН]/sendMessage" \ -d chat_id="[ВАШ_CHAT_ID]" \ -d text="✅ Evolution API backup completed: $BACKUP_NAME ($BACKUP_SIZE)" ===== Использование скрипта ===== ==== Ручной запуск ==== # Запуск с выводом в консоль /opt/scripts/evolution-backup.sh # Запуск в фоновом режиме nohup /opt/scripts/evolution-backup.sh > /dev/null 2>&1 & ==== Автоматический запуск через Cron ==== # Редактируем crontab crontab -e # Добавляем задание (например, каждый день в 3:00 ночи) 0 3 * * * /opt/scripts/evolution-backup.sh >/dev/null 2>&1 # Или с логированием cron ошибок 0 3 * * * /opt/scripts/evolution-backup.sh 2>> /var/log/evolution-backup-cron.log **Примеры расписаний Cron:** * `0 3 * * *` - каждый день в 3:00 * `0 2 * * 0` - каждое воскресенье в 2:00 * `0 1 1 * *` - 1 числа каждого месяца в 1:00 * `0 */6 * * *` - каждые 6 часов ===== Процесс резервного копирования ===== Скрипт выполняет следующие операции: - **Проверка окружения** - проверяет наличие файлов и запущенные контейнеры - **Создание SQL дампа** - создает дамп базы данных PostgreSQL - **Остановка контейнеров** - корректно останавливает все сервисы - **Создание архива** - упаковывает все данные в tar.gz - **Запуск контейнеров** - восстанавливает работу системы - **Проверка состояния** - проверяет что все сервисы запустились - **Очистка старых бекапов** - удаляет файлы старше указанного срока - **Отправка уведомлений** - отправляет статус в Telegram **Время простоя**: Обычно система недоступна 30-60 секунд во время создания бекапа. ==== Мониторинг дискового пространства ==== Скрипт автоматически отслеживает состояние дискового пространства: ^ Уровень заполнения ^ Действие ^ Сообщение ^ | < 80% | Нормальная работа | Информация в логе | | 80-90% | Предупреждение | "⚠️ ВНИМАНИЕ: Диск заполнен более чем на 80%" | | > 90% | Критическое предупреждение | "⚠️ ПРЕДУПРЕЖДЕНИЕ: Диск заполнен более чем на 90%!" | # Проверка свободного места вручную df -h /opt/backups/evolution-api # Расчет размера всех бекапов du -sh /opt/backups/evolution-api/* # Принудительная очистка старых бекапов (осторожно!) find /opt/backups/evolution-api -name "evolution_backup_*.tar.gz" -mtime +7 -delete **Рекомендации по управлению дисковым пространством:** * При заполнении > 80% - рассмотрите уменьшение срока хранения бекапов * При заполнении > 90% - немедленно очистите старые бекапы или увеличьте дисковое пространство * Настройте отдельный диск для бекапов, если это критично ===== Мониторинг и логи ===== ==== Просмотр логов ==== # Последние 50 строк лога tail -50 /opt/backups/evolution-api/backup.log # Мониторинг в реальном времени tail -f /opt/backups/evolution-api/backup.log # Логи за сегодня grep "$(date '+%Y-%m-%d')" /opt/backups/evolution-api/backup.log ==== Проверка статуса бекапов ==== # Список всех бекапов ls -lah /opt/backups/evolution-api/evolution_backup_*.tar.gz # Размер директории бекапов du -sh /opt/backups/evolution-api/ # Последний успешный бекап grep "завершено успешно" /opt/backups/evolution-api/backup.log | tail -1 ==== Настройка ротации логов ==== # Создаем конфиг для logrotate cat > /etc/logrotate.d/evolution-backup << EOF /opt/backups/evolution-api/backup.log { weekly rotate 8 compress delaycompress notifempty create 644 root root } EOF ===== Восстановление из резервной копии ===== ==== Полное восстановление системы ==== **Внимание!** Процедура восстановления полностью заменит текущие данные. Убедитесь что система остановлена. # 1. Останавливаем Evolution API cd /opt/evolution-api docker-compose down # 2. Создаем резервную копию текущих данных (на всякий случай) mv store store_backup_$(date +%Y%m%d) mv instances instances_backup_$(date +%Y%m%d) mv postgres_data postgres_data_backup_$(date +%Y%m%d) mv redis_data redis_data_backup_$(date +%Y%m%d) # 3. Распаковываем бекап cd /opt/evolution-api tar -xzf /opt/backups/evolution-api/evolution_backup_YYYYMMDD_HHMMSS.tar.gz # 4. Запускаем контейнеры docker-compose up -d # 5. Ждем запуска и проверяем sleep 15 docker-compose ps ==== Восстановление только базы данных ==== # 1. Распаковываем дамп из архива cd /tmp tar -xzf /opt/backups/evolution-api/evolution_backup_YYYYMMDD_HHMMSS.tar.gz evolution_backup_YYYYMMDD_HHMMSS_database.sql # 2. Восстанавливаем базу данных cd /opt/evolution-api export PGPASSWORD="Fd6ffgdkF98hGf69" docker exec -i evolution_postgres psql -U evolution_user -d evolution_db < /tmp/evolution_backup_YYYYMMDD_HHMMSS_database.sql # 3. Перезапускаем API для применения изменений docker-compose restart evolution-api ===== Решение проблем ===== ==== Частые ошибки и решения ==== **Ошибка: "Контейнеры не запущены!"** # Решение: Запустите контейнеры перед созданием бекапа cd /opt/evolution-api docker-compose up -d **Ошибка: "Не удалось создать дамп базы данных"** # Проверяем статус PostgreSQL docker exec evolution_postgres pg_isready -U evolution_user # Проверяем логи PostgreSQL docker logs evolution_postgres # Проверяем подключение docker exec evolution_postgres psql -U evolution_user -d evolution_db -c "SELECT version();" **Ошибка: "Permission denied" при доступе к файлам** # Проверяем и исправляем права sudo chown -R $(whoami):$(whoami) /opt/evolution-api/ sudo chmod -R 755 /opt/evolution-api/ **Контейнеры не запускаются после бекапа** # Проверяем логи Docker docker-compose logs # Принудительно пересоздаем контейнеры docker-compose down docker-compose up -d --force-recreate ==== Проверка целостности бекапов ==== # Тест архива на целостность tar -tzf /opt/backups/evolution-api/evolution_backup_YYYYMMDD_HHMMSS.tar.gz > /dev/null && echo "OK" || echo "CORRUPTED" # Проверка размера бекапа (должен быть больше 1MB) if [ $(stat -f%z /opt/backups/evolution-api/evolution_backup_YYYYMMDD_HHMMSS.tar.gz) -gt 1048576 ]; then echo "Размер бекапа нормальный" else echo "Подозрительно маленький размер бекапа" fi ==== Тестирование восстановления ==== Рекомендуется периодически тестировать процедуру восстановления: # Создаем тестовую среду mkdir -p /tmp/evolution-test cd /tmp/evolution-test # Распаковываем последний бекап tar -xzf /opt/backups/evolution-api/evolution_backup_$(ls -t /opt/backups/evolution-api/evolution_backup_*.tar.gz | head -1 | cut -d'/' -f5) # Проверяем содержимое ls -la echo "Тест восстановления завершен. Проверьте содержимое папки /tmp/evolution-test" ===== Рекомендации по безопасности ===== * **Шифрование бекапов**: Рассмотрите использование GPG для шифрования архивов * **Удаленное хранение**: Копируйте бекапы на удаленный сервер или облачное хранилище * **Мониторинг доступа**: Следите за доступом к директории с бекапами * **Регулярное тестирование**: Тестируйте восстановление минимум раз в месяц * **Документирование изменений**: Ведите журнал всех изменений в системе ===== Контакты и поддержка ===== При возникновении проблем с резервным копированием: - Проверьте логи: `/opt/backups/evolution-api/backup.log` - Проверьте системные ресурсы: `df -h` и `free -h` - Обратитесь к системному администратору - Создайте issue в системе отслеживания задач --- //Документ создан: {{ CURRENT_DATE }} | Версия: 1.0 | Автор: System Admin//