Files
remnawave-minishop/docs/features/backups.md
T
2026-05-27 13:53:30 +03:00

9.4 KiB
Raw Blame History

Бэкапы и восстановление

Minishop умеет автоматически собирать ZIP-бэкапы в worker-контейнере, хранить последние архивы на сервере, отправлять их в Telegram и восстанавливать БД/compose-папку из админки.

Что попадает в архив

Архив создается в BACKUP_DIR, по умолчанию data/backups внутри volume shop-data.

Типовой файл называется так:

remnawave-minishop-backup-20260527-120000+0300.zip

Внутри:

  • 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:

BACKUP_ENABLED=True
BACKUP_CHAT_ID=-1001234567890
BACKUP_INTERVAL_SECONDS=3600
BACKUP_LOCAL_RETENTION=100
BACKUP_COMPOSE_ENABLED=True
COMPOSE_BACKUP_SOURCE=.
COMPOSE_RESTORE_MODE=rw

BACKUP_INTERVAL_SECONDS=3600 запускает бэкапы ровно на границе часа: 12:00, 13:00 и т.д. Значение по умолчанию для локального хранения - 100 последних ZIP-архивов.

BACKUP_CHAT_ID задает чат Telegram для отправки архивов. Если он пустой, используется LOG_CHAT_ID. Для topic/thread можно указать BACKUP_THREAD_ID; если он пустой, используется LOG_THREAD_ID.

Каждый архив подписывается HMAC-подписью в manifest.json и содержит SHA-256 каждого файла. По умолчанию restore принимает только архивы с валидной подписью этого инстанса. Если нужен отдельный стабильный ключ подписи, задайте BACKUP_ARCHIVE_SIGNATURE_SECRET; если ключ пустой, используется BOT_TOKEN.

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-путь.

Если нужно запретить восстановление compose-файлов из контейнера, задайте:

COMPOSE_RESTORE_MODE=ro

В этом режиме восстановление БД останется доступным, а восстановление compose-папки вернет понятную ошибку о недоступной записи.

Восстановление из админки

Откройте Система -> Бэкапы. В разделе можно:

  • выбрать архив, уже лежащий в data/backups;
  • загрузить ZIP-архив вручную;
  • отметить, что восстанавливать: БД, compose-папка или оба варианта;
  • запустить восстановление после подтверждения.

БД восстанавливается через pg_restore --clean --if-exists --no-owner --no-privileges. На время восстановления лучше не запускать платежи, рассылки, массовую синхронизацию и ручные изменения подписок.

Compose-файлы восстанавливаются поверх текущей папки. Перед заменой backend создает pre-restore snapshot текущего compose-каталога рядом с остальными архивами:

remnawave-minishop-compose-pre-restore-YYYYMMDD-HHMMSS+ZZZZ.zip

После восстановления compose-папки перезапустите нужные сервисы, чтобы изменения docker-compose.yml, .env, Caddyfile/Nginx-конфигов и других файлов реально применились:

docker compose up -d --build backend worker
docker compose ps

Если менялись proxy-конфиги, перезапустите соответствующий сервис (caddy, nginx, newt).

Проверка архива перед восстановлением

Backend валидирует архив до восстановления:

  • файл должен быть валидным ZIP;
  • manifest.json должен принадлежать remnawave-minishop и иметь поддерживаемую версию формата;
  • HMAC-подпись manifest должна быть валидной, если BACKUP_ARCHIVE_SIGNATURE_REQUIRED=True;
  • 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_ARCHIVE_SIGNATURE_REQUIRED=False, восстановите архив и верните проверку обратно.

Ручное восстановление БД

Если админка недоступна, можно восстановить дамп вручную:

unzip remnawave-minishop-backup-YYYYMMDD-HHMMSS+ZZZZ.zip -d restore
docker compose cp restore/database/remnawave_minishop.dump postgres:/tmp/remnawave_minishop.dump
docker compose stop backend worker
docker compose exec postgres sh -c 'pg_restore -U "$POSTGRES_USER" -d "$POSTGRES_DB" --clean --if-exists --no-owner --no-privileges /tmp/remnawave_minishop.dump'
docker compose up -d backend worker

После ручного восстановления проверьте миграции и healthcheck:

docker compose run --rm migrate
docker compose ps
docker compose logs -f backend worker

Переменные

Полный справочник лежит в переменных окружения. Основные ключи:

Переменная Назначение
BACKUP_ENABLED Включает периодические бэкапы.
BACKUP_CHAT_ID / BACKUP_THREAD_ID Куда отправлять архивы в Telegram.
BACKUP_INTERVAL_SECONDS Периодичность, по умолчанию 3600.
BACKUP_LOCAL_RETENTION Сколько последних архивов хранить на сервере.
BACKUP_DIR Каталог ZIP-архивов.
BACKUP_ARCHIVE_SIGNATURE_REQUIRED Требовать валидную HMAC-подпись manifest при upload/restore.
BACKUP_ARCHIVE_SIGNATURE_SECRET Отдельный секрет подписи архивов; если пустой, используется BOT_TOKEN.
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 внутри контейнеров.