MAATRIX / Блог / Nextcloud: бэкап и восстановление данных

Nextcloud: бэкап и восстановление данных

Nextcloud: бэкап и восстановление данных

MAATRIX

Скопировать папку data — ещё не бэкап Nextcloud. Без дампа базы это каталог файлов, в котором нет ни одной расшаренной ссылки, ни календарей, ни контактов, а без config.php половина из них не расшифруется. Разберём, что входит в бэкап, как снять его без рассинхрона файлов и базы и как пройти восстановление.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Что копировать: четыре части, а не одна папка

Инстанс — четыре независимые сущности, потеря любой ломает остальные.

ЧтоПуть по умолчаниюДоля объёмаЧто теряете без него
Каталог данных/var/www/nextcloud/data или /var/nextcloud/data95–99%Файлы, ключи шифрования, превью
База данныхMariaDB/PostgreSQL, схема nextcloud0,2–3 ГБШары, календари, контакты, теги, права
config/config.php/var/www/nextcloud/config/config.php4–8 КБsecret, passwordsalt, instanceid — а с ними расшифровку
Приложения/var/www/nextcloud/custom_apps и apps0,3–2 ГБСторонние приложения нужных версий

Код ядра можно не хранить — тарбол любой версии лежит на download.nextcloud.com, а вот custom_apps/ надо: в магазине остаются только свежие сборки. И загляните в config.php до подсчёта объёма: блок 'objectstore' => означает, что файлы лежат в S3 и в бэкап сервера не попадут вовсе, версионирование бакета включается отдельно. То же с files_external — Nextcloud хранит только метаданные.

sudo -u www-data php /var/www/nextcloud/occ config:list system --private > /root/nc-config.json

Она выгружает конфиг вместе с паролем БД и солью: держите файл в менеджере секретов, а не рядом с бэкапами.

Согласованность: maintenance mode и два прохода rsync

Главная ошибка — снимать базу и файлы в разное время на живой системе. Файл удалён между дампом и копированием data — при восстановлении в базе останется запись о несуществующем файле, и клиент покажет ошибку синхронизации; обратный порядок даёт невидимые файлы-сироты.

Окно рассинхрона закрывает режим обслуживания: occ maintenance:mode --on. Веб отдаёт заглушку, WebDAV — 503 с телом Sabre\DAV\Exception\ServiceUnavailable: System is in maintenance mode, cron не запускается. Беда в том, что 400 ГБ копируются часами, а простоя каждую ночь никто не потерпит. Рабочая схема — два прохода rsync:

trap 'sudo -u www-data php /var/www/nextcloud/occ maintenance:mode --off' EXIT
# проход 1: долгий, на живой системе
rsync -Aax --delete --numeric-ids /var/nextcloud/data/ /backup/data/
sudo -u www-data php /var/www/nextcloud/occ maintenance:mode --on
# проход 2: догоняет изменения — обычно 30–90 секунд
rsync -Aax --delete --numeric-ids /var/nextcloud/data/ /backup/data/
mariadb-dump --single-transaction --quick nextcloud | zstd -3 > /backup/db.sql.zst

Строка с trap важнее, чем кажется: без неё упавший скрипт оставит облако в обслуживании до утра. Флаги тоже по делу: -A тянет ACL (иначе посыпятся права на групповых папках), -x не пускает rsync на примонтированный внутрь диск, --numeric-ids сохраняет владельца по UID.

Про снапшоты диска честно: снимок живой машины crash-consistent — InnoDB поднимется, но совпадение базы с файлами не гарантировано. Как страховка от «удалил не ту виртуалку» — отлично, как единственный бэкап — нет.

Развернуть за пару минут

Готовый образ на VPS MAATRIX: NVMe, AMD EPYC, root-доступ. Локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Развернуть Nextcloud

Дамп базы: MariaDB и PostgreSQL

MariaDB. В ветке 11.4 LTS бинарник называется mariadb-dump, mysqldump оставлен симлинком.

mariadb-dump --single-transaction --quick --routines --triggers \
  --default-character-set=utf8mb4 --databases nextcloud \
  | zstd -3 -T0 > /backup/nc-db-$(date +%F).sql.zst

--single-transaction даёт консистентный снимок InnoDB без блокировки таблиц, --quick не тянет oc_filecache в память целиком — на 1,3 млн файлов эта таблица весит 600–800 МБ. Ориентир: сырой дамп ~950 МБ, после zstd -3 — 115 МБ, снятие 40–60 секунд.

Две ошибки вылезают уже при восстановлении:

ERROR 1273 (HY000) at line 25: Unknown collation: 'utf8mb4_0900_ai_ci'
mysqldump: Error: 'Access denied; you need (at least one of) the PROCESS
privilege(s) for this operation' when trying to dump tablespaces

