vm:chatwoot:03-backup

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
vm:chatwoot:03-backup [2025/08/28 21:12] – ↷ Имя страницы vm:chatwoot:02-backup изменено на vm:chatwoot:03-backup adminvm:chatwoot:03-backup [2025/08/30 23:56] (текущий) admin
Строка 1: Строка 1:
-====== Резервное копирование Chatwoot ======+====== Автоматическое резервное копирование Chatwoot ======
  
 ===== Описание ===== ===== Описание =====
  
-Автоматическое резервное копирование системы Chatwoot включает в себя создание SQL дампа базы данных PostgreSQL и архивирование всех важных файлов системы.+Система автоматического резервного копирования для Chatwootкоторая создает полные бекапы всех данныхвключая базу данных PostgreSQL, Redis, файлы медиа и конфигурации.
  
-===== Что включается в резервную копию =====+**ВАЖНО**: Скрипт автоматически включает ВСЁ содержимое папки `/opt/chatwoot/chatwoot_data/` - любые новые файлы и папки попадут в бекап автоматически.
  
-  * **База данных** - SQL дамп базы ''chatwoot_production'' через ''pg_dump'' +===== Что включается в бекап =====
-  * **Файлы хранилища** - директория ''storage/'' с загруженными файлами и изображениями +
-  * **Данные PostgreSQL** - директория ''postgres_data/'' с бинарными данными БД +
-  * **Данные Redis** - директория ''redis_data/'' с кэшем и очередями задач +
-  * **Конфигурация** - файлы ''docker-compose.yml'' и ''.env''+
  
-**⚠️ Важно:** Директория ''postgres_data/'' включается для полного резервирования, но при необходимости её можно исключить из архива, так как SQL дамп базы данных уже содержит все необходимые данные для восстановления. Бинарное копирование ''postgres_data/'' требуется только при необходимости точного клонирования PostgreSQL с сохранением всех системных настроек.+^ Компонент ^ Описание ^ Расположение 
 +| База данных PostgreSQL | Полный дамп схемы и данных | `/opt/chatwoot/chatwoot_data/postgres_data/` | 
 +| Redis данные | Дамп всех ключей и значений | `/opt/chatwoot/chatwoot_data/redis_data/` | 
 +| Медиа файлы | Загруженные файлы пользователей | `/opt/chatwoot/chatwoot_data/storage/` | 
 +| Конфигурация времени | Настройки часового пояса | `/opt/chatwoot/chatwoot_data/config/` | 
 +| Docker конфигурация | docker-compose.yml и .env | `/opt/chatwoot/chatwoot_dock/` | 
 +| **Все новые папки** | Автоматически | `/opt/chatwoot/chatwoot_data/*` |
  
-===== Установка скрипта резервного копирования =====+**Преимущество**: При добавлении новых папок в `/opt/chatwoot/chatwoot_data/` они автоматически попадут в следующий бекап без изменения скрипта.
  
-==== 1. Создание директорий ====+====Структура проекта ===== 
 + 
 +<code> 
 +/opt/ 
 +├── chatwoot/ 
 +│   ├── chatwoot_dock/           # Docker Compose проект 
 +│   │   ├── docker-compose.yml   # Конфигурация контейнеров 
 +│   │   └── .env                 # Переменные окружения 
 +│   └── chatwoot_data/           # Все данные приложения 
 +│       ├── postgres_data/       # База данных 
 +│       ├── redis_data/          # Кэш 
 +│       ├── storage/             # Медиа файлы 
 +│       └── config/              # Пользовательские конфигурации 
 +├── backups/ 
 +│   └── chatwoot/                # Папка для бекапов 
 +└── scripts/ 
 +    └── chatwoot-backup.sh       # Скрипт резервного копирования 
 +</code> 
 + 
 +===== Установка и настройка ===== 
 + 
 +==== Шаг 1: Создание структуры папок ====
  
 <code bash> <code bash>
-mkdir -p /opt/scripts +# Создание необходимых папок 
-mkdir -p /opt/backups/chatwoot+sudo mkdir -p /opt/scripts 
 +sudo mkdir -p /opt/backups/chatwoot 
 +sudo chown -R $USER:$USER /opt/backups 
 +sudo chown -R $USER:$USER /opt/scripts
 </code> </code>
  
-==== 2Создание скрипта ====+==== Шаг 2Создание скрипта ====
  
-Создайте файл ''/opt/scripts/chatwoot-backup.sh'':+Создайте файл `/opt/scripts/chatwoot-backup.sh`:
  
 <code bash> <code bash>
-nano /opt/scripts/chatwoot-backup.sh+sudo nano /opt/scripts/chatwoot-backup.sh
 </code> </code>
  
