Бэкапы и восстановление
Minishop умеет автоматически собирать ZIP-бэкапы в worker-контейнере, хранить последние архивы на сервере, отправлять их в Telegram и восстанавливать БД/compose-папку из админки.
Что попадает в архив
Заголовок раздела «Что попадает в архив»Архив создается в BACKUP_DIR, по умолчанию data/backups внутри volume shop-data.
Типовой файл называется так:
Внутри:
database/<POSTGRES_DB>.dump-pg_dumpв custom format дляpg_restore;compose/- snapshot папки сdocker-compose.yml,.envи соседними конфигами;manifest.json- дата создания, сведения о БД, compose snapshot и предупреждения.
Если compose-папка не смонтирована или недоступна, worker не роняет весь бэкап: архив будет создан с дампом БД и предупреждением в manifest.json.
Настройка
Заголовок раздела «Настройка»Основные параметры доступны в админке: Система -> Настройки -> Бэкапы.
Минимальный .env, если LOG_CHAT_ID уже задан и подходит для бэкапов:
Если бэкапы нужно отправлять в отдельный чат или topic/thread, добавьте только нужные переменные:
Остальные backup-переменные обычно не нужны в .env: BACKUP_INTERVAL_SECONDS=3600 запускает бэкапы ровно на границе часа 12:00, 13:00 и т.д.; BACKUP_LOCAL_RETENTION=100 хранит 100 последних ZIP-архивов; BACKUP_COMPOSE_ENABLED=True, COMPOSE_BACKUP_SOURCE=. и COMPOSE_RESTORE_MODE=rw уже совпадают со стандартным compose-сценарием.
BACKUP_CHAT_ID задает чат Telegram для отправки архивов. Если он пустой, используется LOG_CHAT_ID. Для topic/thread можно указать BACKUP_THREAD_ID; если он пустой, используется LOG_THREAD_ID.
Каждый архив содержит manifest.json с SHA-256 и размером каждого файла. Это позволяет проверить, что архив не поврежден и его содержимое не отличается от manifest.
Архив не привязан к текущему инстансу, BOT_TOKEN или серверу. Его можно загрузить и восстановить на другом сервере, если формат архива поддерживается и проверки целостности проходят.
Mount compose-папки
Заголовок раздела «Mount compose-папки»В стандартных compose-файлах есть два mount:
worker:${COMPOSE_BACKUP_SOURCE:-.}:/app/compose-source:ro- только читает папку для создания snapshot;backend:${COMPOSE_BACKUP_SOURCE:-.}:/app/compose-source:${COMPOSE_RESTORE_MODE:-rw}- читает список архивов и может восстановить compose-папку из админки.
COMPOSE_BACKUP_SOURCE=. означает папку рядом с текущим docker-compose.yml. Если compose лежит в другом месте, укажите абсолютный host-путь.
Ручное создание бэкапа из админки выполняется в backend-контейнере, а автоматический backup по расписанию - в worker-контейнере. Оба контейнера должны видеть /app/compose-source. Если ручной backup содержит compose-папку, а автоматический нет, пересоздайте worker после обновления compose:
Если нужно запретить восстановление compose-файлов из контейнера, задайте:
В этом режиме восстановление БД останется доступным, а восстановление compose-папки вернет понятную ошибку о недоступной записи.
Восстановление из админки
Заголовок раздела «Восстановление из админки»Откройте Система -> Бэкапы. В разделе можно:
- создать новый backup вручную, не дожидаясь следующего запуска по расписанию;
- выбрать архив, уже лежащий в
data/backups; - загрузить ZIP-архив вручную;
- отметить, что восстанавливать:
БД,compose-папкаили оба варианта; - запустить восстановление после подтверждения.
Ручное создание использует тот же механизм, что и расписание: делает pg_dump, добавляет compose snapshot, сохраняет ZIP в BACKUP_DIR, отправляет архив в Telegram и применяет локальный retention. На время ручного запуска используется общий Redis lock, поэтому он не пересечется с плановым backup или restore.
БД восстанавливается через pg_restore --clean --if-exists --no-owner --no-privileges. На время восстановления лучше не запускать платежи, рассылки, массовую синхронизацию и ручные изменения подписок.
Compose-файлы восстанавливаются поверх текущей папки. Перед заменой backend создает pre-restore snapshot текущего compose-каталога рядом с остальными архивами:
После восстановления compose-папки перезапустите нужные сервисы, чтобы изменения docker-compose.yml, .env, Caddyfile/Angie/Nginx-конфигов и других файлов реально применились:
Если менялись proxy-конфиги, перезапустите соответствующий сервис (caddy, angie, nginx, newt).
Проверка архива перед восстановлением
Заголовок раздела «Проверка архива перед восстановлением»Backend валидирует архив до восстановления:
- файл должен быть валидным ZIP;
manifest.jsonдолжен принадлежатьremnawave-minishopи иметь поддерживаемую версию формата;- SHA-256 и размер каждого файла должны совпадать с manifest;
- выбранный server-side файл должен лежать внутри
BACKUP_DIR, путь вида../backup.zipотклоняется; - пути внутри ZIP не могут быть абсолютными, содержать
..,\, пустые сегменты или дубли; - архивы с подозрительно большим числом файлов, размером или zip-bomb compression ratio отклоняются;
- для восстановления БД нужен
database/*.dumpилиdatabase/*.backup; - для восстановления compose нужны файлы внутри
compose/; - compose restore стартует только если целевая папка существует и доступна на запись;
- backup/restore защищены одним Redis lock, чтобы две операции не выполнялись одновременно.
Это защищает от случайной загрузки мусорного файла, zip-slip-архивов и поврежденных ZIP. Проверка специально не привязана к секретам инстанса, чтобы архивы можно было использовать для переноса между серверами. Это не проверка доверенного источника: не восстанавливайте архивы, происхождение которых вы не контролируете.
Перенос на другой сервер
Заголовок раздела «Перенос на другой сервер»Для переноса БД между инстансами:
- Создайте backup на старом сервере или возьмите ZIP из Telegram.
- На новом сервере загрузите архив в Система -> Бэкапы.
- Выберите
БД;compose-папкувключайте только если хотите перенести.env,docker-compose.ymlи proxy-конфиги. - Запустите restore и после восстановления выполните миграции/healthcheck.
Если переносите compose-папку, проверьте домены, токены, WEBHOOK_BASE_URL, SUBSCRIPTION_MINI_APP_URL, bind-порты и volume/mount пути: на новом сервере они могут отличаться.
Ручное восстановление БД
Заголовок раздела «Ручное восстановление БД»Если админка недоступна, можно восстановить дамп вручную:
После ручного восстановления проверьте миграции и healthcheck:
Переменные
Заголовок раздела «Переменные»Полный справочник лежит в переменных окружения. Основные ключи:
| Переменная | Назначение |
|---|---|
BACKUP_ENABLED |
Включает периодические бэкапы. |
BACKUP_CHAT_ID / BACKUP_THREAD_ID |
Куда отправлять архивы в Telegram. |
BACKUP_INTERVAL_SECONDS |
Периодичность, по умолчанию 3600. |
BACKUP_LOCAL_RETENTION |
Сколько последних архивов хранить на сервере. |
BACKUP_DIR |
Каталог ZIP-архивов. |
BACKUP_COMPOSE_ENABLED |
Добавлять compose snapshot. |
COMPOSE_BACKUP_SOURCE |
Host-путь compose-папки для mount в контейнеры. |
COMPOSE_RESTORE_MODE |
rw для восстановления compose из админки, ro для запрета записи. |
BACKUP_PG_DUMP_PATH / BACKUP_PG_RESTORE_PATH |
Пути к pg_dump и pg_restore внутри контейнеров. |