Различия
Показаны различия между двумя версиями страницы.
| Предыдущая версия справа и слева Предыдущая версия | |||
| vm:chatwoot:03-backup [2025/08/30 18:23] – admin | vm:chatwoot:03-backup [2025/08/30 23:56] (текущий) – admin | ||
|---|---|---|---|
| Строка 1: | Строка 1: | ||
| - | ====== | + | ====== |
| ===== Описание ===== | ===== Описание ===== | ||
| - | Автоматизированный скрипт для создания резервных копий **Chatwoot** с поддержкой: | + | Система автоматического резервного копирования для Chatwoot, которая создает полные |
| - | * Дампов базы | + | |
| - | * Дампов Redis | + | |
| - | * Архивирования файлов storage, | + | |
| - | * Автоматической очистки старых бекапов | + | |
| - | * Мониторинга дискового пространства | + | |
| - | * Уведомлений в Telegram | + | |
| - | ===== Требования ===== | + | **ВАЖНО**: |
| - | * Docker и Docker Compose | + | ===== Что включается |
| - | * Bash 4.0+ | + | |
| - | * Утилиты: '' | + | |
| - | * Права | + | |
| - | ===== Установка | + | ^ Компонент ^ Описание ^ Расположение ^ |
| + | | База данных PostgreSQL | Полный дамп схемы и данных | `/ | ||
| + | | Redis данные | Дамп всех ключей и значений | `/ | ||
| + | | Медиа файлы | Загруженные файлы пользователей | `/ | ||
| + | | Конфигурация времени | Настройки часового пояса | `/ | ||
| + | | Docker | ||
| + | | **Все новые папки** | Автоматически | `/ | ||
| - | ==== 1. Создание директорий ==== | + | **Преимущество**: |
| + | |||
| + | ===== Структура проекта ===== | ||
| + | |||
| + | < | ||
| + | /opt/ | ||
| + | ├── chatwoot/ | ||
| + | │ | ||
| + | │ | ||
| + | │ | ||
| + | │ | ||
| + | │ | ||
| + | │ | ||
| + | │ | ||
| + | │ | ||
| + | ├── backups/ | ||
| + | │ | ||
| + | └── scripts/ | ||
| + | └── chatwoot-backup.sh | ||
| + | </ | ||
| + | |||
| + | ===== Установка и настройка ===== | ||
| + | |||
| + | ==== Шаг 1: Создание структуры папок | ||
| <code bash> | <code bash> | ||
| - | # Создаем необходимые директории | + | # Создание необходимых папок |
| sudo mkdir -p / | sudo mkdir -p / | ||
| sudo mkdir -p / | sudo mkdir -p / | ||
| - | + | sudo chown -R $USER: | |
| - | # Устанавливаем права доступа | + | sudo chown -R $USER: |
| - | sudo chmod 755 /opt/scripts | + | |
| - | sudo chmod 755 /opt/backups | + | |
| </ | </ | ||
| - | ==== 2. Создание скрипта ==== | + | ==== Шаг |
| + | |||
| + | Создайте файл `/ | ||
| <code bash> | <code bash> | ||
| Строка 38: | Строка 58: | ||
| </ | </ | ||
| - | Скопируйте в файл следующий | + | Вставьте |
| <code bash> | <code bash> | ||
| Строка 54: | Строка 74: | ||
| RETENTION_DAYS=10 | RETENTION_DAYS=10 | ||
| - | # Настройки базы данных | + | # Настройки базы данных |
| DB_CONTAINER=" | DB_CONTAINER=" | ||
| DB_USER=" | DB_USER=" | ||
| - | DB_PASSWORD=" | + | DB_PASSWORD=" |
| DB_NAME=" | DB_NAME=" | ||
| - | # Настройки Redis | + | # Настройки Redis - ИЗМЕНИТЕ НА СВОИ |
| REDIS_CONTAINER=" | REDIS_CONTAINER=" | ||
| - | REDIS_PASSWORD=" | + | REDIS_PASSWORD=" |
| # Логирование | # Логирование | ||
| Строка 88: | Строка 108: | ||
| exit 1 | exit 1 | ||
| } | } | ||
| + | |||
| # Проверяем что контейнеры запущены | # Проверяем что контейнеры запущены | ||
| log " | log " | ||
| Строка 94: | Строка 115: | ||
| exit 1 | exit 1 | ||
| fi | fi | ||
| + | |||
| + | # Показываем что будет включено в бекап | ||
| + | log " | ||
| + | CHATWOOT_DATA_CONTENTS=$(ls -la / | ||
| + | log " | ||
| + | |||
| # Создаем дамп базы данных (пока контейнеры работают) | # Создаем дамп базы данных (пока контейнеры работают) | ||
| log " | log " | ||
| Строка 115: | Строка 142: | ||
| log " | log " | ||
| REDIS_DUMP_PATH=" | REDIS_DUMP_PATH=" | ||
| - | docker exec " | + | # Создаем дамп внутри контейнера во временный файл |
| + | REDIS_TEMP_PATH="/ | ||
| + | docker exec " | ||
| if [ $? -eq 0 ]; then | if [ $? -eq 0 ]; then | ||
| # Копируем дамп из контейнера | # Копируем дамп из контейнера | ||
| - | docker cp " | + | docker cp " |
| if [ -f " | if [ -f " | ||
| log " | log " | ||
| REDIS_DUMP_SIZE=$(du -h " | REDIS_DUMP_SIZE=$(du -h " | ||
| log " | log " | ||
| + | # Удаляем временный файл из контейнера | ||
| + | docker exec " | ||
| else | else | ||
| log " | log " | ||
| Строка 134: | Строка 165: | ||
| # Очищаем переменную окружения | # Очищаем переменную окружения | ||
| unset PGPASSWORD | unset PGPASSWORD | ||
| + | |||
| # Останавливаем контейнеры | # Останавливаем контейнеры | ||
| log " | log " | ||
| Строка 148: | Строка 180: | ||
| sleep 5 | sleep 5 | ||
| - | # Создаем архив с данными | + | # Создаем архив с данными |
| - | log " | + | log " |
| BACKUP_PATH=" | BACKUP_PATH=" | ||
| - | + | ||
| + | # Создаем архив с автоматическим включением ВСЕГО содержимого / | ||
| tar -czf " | tar -czf " | ||
| --exclude=' | --exclude=' | ||
| --exclude=' | --exclude=' | ||
| + | --exclude=' | ||
| + | --exclude=' | ||
| + | --exclude=' | ||
| -C " | -C " | ||
| $([ -f " | $([ -f " | ||
| - | -C "/ | + | -C "/ |
| - | | + | |
| - | redis_data/ \ | + | |
| - | storage/ \ | + | |
| -C " | -C " | ||
| docker-compose.yml \ | docker-compose.yml \ | ||
| .env | .env | ||
| - | + | ||
| if [ $? -eq 0 ]; then | if [ $? -eq 0 ]; then | ||
| log " | log " | ||
| Строка 176: | Строка 210: | ||
| [ -f " | [ -f " | ||
| log " | log " | ||
| + | | ||
| + | # Показываем что попало в архив | ||
| + | log " | ||
| + | tar -tzf " | ||
| + | log " | ||
| + | done | ||
| + | TOTAL_FILES=$(tar -tzf " | ||
| + | log " | ||
| + | | ||
| else | else | ||
| log " | log " | ||
| Строка 208: | Строка 251: | ||
| log " | log " | ||
| fi | fi | ||
| + | |||
| # Проверяем доступность базы данных | # Проверяем доступность базы данных | ||
| log " | log " | ||
| Строка 253: | Строка 297: | ||
| log " | log " | ||
| log " | log " | ||
| + | |||
| # Получаем информацию о свободном месте на диске | # Получаем информацию о свободном месте на диске | ||
| BACKUP_DISK_USAGE=$(df -h " | BACKUP_DISK_USAGE=$(df -h " | ||
| Строка 260: | Строка 305: | ||
| log " | log " | ||
| fi | fi | ||
| + | |||
| # Получаем процент заполнения диска с бекапами для предупреждений | # Получаем процент заполнения диска с бекапами для предупреждений | ||
| BACKUP_DISK_PERCENT=$(df " | BACKUP_DISK_PERCENT=$(df " | ||
| Строка 269: | Строка 315: | ||
| log "=== Резервное копирование завершено успешно ===" | log "=== Резервное копирование завершено успешно ===" | ||
| + | |||
| # Формируем сообщение для Telegram | # Формируем сообщение для Telegram | ||
| TELEGRAM_MESSAGE=" | TELEGRAM_MESSAGE=" | ||
| Строка 275: | Строка 322: | ||
| 🗄️ Redis dump: $REDIS_DUMP_SIZE | 🗄️ Redis dump: $REDIS_DUMP_SIZE | ||
| 📊 Total backups: $BACKUP_COUNT | 📊 Total backups: $BACKUP_COUNT | ||
| + | 📄 Files in archive: $TOTAL_FILES | ||
| 💿 Disk space: $BACKUP_DISK_USAGE" | 💿 Disk space: $BACKUP_DISK_USAGE" | ||
| + | |||
| # Добавляем предупреждение о месте, если нужно | # Добавляем предупреждение о месте, если нужно | ||
| if [ " | if [ " | ||
| Строка 284: | Строка 333: | ||
| ⚠️ ATTENTION: Disk >80% full" | ⚠️ ATTENTION: Disk >80% full" | ||
| fi | fi | ||
| + | |||
| # Отправляем уведомление в Telegram (опционально) | # Отправляем уведомление в Telegram (опционально) | ||
| - | curl -s -X POST " | + | # Замените на свой BOT_TOKEN и CHAT_ID |
| - | -d chat_id=" | + | curl -s -X POST " |
| + | -d chat_id=" | ||
| -d text=" | -d text=" | ||
| + | |||
| exit 0 | exit 0 | ||
| </ | </ | ||
| - | **Обязательно измените | + | **Обязательно измените**: |
| - | * '' | + | * `YOUR_POSTGRES_PASSWORD` на ваш пароль PostgreSQL |
| - | * '' | + | * `YOUR_REDIS_PASSWORD` на ваш пароль Redis |
| - | * '' | + | * `[YOUR_BOT_TOKEN]` на токен вашего Telegram бота (опционально) |
| - | * '' | + | * `[YOUR_CHAT_ID]` на ваш Chat ID в Telegram (опционально) |
| - | * '' | + | |
| - | ==== 3. Установка прав | + | ==== Шаг |
| <code bash> | <code bash> | ||
| + | # Делаем скрипт исполняемым | ||
| sudo chmod +x / | sudo chmod +x / | ||
| + | |||
| + | # Проверяем права | ||
| + | ls -la / | ||
| </ | </ | ||
| - | <WRAP tip> | + | ==== Шаг 4: Тестовый запуск |
| - | **Важно:** Убедитесь | + | |
| - | </ | + | |
| <code bash> | <code bash> | ||
| - | # Проверяем список баз данных | + | # Запуск тестового |
| - | docker exec chatwoot_postgres psql -U postgres | + | sudo / |
| - | # Если база называется по-другому, измените переменную DB_NAME в скрипте | + | # Проверка |
| + | ls -la / | ||
| + | cat / | ||
| </ | </ | ||
| - | ===== Настройка Telegram уведомлений | + | ===== Автоматизация через Cron ===== |
| - | 1. Создайте бота через **@BotFather** | + | ==== Настройка ежедневного бекапа ==== |
| - | 2. Получите **токен бота** и **chat_id** | + | |
| - | 3. Замените в скрипте соответствующие плейсхолдеры | + | |
| - | + | ||
| - | ===== Автоматизация ===== | + | |
| - | + | ||
| - | ==== Настройка Cron ==== | + | |
| <code bash> | <code bash> | ||
| - | # Редактируем crontab | + | # Открываем crontab |
| sudo crontab -e | sudo crontab -e | ||
| - | # Добавляем задание - ежедневно в 4:00 | + | # Добавляем задачу (бекап каждый день в 2:00 ночи) |
| - | 0 4 * * * / | + | 0 2 * * * / |
| + | |||
| + | # Сохраняем и выходим (Ctrl+X, Y, Enter) | ||
| </ | </ | ||
| - | ===== Использование ===== | + | ==== Альтернативные расписания ==== |
| - | ==== Ручной запуск ==== | + | < |
| + | # Каждый день в 3:00 | ||
| + | 0 3 * * * / | ||
| - | <code bash> | + | # Каждые 12 часов (в 6:00 и 18:00) |
| - | sudo / | + | 0 6,18 * * * / |
| + | |||
| + | # Каждый день в 1:30 ночи | ||
| + | 30 1 * * * / | ||
| + | |||
| + | # Только в выходные в 4:00 | ||
| + | 0 4 * * 6,0 / | ||
| </ | </ | ||
| - | ==== Проверка | + | ==== Проверка |
| <code bash> | <code bash> | ||
| - | # Список бекапов | + | # Проверить статус cron |
| - | ls -la / | + | sudo systemctl status cron |
| - | # Просмотр лога | + | # Посмотреть активные задачи |
| - | tail -f /opt/backups/chatwoot/backup.log | + | sudo crontab -l |
| + | |||
| + | # Посмотреть | ||
| + | sudo tail -f /var/log/chatwoot-backup-cron.log | ||
| </ | </ | ||
| - | ===== Структура бекапов ===== | + | ===== Мониторинг и уведомления |
| - | < | + | ==== Настройка Telegram бота ==== |
| - | /opt/ | + | |
| - | ├── chatwoot_backup_20250830_201456.tar.gz # | + | 1. **Создайте бота**: Отправьте `/start` боту @BotFather в Telegram |
| - | ├── backup.log # Лог операций | + | 2. **Получите токен**: |
| - | └── [старые бекапы...] | + | 3. **Узнайте Chat ID**: Отправьте |
| + | `https:// | ||
| + | |||
| + | ==== Проверка уведомлений ==== | ||
| + | |||
| + | <code bash> | ||
| + | # Тест отправки сообщения (замените токен и chat_id) | ||
| + | curl -s -X POST " | ||
| + | -d chat_id=" | ||
| + | -d text=" | ||
| </ | </ | ||
| - | **Содержимое архива:** | + | ==== Мониторинг места на диске ==== |
| - | * '' | + | |
| - | * '' | + | |
| - | * '' | + | |
| - | * '' | + | |
| - | * '' | + | |
| - | * '' | + | |
| - | * '' | + | |
| - | ===== Восстановление ===== | + | <code bash> |
| + | # Проверка места в папке бекапов | ||
| + | df -h / | ||
| + | |||
| + | # Размер всех бекапов | ||
| + | du -sh / | ||
| + | |||
| + | # Список всех бекапов с размерами | ||
| + | ls -lah / | ||
| + | </ | ||
| + | |||
| + | ===== Восстановление | ||
| ==== Полное восстановление ==== | ==== Полное восстановление ==== | ||
| <code bash> | <code bash> | ||
| - | # Останавливаем сервисы | + | # Остановите Chatwoot |
| cd / | cd / | ||
| docker-compose down | docker-compose down | ||
| - | # Создаем бекап | + | # Найдите нужный |
| - | sudo mv /opt/chatwoot/ | + | ls -la /opt/backups/chatwoot/ |
| - | # Создаем новую директорию данных | + | # Извлеките архив (замените |
| - | sudo mkdir -p / | + | cd /tmp |
| + | tar -xzf /opt/backups/chatwoot/chatwoot_backup_YYYYMMDD_HHMMSS.tar.gz | ||
| - | # Извлекаем архив | + | # Восстановите данные |
| - | sudo tar -xzf /opt/backups/chatwoot/chatwoot_backup_YYYYMMDD_HHMMSS.tar.gz | + | sudo rm -rf / |
| + | sudo cp -r chatwoot_data/ | ||
| - | # Запускаем сервисы | + | # Восстановите |
| + | cp docker-compose.yml / | ||
| + | cp .env / | ||
| + | |||
| + | # Запустите Chatwoot | ||
| + | cd / | ||
| docker-compose up -d | docker-compose up -d | ||
| </ | </ | ||
| - | ==== Восстановление только | + | ==== Восстановление только |
| <code bash> | <code bash> | ||
| - | # Извлекаем SQL дамп | + | # Найдите дамп |
| - | tar -xzf backup.tar.gz | + | tar -tzf / |
| - | # Восстанавливаем в контейнер | + | # Извлеките дамп |
| - | docker exec -i chatwoot_postgres psql -U postgres -d chatwoot < chatwoot_backup_YYYYMMDD_HHMMSS_database.sql | + | tar -xzf / |
| + | |||
| + | # Восстановите в контейнер | ||
| + | export PGPASSWORD=" | ||
| + | cat chatwoot_backup_YYYYMMDD_HHMMSS_database.sql | docker exec -i chatwoot_postgres psql -U postgres -d chatwoot_production | ||
| + | unset PGPASSWORD | ||
| </ | </ | ||
| - | ===== Мониторинг ===== | + | ===== Устранение неполадок |
| - | При успешном бекапе приходит уведомление: | + | ==== Основные проблемы ==== |
| - | < | + | |
| - | ✅ Chatwoot backup completed | + | |
| - | 📁 Backup: chatwoot_backup_20250830_201456 (125M) | + | |
| - | 💾 DB dump: 45M | + | |
| - | 🗄️ Redis dump: 8M | + | |
| - | 📊 Total backups: 7 | + | |
| - | 💿 Disk space: 2.1G свободно из 10G (79% занято) | + | |
| - | </ | + | |
| - | Предупреждения при заполнении диска: | + | === Ошибка " |
| - | < | + | |
| - | ⚠️ ATTENTION: Disk >80% full | + | |
| - | ⚠️ WARNING: Disk >90% full! | + | |
| - | </ | + | |
| - | ===== Устранение проблем | + | **Причина**: Неправильные имена контейнеров |
| - | === Контейнеры не запущены === | + | **Решение**: Проверьте имена контейнеров: |
| <code bash> | <code bash> | ||
| - | cd / | + | docker ps |
| - | docker-compose | + | # Обновите переменные DB_CONTAINER и REDIS_CONTAINER в скрипте |
| - | docker-compose up -d | + | |
| </ | </ | ||
| - | === Ошибка дампа БД === | + | === Ошибка доступа к базе данных |
| + | |||
| + | **Причина**: | ||
| + | |||
| + | **Решение**: | ||
| <code bash> | <code bash> | ||
| - | # Проверяем доступность БД | + | cat / |
| - | docker exec chatwoot_postgres pg_isready -U postgres | + | # Обновите переменные в скрипте согласно .env |
| + | </ | ||
| - | # Проверяем правильную базу данных | + | === Нехватка места на диске === |
| - | docker exec chatwoot_postgres psql -U postgres -d chatwoot_production -c " | + | |
| - | # Проверяем логи | + | **Причина**: |
| - | docker logs chatwoot_postgres | + | |
| + | **Решение**: | ||
| + | <code bash> | ||
| + | # Удалите старые бекапы вручную | ||
| + | find / | ||
| + | |||
| + | # Уменьшите RETENTION_DAYS в скрипте | ||
| </ | </ | ||
| - | === Ошибка дампа Redis === | + | ==== Проверка логов ==== |
| <code bash> | <code bash> | ||
| - | # Проверяем Redis | + | # Основной лог скрипта |
| - | docker exec chatwoot_redis redis-cli -a [пароль] ping | + | tail -f / |
| - | # Проверяем логи | + | # Лог cron |
| + | tail -f / | ||
| + | |||
| + | # Логи | ||
| + | docker logs chatwoot_postgres | ||
| docker logs chatwoot_redis | docker logs chatwoot_redis | ||
| </ | </ | ||
| - | === Нет места | + | ===== Дополнительные |
| + | |||
| + | ==== Изменение времени хранения | ||
| + | |||
| + | В скрипте измените: | ||
| <code bash> | <code bash> | ||
| - | # Проверяем использование | + | RETENTION_DAYS=10 |
| - | df -h /opt/backups | + | </code> |
| - | # Удаляем старые бекапы | + | ==== Изменение папки |
| - | find / | + | |
| + | В скрипте измените: | ||
| + | <code bash> | ||
| + | BACKUP_DIR=" | ||
| </ | </ | ||
| + | |||
| + | **Рекомендация**: | ||
| ===== Безопасность ===== | ===== Безопасность ===== | ||
| + | |||
| + | ==== Защита скрипта ==== | ||
| <code bash> | <code bash> | ||
| - | # Устанавливаем | + | # Ограничить доступ только root |
| - | sudo chmod 700 / | + | |
| sudo chown root:root / | sudo chown root:root / | ||
| + | sudo chmod 700 / | ||
| - | # Защищаем директорию бекапов | + | # Проверить права |
| - | sudo chmod 755 /opt/backups | + | ls -la /opt/scripts/chatwoot-backup.sh |
| - | sudo chown root:root /opt/backups | + | |
| </ | </ | ||
| + | |||
| + | ==== Шифрование бекапов ==== | ||
| + | |||
| + | Для дополнительной безопасности можно добавить шифрование: | ||
| + | |||
| + | <code bash> | ||
| + | # Добавьте в скрипт после создания архива: | ||
| + | gpg --symmetric --cipher-algo AES256 " | ||
| + | rm " | ||
| + | </ | ||
| + | |||
| + | ===== Заключение ===== | ||
| + | |||
| + | Данный скрипт обеспечивает: | ||
| + | |||
| + | - **Полное резервное копирование** всех данных Chatwoot | ||
| + | - **Автоматическое включение** новых файлов и папок в `/ | ||
| + | - **Безопасное выполнение** с остановкой и запуском контейнеров | ||
| + | - **Очистку старых бекапов** для экономии места | ||
| + | - **Детальное логирование** всех операций | ||
| + | - **Уведомления в Telegram** о статусе бекапа | ||
| + | - **Мониторинг места на диске** с предупреждениями | ||
| + | |||
| + | **Результат**: | ||
| ---- | ---- | ||
| - | //Документация обновлена: {{ CURRENTUSER }} {{ date:j.m.Y H:i }}/ | + | //Инструкция протестирована на Ubuntu Server с Docker Compose. Регулярно проверяйте работоспособность бекапов |