Первая — дамп снят в MySQL 8, а заливается в MariaDB: такой коллации у неё нет, лечится sed -i 's/utf8mb4_0900_ai_ci/utf8mb4_general_ci/g' dump.sql. Вторая вылезает у непривилегированного пользователя в MySQL 8 и снимается флагом --no-tablespaces.

PostgreSQL. Формат custom жмётся сам и восстанавливается параллельно.

sudo -u postgres pg_dump -Fc -Z3 nextcloud > /backup/nc-db-$(date +%F).dump
sudo -u postgres pg_restore -d nextcloud --clean --if-exists -j4 /backup/nc-db.dump

Грабля на чистом сервере — pg_restore: error: could not execute query: ERROR: role "nextcloud" does not exist: без -C дамп не создаёт ни роль, ни базу. Заведите роль руками, пароль — из dbpassword в config.php.

Сверьте SELECT COUNT(*) FROM oc_filecache; с find /var/nextcloud/data -type f | wc -l: расхождение в тысячи строк значит, что файлы и база сняты не в одном окне.

Файлы: restic вместо зеркала и что можно не копировать

Зеркало через rsync работает ровно до дня, когда шифровальщик прошёл по data, а ночной запуск с --delete повторил это на бэкапе. Нужны версии — restic (0.18 и новее) или BorgBackup: дедупликация по блокам, шифрование, история снимков.

export RESTIC_PASSWORD_FILE=/root/.restic-pass
restic -r sftp:backup@backup.example.com:/srv/restic init
restic -r sftp:backup@backup.example.com:/srv/restic backup \
  --exclude-file=/root/nc-exclude.txt \
  /var/nextcloud/data /var/www/nextcloud/config /var/www/nextcloud/custom_apps
restic -r sftp:... forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune

Содержимое /root/nc-exclude.txt:

/var/nextcloud/data/appdata_*/preview
/var/nextcloud/data/*/cache
/var/nextcloud/data/*/uploads
/var/nextcloud/data/nextcloud.log
/var/nextcloud/data/updater-*/backups

Превью — самый жирный мусор: на 300 ГБ фотоархива preview занимает 40–60 ГБ и пересобирается при просмотре. А вот **исключать appdata_* целиком нельзя**: рядом с превью там тема оформления, данные приложения «Текст» и индексы поиска.

Замеры на инстансе 420 ГБ и 1,3 млн файлов: первый прогон по гигабитному каналу — около четырёх часов, суточные инкременты — 3–7 минут и 1–4 ГБ прироста. Раз в месяц добавляйте restic check --read-data-subset=5%: без него о битом репозитории вы узнаете в худший день.

Риск, о котором молчат руководства: пароль репозитория восстановить нельзя — потеряли /root/.restic-pass, потеряли весь архив. Копия пароля должна лежать вне сервера, который вы бэкапите. Запуск — systemd-таймером с OnCalendar=*-*-* 03:30:00 и Persistent=true, а не строкой в crontab: результат виден в journalctl.

Восстановление: полный прогон по шагам

Порядок жёсткий: отступления дают те самые ошибки, которые потом гуглят.

1. Поднимите окружение той же версии. PHP 8.3 или 8.4, база не старше донора, тот же набор расширений. На версии ядра ниже записанной в базе Nextcloud не стартует: Downgrading is not supported and is likely to cause unpredictable issues. Версию донора выпишите заранее — её печатает occ status (- version: 32.0.4.1).

2. Верните файлы и права.

rsync -Aax --numeric-ids /backup/data/ /var/nextcloud/data/
chown -R www-data:www-data /var/nextcloud/data /var/www/nextcloud
find /var/nextcloud/data -type d -exec chmod 750 {} \;
ls -la /var/nextcloud/data/.ncdata

Последняя строка не для галочки: если архив снимался с маской, отбросившей точечные файлы, вас встретит Your data directory is invalid. Ensure there is a file called ".ncdata" in the root of the data directory. Файл пустой и создаётся touch. На инстансах старше 28-й ветки он назывался .ocdata.

3. Залейте базу, затем положите свой config.php, а не сгенерированный новой установкой.

4. Снимите режим обслуживания и прогоните ремонт.

sudo -u www-data php occ maintenance:mode --off
sudo -u www-data php occ maintenance:repair --include-expensive
sudo -u www-data php occ db:add-missing-indices
sudo -u www-data php occ db:add-missing-columns
sudo -u www-data php occ files:scan --all

files:scan сверяет oc_filecache с диском и печатает по каждому пользователю строку вида Starting scan for user 3 out of 12 (ivanov) и таблицу Folders / Files / Elapsed time — на NVMe это около 100 тысяч файлов за 3–6 минут. Дамп базы он не заменяет: список файлов пересоберёт, но шары, календари и контакты живут только в БД.