-Вставьте следующий код:+Вставьте следующий код, заменив пароли на свои:
  
 <code bash> <code bash>
 #!/bin/bash #!/bin/bash
 + 
 # Скрипт резервного копирования Chatwoot # Скрипт резервного копирования Chatwoot
 # Запуск: /opt/scripts/chatwoot-backup.sh # Запуск: /opt/scripts/chatwoot-backup.sh
 + 
 # Настройки # Настройки
-COMPOSE_FILE="/opt/chatwoot/docker-compose.yml" +COMPOSE_FILE="/opt/chatwoot/chatwoot_dock/docker-compose.yml" 
-CHATWOOT_DIR="/opt/chatwoot"+CHATWOOT_DIR="/opt/chatwoot/chatwoot_dock"
 BACKUP_DIR="/opt/backups/chatwoot" BACKUP_DIR="/opt/backups/chatwoot"
 DATE=$(date +"%Y%m%d_%H%M%S") DATE=$(date +"%Y%m%d_%H%M%S")
 BACKUP_NAME="chatwoot_backup_${DATE}" BACKUP_NAME="chatwoot_backup_${DATE}"
-RETENTION_DAYS=30  # Храним бекапы 30 дней +RETENTION_DAYS=10  # Храним бекапы 10 дней 
- +  
-# Настройки базы данных +# Настройки базы данных - ИЗМЕНИТЕ НА СВОИ 
-DB_NAME="chatwoot_production"+DB_CONTAINER="chatwoot_postgres"
 DB_USER="postgres" DB_USER="postgres"
-DB_PASSWORD="YOUR_DB_PASSWORD # Замените на ваш пароль от БД +DB_PASSWORD="YOUR_POSTGRES_PASSWORD # Замените на ваш пароль 
-DB_CONTAINER="chatwoot_postgres_1"+DB_NAME="chatwoot_production"
  
 +# Настройки Redis - ИЗМЕНИТЕ НА СВОИ
 +REDIS_CONTAINER="chatwoot_redis"
 +REDIS_PASSWORD="YOUR_REDIS_PASSWORD"  # Замените на ваш пароль
 + 
 # Логирование # Логирование
 LOG_FILE="${BACKUP_DIR}/backup.log" LOG_FILE="${BACKUP_DIR}/backup.log"
 + 
 # Функция логирования # Функция логирования
 log() { log() {
     echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"     echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
 } }
 + 
 # Создаем директорию для бекапов если не существует # Создаем директорию для бекапов если не существует
 mkdir -p "$BACKUP_DIR" mkdir -p "$BACKUP_DIR"
 + 
 log "=== Начало резервного копирования Chatwoot ===" log "=== Начало резервного копирования Chatwoot ==="
 + 
 # Проверяем что compose файл существует # Проверяем что compose файл существует
 if [ ! -f "$COMPOSE_FILE" ]; then if [ ! -f "$COMPOSE_FILE" ]; then
