Содержание

Резервное копирование Evolution API

Описание системы

Evolution API - это система для работы с WhatsApp Business API, развернутая в Docker контейнерах. Система состоит из:

<note important> Данная инструкция предназначена для систем с Evolution API, развернутой через Docker Compose в директории `/opt/evolution-api/`. </note>

Компоненты для резервного копирования

Скрипт создает резервные копии следующих компонентов:

Компонент Описание Расположение
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 дамп базы данных Создается автоматически

Требования

Системные требования

Необходимые пакеты

# 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

<note warning> Безопасность: Обязательно замените все плейсхолдеры на реальные значения! Пароль должен совпадать с `POSTGRES_PASSWORD` из вашего `docker-compose.yml`. </note>

4. Настройка Telegram уведомлений (опционально)

Для получения уведомлений о результатах резервного копирования:

  1. Создайте Telegram бота через [@BotFather](https://t.me/botfather)
  2. Получите токен бота
  3. Узнайте ваш chat_id (можно использовать [@userinfobot](https://t.me/userinfobot))
  4. Замените токен и 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:

Процесс резервного копирования

Скрипт выполняет следующие операции:

  1. Проверка окружения - проверяет наличие файлов и запущенные контейнеры
  2. Создание SQL дампа - создает дамп базы данных PostgreSQL
  3. Остановка контейнеров - корректно останавливает все сервисы
  4. Создание архива - упаковывает все данные в tar.gz
  5. Запуск контейнеров - восстанавливает работу системы
  6. Проверка состояния - проверяет что все сервисы запустились
  7. Очистка старых бекапов - удаляет файлы старше указанного срока
  8. Отправка уведомлений - отправляет статус в Telegram

<note> Время простоя: Обычно система недоступна 30-60 секунд во время создания бекапа. </note>

Мониторинг дискового пространства

Скрипт автоматически отслеживает состояние дискового пространства:

Уровень заполнения Действие Сообщение
< 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

Рекомендации по управлению дисковым пространством:

Мониторинг и логи

Просмотр логов

# Последние 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

Восстановление из резервной копии

Полное восстановление системы

<note warning> Внимание! Процедура восстановления полностью заменит текущие данные. Убедитесь что система остановлена. </note>

# 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"

Рекомендации по безопасности

Контакты и поддержка

При возникновении проблем с резервным копированием:

  1. Проверьте логи: `/opt/backups/evolution-api/backup.log`
  2. Проверьте системные ресурсы: `df -h` и `free -h`
  3. Обратитесь к системному администратору
  4. Создайте issue в системе отслеживания задач

Документ создан: current_date | Версия: 1.0 | Автор: System Admin