5. Обязательный штрих при откате на точку в прошломocc maintenance:data-fingerprint. Она меняет отпечаток инстанса, и клиенты вместо «сервер удалил файлы — удалю и я» показывают диалог конфликта. Пропустите — и они повторят откат, стерев локальные файлы, созданные после точки восстановления.

Что ломается только при восстановлении

Серверное шифрование. При включённом encryption ключи лежат в data/files_encryption и data/<user>/files_encryption, а расшифровка завязана на secret и passwordsalt. Потеряли любую часть — файлы не прочитает никто, включая вас: Cannot decrypt this file, probably this is a shared file. Честно: на локальном диске эта функция добавляет 20–30% ко времени операций и риск потерять всё, не защищая от того, кто получил root.

instanceid. Каталог appdata_<instanceid> завязан на значение из конфига. Взяли config.php от новой установки — Nextcloud создаст пустой appdata_ с другим суффиксом, и разом отвалятся тема, превью и часть приложений.

Корзина и версии — не бэкап. По умолчанию trashbin_retention_obligation и versions_retention_obligation стоят в auto: при нехватке места Nextcloud чистит их сам, и пользователь, пришедший «восстановить из корзины через месяц», может не найти ничего.

Штатное приложение Backup. Точки восстановления кнопкой в интерфейсе — вариант для инстанса на 20–50 ГБ. На сотнях гигабайт оно нагружает сервер и всё равно требует места вне машины: restic по таймеру предсказуемее.

Проверка равна восстановлению. Единственное доказательство — поднятая из бэкапа копия. Держите в её config.php 'maintenance' => true и не выпускайте наружу: два Nextcloud с одним instanceid в сети дают встречную синхронизацию.

Какой сервер под Nextcloud с бэкапами взять в MAATRIX

Считать надо не по объёму данных, а по объёму плюс место под копию и пик нагрузки при снятии.

Честный минимум: 2 vCPU, 4 ГБ RAM, 80 ГБ NVMe. Хватает на 10–15 пользователей, MariaDB и ночной restic. Ограничение прямое: репозиторий держите вне этой машины, иначе бэкапа у вас нет. И zstd -3 во время дампа на двух ядрах просаживает отзывчивость — ставьте задание на ночь.

Комфортный вариант: 4 vCPU, 8 ГБ RAM, 200–400 ГБ NVMe. Redis для блокировок файлов, генератор превью, до 50 пользователей и запас, чтобы files:scan --all не растягивался на полчаса. Четыре ядра позволяют бэкапу и облаку не мешать друг другу. Про память подробнее — в статье сколько RAM нужно для Nextcloud.

Схема, которую советуем чаще всего: боевой Nextcloud в одной локации и недорогой сервер с большим диском в другой — под репозиторий restic по SSH. Диск бэкап-узла берите от 1,5 объёма данных: дедупликация экономит, но полгода истории занимают место.

Локация — Лондон. Nextcloud почти всегда хранит персональные данные, а британская площадка даёт европейский правовой контур и 45–60 мс до Москвы: для WebDAV и десктопного клиента это неотличимо от локальной сети. Франция — так же. Россию берите, когда обязаны выполнять 152-ФЗ: боевой узел в РФ, копия — в Европе.

Nextcloud из каталога apps.maatrix.io ставится автоматически при заказе — вставлять команды не нужно. Автоустановка работает на Ubuntu и Debian, адрес, логин администратора и пароль появляются в личном кабинете, в разделе «Доступ». Дальше вы заводите SSH-ключ до бэкап-узла и вешаете таймер — до того, как в облако попадут первые файлы. Оплата — картами российских банков, по СБП, криптой или токеном MAAT. Смежное: установка Nextcloud на VPS и почему Nextcloud медленно работает.

Развернуть за пару минут

Готовый образ на VPS MAATRIX: NVMe, AMD EPYC, root-доступ. Локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Развернуть Nextcloud

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Частые вопросы

Достаточно ли снапшотов диска у провайдера?

Как страховка от собственной ошибки — да, как единственный бэкап — нет: снимок crash-consistent и не даёт достать один файл за прошлый вторник. Держите его в дополнение к restic-репозиторию на другой площадке.

Можно ли восстановить одного пользователя, не трогая остальных?

Файлы — да: restic restore <snapshot> --target /tmp/r --include /var/nextcloud/data/ivanov, затем occ files:scan --path=ivanov/files. Шары и календари лежат в общей базе, вынуть их по одному пользователю штатно нельзя.

Как часто проверять бэкапы?

restic check после каждого прогона, restic check --read-data-subset=5% раз в месяц и полное тестовое восстановление раз в квартал. Бэкап, который ни разу не разворачивали, считайте гипотезой, а не копией.

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.