Строка 72: Строка 102:
     exit 1     exit 1
 fi fi
 + 
 # Переходим в директорию с Chatwoot # Переходим в директорию с Chatwoot
 cd "$CHATWOOT_DIR" || { cd "$CHATWOOT_DIR" || {
Строка 80: Строка 110:
  
 # Проверяем что контейнеры запущены # Проверяем что контейнеры запущены
-if ! docker-compose ps | grep -q "Up"; then +log "Проверяем статус контейнеров..." 
-    log "ПРЕДУПРЕЖДЕНИЕНе все контейнеры запущены"+if ! docker-compose -f "$COMPOSE_FILE" ps | grep -q "Up"; then 
 +    log "ОШИБКАКонтейнеры не запущены! Запустите их перед созданием бекапа." 
 +    exit 1
 fi fi
  
-Создаем дамп базы данных +Показываем что будет включено в бекап 
-log "Создаем дамп базы данных..." +log "Анализируем содержимое /opt/chatwoot/chatwoot_data/..." 
-DB_DUMP_FILE="${BACKUP_DIR}/${BACKUP_NAME}_database.sql"+CHATWOOT_DATA_CONTENTS=$(ls -la /opt/chatwoot/chatwoot_data/ 2>/dev/null | grep -v "^total" | grep -v "^\." | awk '{print $9}' | grep -v "^$" | tr '\n' ' ') 
 +log "Будет включено в бекап: $CHATWOOT_DATA_CONTENTS"
  
-docker exec -t "$DB_CONTAINER" pg_dump -U "$DB_USER" -d "$DB_NAME" > "$DB_DUMP_FILE"+# Создаем дамп базы данных (пока контейнеры работают) 
 +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
  
 +# Создаем дамп Redis
 +log "Создаем дамп Redis..."
 +REDIS_DUMP_PATH="${BACKUP_DIR}/${BACKUP_NAME}_redis.rdb"
 +# Создаем дамп внутри контейнера во временный файл
 +REDIS_TEMP_PATH="/tmp/redis_dump.rdb"
 +docker exec "$REDIS_CONTAINER" redis-cli -a "$REDIS_PASSWORD" --rdb "$REDIS_TEMP_PATH" 2>> "$LOG_FILE"
 if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
-    log "Дамп базы данных создан: $DB_DUMP_FILE+    # Копируем дамп из контейнера 
-    DB_SIZE=$(du -h "$DB_DUMP_FILE" | cut -f1) +    docker cp "$REDIS_CONTAINER:$REDIS_TEMP_PATH" "$REDIS_DUMP_PATH" 2>> "$LOG_FILE" 
-    log "Размер дампа базы данных: $DB_SIZE"+    if [ -f "$REDIS_DUMP_PATH" ]; then 
 +        log "Дамп Redis создан: $REDIS_DUMP_PATH
 +        REDIS_DUMP_SIZE=$(du -h "$REDIS_DUMP_PATH" | cut -f1) 
 +        log "Размер дампа Redis: $REDIS_DUMP_SIZE" 
 +        # Удаляем временный файл из контейнера 
 +        docker exec "$REDIS_CONTAINERrm -f "$REDIS_TEMP_PATH" 2>/dev/null 
 +    else 
 +        log "ПРЕДУПРЕЖДЕНИЕ: Файл дампа Redis не найден" 
 +        REDIS_DUMP_SIZE="0B" 
 +    fi
 else else
-    log "ОШИБКА: Не удалось создать дамп базы данных+    log "ПРЕДУПРЕЖДЕНИЕ: Не удалось создать дамп Redis
-    exit 1+    REDIS_DUMP_SIZE="0B"
 fi fi
  
-# Останавливаем контейнеры для консистентного бекапа файлов+# Очищаем переменную окружения 
 +unset PGPASSWORD 
 + 
 +# Останавливаем контейнеры
 log "Останавливаем контейнеры Chatwoot..." log "Останавливаем контейнеры Chatwoot..."
 docker-compose -f "$COMPOSE_FILE" down docker-compose -f "$COMPOSE_FILE" down
 + 
 if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
     log "Контейнеры успешно остановлены"     log "Контейнеры успешно остановлены"
Строка 109: Строка 176:
     exit 1     exit 1
 fi fi
 + 
 # Ждем пару секунд для полной остановки # Ждем пару секунд для полной остановки
 sleep 5 sleep 5
 + 
 +# Создаем архив с данными - АВТОМАТИЧЕСКИ ВКЛЮЧАЕТ ВСЁ СОДЕРЖИМОЕ chatwoot_data
 +log "Создаем архив данных (включает ВСЁ содержимое chatwoot_data)..."
 +BACKUP_PATH="${BACKUP_DIR}/${BACKUP_NAME}.tar.gz"
  
-# Создаем архив с данными +# Создаем архив с автоматическим включением ВСЕГО содержимого /opt/chatwoot/chatwoot_data
-log "Создаем архив данных..." +tar -czf "$BACKUP_PATH" \
-BACKUP_ARCHIVE="${BACKUP_DIR}/${BACKUP_NAME}.tar.gz" +
- +
-tar -czf "$BACKUP_ARCHIVE" \+
     --exclude='*.log' \     --exclude='*.log' \
     --exclude='**/lost+found' \     --exclude='**/lost+found' \
-    --exclude='tmp/' \ +    --exclude='**/.tmp' \ 
-    --exclude='log/' \ +    --exclude='**/tmp/*' \ 
-    storage/ \ +    --exclude='**/.cache' 
-    postgres_data/ \ +    -C "$BACKUP_DIR" "${BACKUP_NAME}_database.sql"
-    redis_data/ \+    $([ -f "$REDIS_DUMP_PATH" ] && echo "-C $BACKUP_DIR ${BACKUP_NAME}_redis.rdb") \ 
 +    -C "/opt/chatwoot" 
 +    chatwoot_data
 +    -C "$CHATWOOT_DIR" \
     docker-compose.yml \     docker-compose.yml \
     .env     .env
  
 if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
-    log "Архив создан: $BACKUP_ARCHIVE"+    log "Архив создан: $BACKUP_PATH" 
 +  
 +    # Получаем размер архива 
 +    BACKUP_SIZE=$(du -h "$BACKUP_PATH" | cut -f1) 
 +    log "Размер архива: $BACKUP_SIZE" 
 +     
 +    # Удаляем отдельные файлы дампов, так как они теперь в архиве 
 +    rm -f "$DB_DUMP_PATH" 
 +    [ -f "$REDIS_DUMP_PATH" ] && rm -f "$REDIS_DUMP_PATH" 
 +    log "Отдельные файлы дампов удалены (включены в архив)" 
 +     
 +    # Показываем что попало в архив 
 +    log "Содержимое архива (основные папки и файлы):" 
 +    tar -tzf "$BACKUP_PATH" | head -20 | while read file; do 
 +        log "  $file" 
 +    done 
 +    TOTAL_FILES=$(tar -tzf "$BACKUP_PATH" | wc -l) 
 +    log "Общее количество файлов в архиве: $TOTAL_FILES"
          
-    # Получаем размер архива 
-    ARCHIVE_SIZE=$(du -h "$BACKUP_ARCHIVE" | cut -f1) 
-    log "Размер архива: $ARCHIVE_SIZE" 
 else else
     log "ОШИБКА: Не удалось создать архив"     log "ОШИБКА: Не удалось создать архив"
-    + 
     # Пытаемся запустить контейнеры даже при ошибке     # Пытаемся запустить контейнеры даже при ошибке
     log "Запускаем контейнеры после ошибки..."     log "Запускаем контейнеры после ошибки..."
Строка 142: Строка 227:
     exit 1     exit 1
 fi fi
 + 
 # Запускаем контейнеры обратно # Запускаем контейнеры обратно
 log "Запускаем контейнеры Chatwoot..." log "Запускаем контейнеры Chatwoot..."
 docker-compose -f "$COMPOSE_FILE" up -d docker-compose -f "$COMPOSE_FILE" up -d
 + 
 if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
     log "Контейнеры успешно запущены"     log "Контейнеры успешно запущены"
Строка 153: Строка 238:
     exit 1     exit 1
 fi fi
 + 
 # Ждем запуска сервисов # Ждем запуска сервисов
-log "Ожидаем запуска сервисов..." +sleep 15 
-sleep 30 + 
 # Проверяем что все контейнеры работают # Проверяем что все контейнеры работают
 log "Проверяем статус контейнеров..." log "Проверяем статус контейнеров..."
-if docker-compose -f "$COMPOSE_FILE" ps | grep -"Up"; then +RUNNING_CONTAINERS=$(docker-compose -f "$COMPOSE_FILE" ps --services --filter "status=running" wc -l) 
-    log "Контейнеры работают корректно"+TOTAL_CONTAINERS=$(docker-compose -f "$COMPOSE_FILEps --services | wc -l) 
 +if [ "$RUNNING_CONTAINERS" -eq "$TOTAL_CONTAINERS" ]; then 
 +    log "Все контейнеры ($RUNNING_CONTAINERS/$TOTAL_CONTAINERS) работают корректно"
 else else
-    log "ПРЕДУПРЕЖДЕНИЕ: Некоторые контейнеры могут работать некорректно"+    log "ПРЕДУПРЕЖДЕНИЕ: Работают только $RUNNING_CONTAINERS из $TOTAL_CONTAINERS контейнеров"
 fi fi
  
-# Проверяем подключение к базе данных+# Проверяем доступность базы данных
 log "Проверяем подключение к базе данных..." log "Проверяем подключение к базе данных..."
-if docker exec "$DB_CONTAINER" pg_isready -U "$DB_USER" >/dev/null 2>&1; then +export PGPASSWORD="$DB_PASSWORD" 
-    log "База данных доступна"+if docker exec "$DB_CONTAINER" pg_isready -U "$DB_USER" -d "$DB_NAME" > /dev/null 2>&1; then 
 +    log "База данных доступна и готова к работе"
 else else
     log "ПРЕДУПРЕЖДЕНИЕ: База данных может быть недоступна"     log "ПРЕДУПРЕЖДЕНИЕ: База данных может быть недоступна"
 fi fi
  
-Создаем итоговый архив с дампом базы данных +Проверяем что база данных Chatwoot содержит нужные таблицы 
-log "Создаем итоговый архив с дампом базы данных...+log "Проверяем структуру базы данных Chatwoot..." 
-FINAL_BACKUP="${BACKUP_DIR}/${BACKUP_NAME}_complete.tar.gz"+if docker exec "$DB_CONTAINER" psql -U "$DB_USER" -d "$DB_NAME" -c "\dt" 2>/dev/null | grep -q "accounts\|users\|conversations"; then 
 +    log "База данных Chatwoot содержит основные таблицы" 
 +else 
 +    log "ПРЕДУПРЕЖДЕНИЕ: База данных Chatwoot может быть неполной
 +fi
  
-tar -czf "$FINAL_BACKUP" -"$BACKUP_DIR" "${BACKUP_NAME}.tar.gz" "${BACKUP_NAME}_database.sql"+# Проверяем Redis контейнер 
 +log "Проверяем Redis..." 
 +if docker exec "$REDIS_CONTAINERredis-cli -a "$REDIS_PASSWORDping 2>/dev/null | grep -q "PONG"; then 
 +    log "Redis работает корректно" 
 +else 
 +    log "ПРЕДУПРЕЖДЕНИЕ: Redis может работать некорректно" 
 +fi
  
-if [ $? -eq 0 ]; then +# Проверяем Rails контейнер 
-    log "Итоговый архив создан: $FINAL_BACKUP" +log "Проверяем Rails приложение..." 
-     +if docker exec chatwoot_rails bundle exec rails runner "puts 'Chatwoot OK'2>/dev/null | grep -q "Chatwoot OK"; then 
-    # Получаем размер итогового архива +    log "Rails приложение работает корректно"
-    FINAL_SIZE=$(du -h "$FINAL_BACKUP" | cut -f1) +
-    log "Размер итогового архива: $FINAL_SIZE" +
-     +
-    # Удаляем промежуточные файлы +
-    rm -f "$BACKUP_ARCHIVE" "$DB_DUMP_FILE+
-    log "Промежуточные файлы удалены"+
 else else
-    log "ОШИБКАНе удалось создать итоговый архив"+    log "ПРЕДУПРЕЖДЕНИЕRails приложение может работать некорректно"
 fi fi
  
 +unset PGPASSWORD
 + 
 # Удаляем старые бекапы # Удаляем старые бекапы
 log "Удаляем бекапы старше $RETENTION_DAYS дней..." log "Удаляем бекапы старше $RETENTION_DAYS дней..."
-find "$BACKUP_DIR" -name "chatwoot_backup_*_complete.tar.gz" -mtime +$RETENTION_DAYS -delete +DELETED_COUNT=$(find "$BACKUP_DIR" -name "chatwoot_backup_*.tar.gz" -mtime +$RETENTION_DAYS -delete -print | wc -l) 
-find "$BACKUP_DIR" -name "chatwoot_backup_*.tar.gz" -mtime +$RETENTION_DAYS -delete +log "Удалено старых бекапов: $DELETED_COUNT
-find "$BACKUP_DIR-name "chatwoot_backup_*_database.sql" -mtime +$RETENTION_DAYS -delete + 
 # Показываем статистику бекапов # Показываем статистику бекапов
-BACKUP_COUNT=$(ls -1 "${BACKUP_DIR}"/chatwoot_backup_*_complete.tar.gz 2>/dev/null | wc -l) +BACKUP_COUNT=$(ls -1 "${BACKUP_DIR}"/chatwoot_backup_*.tar.gz 2>/dev/null | wc -l
-log "Общее количество полных бекапов: $BACKUP_COUNT"+TOTAL_SIZE=$(du -sh "${BACKUP_DIR}" 2>/dev/null | cut -f1
 +log "Общее количество бекапов: $BACKUP_COUNT" 
 +log "Общий размер папки бекапов: $TOTAL_SIZE"
  
-# Показываем общий размер всех бекапов +# Получаем информацию о свободном месте на диске 
-TOTAL_SIZE=$(du -sh "$BACKUP_DIR"cut -f1+BACKUP_DISK_USAGE=$(df -h "$BACKUP_DIR" | awk 'NR==2 {print $4 " свободно из " $2 " (" $5 " занято)"}'
-log "Общий размер директории бекапов: $TOTAL_SIZE"+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 "=== Резервное копирование завершено успешно ===" log "=== Резервное копирование завершено успешно ==="
  
-# Отправляем уведомление (раскомментируйте если нужно) +# Формируем сообщение для Telegram 
-curl -s -X POST "https://api.telegram.org/botYOUR_BOT_TOKEN/sendMessage"+TELEGRAM_MESSAGE="✅ Chatwoot backup completed 
-    -d chat_id="YOUR_CHAT_ID"+📁 Backup: $BACKUP_NAME ($BACKUP_SIZE) 
-    -d text="✅ Chatwoot backup completed: $BACKUP_NAME ($FINAL_SIZE)"+💾 DB dump: $DB_DUMP_SIZE 
 +🗄️ Redis dump: $REDIS_DUMP_SIZE 
 +📊 Total backups: $BACKUP_COUNT 
 +📄 Files in archive: $TOTAL_FILES 
 +💿 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 (опционально
 +# Замените на свой BOT_TOKEN и CHAT_ID 
 +curl -s -X POST "https://api.telegram.org/bot[YOUR_BOT_TOKEN]/sendMessage"
 +     -d chat_id="[YOUR_CHAT_ID]" \ 
 +     -d text="$TELEGRAM_MESSAGE> /dev/null
  
 exit 0 exit 0
 </code> </code>
  
-==== 3Настройка прав доступа ====+**Обязательно измените**: 
 +  * `YOUR_POSTGRES_PASSWORD` на ваш пароль PostgreSQL 
 +  * `YOUR_REDIS_PASSWORD` на ваш пароль Redis   
 +  * `[YOUR_BOT_TOKEN]` на токен вашего Telegram бота (опционально) 
 +  * `[YOUR_CHAT_ID]` на ваш Chat ID в Telegram (опционально) 
 + 
 +==== Шаг 3Настройка прав доступа ====
  
 <code bash> <code bash>
-chmod +x /opt/scripts/chatwoot-backup.sh+# Делаем скрипт исполняемым 
 +sudo chmod +x /opt/scripts/chatwoot-backup.sh 
 + 
 +# Проверяем права 
 +ls -la /opt/scripts/chatwoot-backup.sh
 </code> </code>
  
-===== Настройка автоматического запуска =====+==== Шаг 4: Тестовый запуск ====
  
-==== Добавление в crontab ====+<code bash> 
 +# Запуск тестового бекапа 
 +sudo /opt/scripts/chatwoot-backup.sh 
 + 
 +# Проверка результата 
 +ls -la /opt/backups/chatwoot/ 
 +cat /opt/backups/chatwoot/backup.log 
 +</code> 
 + 
 +===== Автоматизация через Cron ===== 
 + 
 +==== Настройка ежедневного бекапа ====
  
 <code bash> <code bash>
-crontab -e+# Открываем crontab 
 +sudo crontab -e 
 + 
 +# Добавляем задачу (бекап каждый день в 2:00 ночи) 
 +0 2 * * * /opt/scripts/chatwoot-backup.sh >> /var/log/chatwoot-backup-cron.log 2>&
 + 
 +# Сохраняем и выходим (Ctrl+X, Y, Enter)
 </code> </code>
  
-Добавьте строку для ежедневного запуска в 2:00 ночи:+==== Альтернативные расписания ====
  
 <code> <code>
-* * * /opt/scripts/chatwoot-backup.sh >> /opt/backups/chatwoot/cron.log 2>&+# Каждый день в 3:00 
-</code>+* * * /opt/scripts/chatwoot-backup.sh
  
-===== Тестирование скрипта =====+# Каждые 12 часов (в 6:00 и 18:00) 
 +0 6,18 * * * /opt/scripts/chatwoot-backup.sh
  
-==== Ручной запуск ====+# Каждый день в 1:30 ночи 
 +30 1 * * * /opt/scripts/chatwoot-backup.sh
  
-<code bash> +# Только в выходные в 4:00 
-/opt/scripts/chatwoot-backup.sh+0 4 * * 6,0 /opt/scripts/chatwoot-backup.sh
 </code> </code>
  
-==== Проверка результатов ====+==== Проверка работы Cron ====
  
 <code bash> <code bash>
-# Проверить созданные файлы +# Проверить статус cron 
-ls -la /opt/backups/chatwoot/+sudo systemctl status cron
  
-# Посмотреть лог +# Посмотреть активные задачи 
-tail -f /opt/backups/chatwoot/backup.log+sudo crontab -l
  
-# Проверить размер бекапов +# Посмотреть логи cron 
-du -sh /opt/backups/chatwoot/+sudo tail -/var/log/chatwoot-backup-cron.log
 </code> </code>
  
-===== Настройка параметров =====+===== Мониторинг и уведомления =====
  
-==== Изменение времени хранения бекапов ====+==== Настройка Telegram бота ====
  
-В скрипте найдите и измените строку:+1. **Создайте бота**: Отправьте `/start` боту @BotFather в Telegram 
 +2. **Получите токен**: Сохраните Bot Token  
 +3. **Узнайте Chat ID**: Отправьте сообщение боту, затем откройте: 
 +   `https://api.telegram.org/bot[YOUR_BOT_TOKEN]/getUpdates` 
 + 
 +==== Проверка уведомлений ====
  
 <code bash> <code bash>
-RETENTION_DAYS=30  Храним бекапы 30 дней+Тест отправки сообщения (замените токен и chat_id) 
 +curl -s -X POST "https://api.telegram.org/bot[YOUR_BOT_TOKEN]/sendMessage"
 +     -d chat_id="[YOUR_CHAT_ID]"
 +     -d text="Test message from Chatwoot backup script"
 </code> </code>
  
-==== Настройки базы данных ==== +==== Мониторинг места на диске ====
- +
-При необходимости измените параметры подключения к БД:+
  
 <code bash> <code bash>
-DB_NAME="chatwoot_production" +Проверка места в папке бекапов 
-DB_USER="postgres"  +df -h /opt/backups/chatwoot/ 
-DB_PASSWORD="YOUR_DB_PASSWORD"  Замените на ваш пароль от БД + 
-DB_CONTAINER="chatwoot_postgres_1"+# Размер всех бекапов 
 +du -sh /opt/backups/chatwoot/ 
 + 
 +# Список всех бекапов с размерами 
 +ls -lah /opt/backups/chatwoot/chatwoot_backup_*.tar.gz
 </code> </code>
  
-===== Уведомления =====+===== Восстановление из бекапа =====
  
-==== Настройка Telegram уведомлений ====+==== Полное восстановление ====
  
-Раскомментируйте и настройте в конце скрипта:+<code bash> 
 +# Остановите Chatwoot 
 +cd /opt/chatwoot/chatwoot_dock 
 +docker-compose down 
 + 
 +# Найдите нужный бекап 
 +ls -la /opt/backups/chatwoot/ 
 + 
 +# Извлеките архив (замените на ваш файл) 
 +cd /tmp 
 +tar -xzf /opt/backups/chatwoot/chatwoot_backup_YYYYMMDD_HHMMSS.tar.gz 
 + 
 +# Восстановите данные 
 +sudo rm -rf /opt/chatwoot/chatwoot_data/
 +sudo cp -r chatwoot_data/* /opt/chatwoot/chatwoot_data/ 
 + 
 +# Восстановите конфигурацию (если нужно) 
 +cp docker-compose.yml /opt/chatwoot/chatwoot_dock/ 
 +cp .env /opt/chatwoot/chatwoot_dock/ 
 + 
 +# Запустите Chatwoot 
 +cd /opt/chatwoot/chatwoot_dock 
 +docker-compose up -d 
 +</code> 
 + 
 +==== Восстановление только базы данных ====
  
 <code bash> <code bash>
-curl -s -X POST "https://api.telegram.org/botYOUR_BOT_TOKEN/sendMessage" \ +# Найдите дамп базы в архиве 
-    -d chat_id="YOUR_CHAT_ID\ +tar -tzf /opt/backups/chatwoot/chatwoot_backup_YYYYMMDD_HHMMSS.tar.gz | grep database.sql 
-    -d text="✅ Chatwoot backup completed: $BACKUP_NAME ($FINAL_SIZE)"+ 
 +# Извлеките дамп 
 +tar -xzf /opt/backups/chatwoot/chatwoot_backup_YYYYMMDD_HHMMSS.tar.gz chatwoot_backup_YYYYMMDD_HHMMSS_database.sql 
 + 
 +# Восстановите в контейнер (Chatwoot должен быть запущен) 
 +export PGPASSWORD="YOUR_POSTGRES_PASSWORD
 +cat chatwoot_backup_YYYYMMDD_HHMMSS_database.sql | docker exec -i chatwoot_postgres psql -U postgres -d chatwoot_production 
 +unset PGPASSWORD
 </code> </code>
  
-Замените: +===== Устранение неполадок =====
-  * ''YOUR_BOT_TOKEN'' - токен вашего Telegram бота +
-  * ''YOUR_CHAT_ID'' - ваш chat ID в Telegram+
  
-===== Восстановление из резервной копии =====+==== Основные проблемы ====
  
-==== 1. Распаковка архива ====+=== Ошибка "Container not found" ===
  
 +**Причина**: Неправильные имена контейнеров
 +
 +**Решение**: Проверьте имена контейнеров:
 <code bash> <code bash>
-cd /opt/backups/chatwoot/ +docker ps 
-tar -xzf chatwoot_backup_YYYYMMDD_HHMMSS_complete.tar.gz+# Обновите переменные DB_CONTAINER и REDIS_CONTAINER в скрипте
 </code> </code>
  
-==== 2. Восстановление базы данных ====+=== Ошибка доступа к базе данных ===
  
 +**Причина**: Неправильный пароль или имя базы
 +
 +**Решение**: Проверьте настройки в `.env` файле:
 <code bash> <code bash>
-# Остановить Chatwoot +cat /opt/chatwoot/chatwoot_dock/.env | grep -i postgres 
-cd /opt/chatwoot +# Обновите переменные в скрипте согласно .env 
-docker-compose down+</code>
  
-# Очистить существующую базу данных (осторожно!) +=== Нехватка места на диске === 
-docker-compose up -d postgres + 
-docker exec -it chatwoot_postgres_1 dropdb -U postgres chatwoot_production +**Причина**: Заполнен диск 
-docker exec -it chatwoot_postgres_1 createdb -U postgres chatwoot_production+ 
 +**Решение**:  
 +<code bash> 
 +# Удалите старые бекапы вручную 
 +find /opt/backups/chatwoot/ -name "chatwoot_backup_*.tar.gz" -mtime +7 -delete
  
-Восстановить из дампа +Уменьшите RETENTION_DAYS в скрипте
-docker exec -i chatwoot_postgres_1 psql -U postgres -d chatwoot_production < /opt/backups/chatwoot/chatwoot_backup_YYYYMMDD_HHMMSS_database.sql+
 </code> </code>
  
-==== 3. Восстановление файлов ====+==== Проверка логов ====
  
 <code bash> <code bash>
-Распаковать файлы системы +Основной лог скрипта 
-cd /opt/chatwoot +tail -/opt/backups/chatwoot/backup.log
-tar -xzf /opt/backups/chatwoot/chatwoot_backup_YYYYMMDD_HHMMSS.tar.gz+
  
-Запустить систему +Лог cron 
-docker-compose up -d+tail -f /var/log/chatwoot-backup-cron.log 
 + 
 +# Логи Docker контейнеров 
 +docker logs chatwoot_postgres 
 +docker logs chatwoot_redis
 </code> </code>
  
-===== Мониторинг и обслуживание =====+===== Дополнительные настройки =====
  
-==== Проверка статуса бекапов ====+==== Изменение времени хранения ====
  
 +В скрипте измените:
 <code bash> <code bash>
-Просмотр последних логов +RETENTION_DAYS=10  Храним бекапы 10 дней 
-tail -n 50 /opt/backups/chatwoot/backup.log+</code>
  
-# Статистика бекапов +==== Изменение папки бекапов ====
-ls -lh /opt/backups/chatwoot/chatwoot_backup_*_complete.tar.gz+
  
-# Общий размер +В скрипте измените: 
-du -sh /opt/backups/chatwoot/+<code bash> 
 +BACKUP_DIR="/opt/backups/chatwoot"
 </code> </code>
  
-==== Очистка старых бекапов (ручная) ====+**Рекомендация**: Для больших проектов рассмотрите возможность хранения бекапов на отдельном диске или в облачном хранилище. 
 + 
 +===== Безопасность ===== 
 + 
 +==== Защита скрипта ====
  
 <code bash> <code bash>
-Удалить бекапы старше 60 дней +Ограничить доступ только root 
-find /opt/backups/chatwoot/ -name "chatwoot_backup_*_complete.tar.gz" -mtime +60 -delete+sudo chown root:root /opt/scripts/chatwoot-backup.sh 
 +sudo chmod 700 /opt/scripts/chatwoot-backup.sh 
 + 
 +# Проверить права 
 +ls -la /opt/scripts/chatwoot-backup.sh
 </code> </code>
  
-===== Оптимизация размера бекапов =====+==== Шифрование бекапов ====
  
-**💡 Совет по оптимизации:** Если размер бекапов слишком большой, можно исключить директорию ''postgres_data/'' из архива, изменив строку в скрипте:+Для дополнительной безопасности можно добавить шифрование:
  
 <code bash> <code bash>
-tar -czf "$BACKUP_ARCHIVE" \ +# Добавьте в скрипт после создания архива: 
-    --exclude='*.log'+gpg --symmetric --cipher-algo AES256 "$BACKUP_PATH" 
-    --exclude='**/lost+found'+rm "$BACKUP_PATH"  # Удаляем незашифрованную версию
-    --exclude='tmp/'+
-    --exclude='log/'+
-    storage/ \ +
-    # postgres_data/ # Закомментировать эту строку +
-    redis_data/ \ +
-    docker-compose.yml \ +
-    .env+
 </code> </code>
  
-SQL дамп базы данных содержит все необходимые данные для восстановления системы. Бинарная копия ''postgres_data/'' нужна только для точного клонирования PostgreSQL.+===== Заключение =====
  
-===== Безопасность =====+Данный скрипт обеспечивает:
  
-  Убедитесь, что директория ''/opt/backups/chatwoot/'' доступна только root +**Полное резервное копирование** всех данных Chatwoot 
-  * Регулярно проверяйте логи на наличие ошибок +- **Автоматическое включение** новых файлов и папок в `/opt/chatwoot/chatwoot_data/` 
-  Периодически тестируйте процедуру восстановления +*езопасное выполнение** с остановкой и запуском контейнеров 
-  Рассмотрите возможность хранения бекапов на удаленном сервере+- **Очистку старых бекапов** для экономии места 
 +- **Детальное логирование** всех операций 
 +- **Уведомления в Telegram** о статусе бекапа 
 +- **Мониторинг места на диске** с предупреждениями
  
-===== Структура файлов =====+**Результат**: Надежная система резервного копирования, которая автоматически адаптируется к изменениям в структуре данных Chatwoot.
  
-<code> +---- 
-/opt/scripts/chatwoot-backup.sh          # Скрипт резервного копирования + 
-/opt/backups/chatwoot/                   # Директория бекапов +//Инструкция протестирована на Ubuntu Server с Docker Compose. Регулярно проверяйте работоспособность бекапов и процедуры восстановления.//
-├── backup.log                          # Лог файл +
-├── cron.log                            # Лог cron задач +
-└── chatwoot_backup_YYYYMMDD_HHMMSS_complete.tar.gz  # Архивы бекапов +
-</code>+
  • vm/chatwoot/03-backup.1756415562.txt.gz
  • Последнее изменение: 2025/08/28 21:12
  • admin