====== Резервное копирование 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//