Перейти к содержимому
Поиск
Разработка

restic: резервные копии, снимки и восстановление — 9 практических опытов

Создаём пять снимков, сравниваем изменения и восстанавливаем файлы с SHA256. Девять опытов в мастерской, команды Windows/Linux, Docker и практический план бэкапа VPS.

Александр Некрасов
restic: резервные копии, история снимков и восстановление файлов

Резервная копия нужна не в тот момент, когда всё работает. Она нужна после неудачного обновления, случайного удаления каталога, поломки диска или обнаружения испорченных данных. Поэтому хороший процесс заканчивается не сообщением «backup completed», а пониманием, какой снимок выбрать, где взять пароль и как вернуть работоспособный сервис.

В этом материале пройдём полный учебный цикл с restic: создадим зашифрованный репозиторий, сохраним пять состояний проекта, увидим инкрементальный бэкап, сравним изменения и восстановим файлы с проверкой SHA256. В мини-мастерской девять сценариев на настоящих сохранённых результатах. В архиве — весь код, команды Windows и Linux, Docker и шаблоны для практического применения на VPS. Проверенная версия — restic 0.19.1.

Что такое restic и что он даёт разработчику

Restic — консольная программа резервного копирования. Она читает выбранные файлы, сохраняет их в репозиторий и создаёт снимок состояния. Позже вы выбираете нужный снимок и восстанавливаете его целиком либо извлекаете отдельный документ. Репозиторий может находиться на локальном диске, другом сервере или поддерживаемом объектном хранилище.

Для разработчика это полезный строительный блок: команда запускается вручную, из расписания или в обслуживающем процессе. Ей можно передать список источников, исключения, название хоста и теги, а результат получить в текстовом или JSON-виде. При этом restic не становится администратором вашего приложения: он не знает, какие данные можно потерять и какой порядок запуска нужен после аварии.

В статье мы рассматриваем файлы как часть понятного плана восстановления. Для небольшого сайта это могут быть загрузки пользователей, завершённый экспорт базы и конфигурация развёртывания. Для рабочего компьютера — отдельная папка проекта. Для внутреннего сервиса — документы и данные, которые невозможно воспроизвести из Git. Такой перечень сначала составляют, а затем превращают в команду.

Официальная документация: назначение restic.

Где применять: сайт, CRM, документы и сервер

Представьте сайт с пользовательскими вложениями. Исходный код хранится в Git, однако загруженные договоры и фотографии туда не попадают. Если сохранить только репозиторий разработки, сайт после аварии будет установлен, но данные посетителей исчезнут. Restic позволяет включить каталог загрузок в регулярный процесс и сохранить несколько прошлых состояний.

В CRM похожая задача возникает с документами, экспортами и локальными интеграциями. Сотрудник может удалить файл, а ошибка синхронизации — разнести удаление по рабочим копиям. История снимков помогает вернуться к моменту до события. Для этого срок хранения должен покрывать не только время реакции администратора, но и задержку обнаружения проблемы.

Ещё один сценарий — проверяемый переезд на новый сервер. Вы восстанавливаете данные в отдельное место, поднимаете приложение, проверяете его и только затем планируете переключение. Это не отменяет отдельной стратегии базы данных и сетевых зависимостей, но даёт повторяемый способ доставки файлов. Маленький учебный проект ниже позволяет понять эту механику без подключения настоящего рабочего каталога.

До первой команды: RPO, RTO и состав копии

Полезно ответить на два вопроса обычными словами. Сколько последних изменений допустимо потерять? Сколько времени сервис может оставаться недоступным? Первое называют RPO, второе — RTO. Если заявки создаются каждую минуту, один ночной файловый бэкап может не соответствовать требованиям бизнеса, даже если он технически исправен.

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

Затем запишите короткую инструкцию восстановления и попробуйте выполнить её на чистом окружении. Часто именно здесь выясняется, что пароль находился только на погибшем сервере, нужный пакет больше не устанавливается или база зависит от конкретной версии расширения. Регулярный бэкап полезен тогда, когда такая процедура уже проверена, а не предполагается.

Мини-мастерская: девять опытов на реальных результатах

Начните с создания репозитория и первого снимка, затем откройте повторный запуск без изменений. В этом опыте restic действительно сообщил о пяти неизменённых файлах и нулевом объёме добавленных данных. В истории можно переключаться между пятью состояниями, смотреть имена файлов и их SHA256, а в разделе различий — увидеть изменение, добавление и удаление.

Восстановление представлено тремя выполненными проверками: первое полное дерево, последнее полное дерево и отдельный документ из третьего снимка. Кнопка раскрывает сохранённый результат настоящей команды. Она не запускает резервирование на сервере сайта. Браузер ничего не отправляет из ваших папок: публичная часть только исследует обезличенный журнал учебного опыта.

Последний раздел показывает три варианта политики хранения. Выбирайте один, два или три последних снимка и смотрите, какие записи попали бы под удаление. Все результаты получены с dry-run; после проверок в репозитории осталось пять снимков. Для повторения есть команды PowerShell и Bash, скачивание рецепта и полный проект. Даты снимков заданы искусственно, чтобы история читалась последовательно.

На телефоне мастерскую удобно открыть отдельно. Встроенная область имеет собственную прокрутку.

Как устроены снимки, блоки и инкрементальность

Пользователь видит снимок как полное дерево файлов на определённый момент. Внутри репозитория данные организованы иначе: одинаковое содержимое может использоваться повторно, поэтому каждый новый запуск не обязан записывать весь проект заново. Сохраняются новые данные и описание нового состояния, а прежние блоки могут оставаться общими для нескольких снимков.

Отсюда следуют две практические особенности. Во-первых, для восстановления не требуется вручную распаковывать последовательность полного и ежедневных архивов. Вы выбираете нужный снимок, а restic собирает данные. Во-вторых, нельзя самостоятельно удалять непонятные файлы внутри репозитория: один такой файл может быть необходим нескольким точкам восстановления.

Нулевая добавка в нашем втором опыте относится к конкретному счётчику data_added. Сам новый снимок и служебная информация всё равно существуют, а размер каталога на диске не обязан остаться прежним байт в байт. Производительность и экономию оценивают на реальном наборе данных: большие постоянно переписываемые файлы, сжимаемые документы и уже сжатые медиа ведут себя по-разному.

Установка: фиксируем версию и проверяем архив

В исходниках установлен явный номер 0.19.1. Небольшой Python-installer скачивает официальный архив для Windows x64 либо Linux x64, сверяет SHA256 с закреплённым значением и помещает бинарник в tools/bin. Он не меняет системный PATH и не устанавливает программу глобально. Самому restic Python не требуется: он нужен нашему учебному генератору и тестам.

Такой подход делает опыт повторяемым. Вы знаете, какая версия выполняла команды, а повреждённый или неожиданный архив не будет принят вместо нужного файла. Проверка checksum опирается на доверенный список проекта; при самостоятельном обновлении полезно отдельно проверить официальные SHA256SUMS и подпись релиза по инструкции разработчиков.

На ARM-сервере потребуется другой бинарник. Не запускайте x64-installer по привычке и не заменяйте файл непроверенным скачиванием из случайной инструкции. Сначала определите систему и архитектуру, затем источник пакета и версию. После обновления повторите маленький backup/restore-тест: успешное сообщение version подтверждает запуск программы, но ещё не проверяет ваш процесс восстановления.

python tools/install.py
# Linux: python3 tools/install.py
# Бинарник останется в tools/bin, глобальная установка не требуется.

Официальная документация: установка и проверка релизов.

Безопасный учебный набор: что делает runner

Учебная команда принимает только имя запуска, например windows-demo. Она сама создаёт папку .runtime с этим именем, синтетический источник, локальный репозиторий, кэш и случайный пароль. Передать произвольный каталог документов или внешний адрес хранилища ей нельзя. Если такое имя уже существует, программа завершится и предложит выбрать новое, сохранив прежние данные.

В наборе восемь файлов: две инструкции, CSV с заказами, пример конфигурации, двоичный образец, временный кэш, журнал и фиктивный .env. Пять файлов включаются в снимки. Во время опыта меняются только собственные сгенерированные документы; один из них удаляется, чтобы продемонстрировать восстановление старой версии.

Реальные репозитории и парольные файлы не входят в скачиваемый архив. Они появляются у вас локально. На Linux пароль получает ограниченные права доступа; на Windows проект следует держать в личной папке с корректными NTFS ACL. Эти ограничения помогают избежать случайного выбора рабочих данных, но не являются песочницей против пользователя, который сам изменяет Python-код или подменяет файлы проекта.

python tools/run_lab.py --run windows-demo
# Новый опыт — новое имя, существующая папка не очищается.

Init: репозиторий и пароль решают разные задачи

Репозиторий — место хранения зашифрованных данных. Пароль позволяет открыть его ключи и получить доступ к содержимому. Если потерять пароль, одного набора файлов репозитория недостаточно для восстановления. Если потерять сам репозиторий, знание пароля тоже не вернёт данные. Поэтому аварийный план должен сохранять оба элемента, но не зависеть исключительно от одного исходного сервера.

В обычной ручной работе init создаёт структуру нового хранилища. Выполняется он при подготовке репозитория, а не перед каждым ежедневным бэкапом. Пример ниже показывает синтаксис с условными путями; учебный runner подставляет собственные абсолютные пути и случайный парольный файл автоматически.

Не кладите настоящий пароль в Git, публичный README или командную строку, которая попадёт в историю shell. Для автоматизации используйте защищённый файл либо другой предусмотренный механизм выдачи секрета. Отдельно подумайте о восстановительной копии пароля: её должен суметь получить ответственный человек даже при недоступности обычного рабочего компьютера и VPS.

restic --repo REPO --password-file PASSWORD_FILE init

Официальная документация: подготовка локального и удалённого репозитория.

Backup: сохраняем файлы и проверяем результат

Первый backup читает подготовленный источник и создаёт снимок. В нашем наборе это пять включённых файлов общим объёмом чуть больше 256 КиБ. Большую часть занимает синтетический двоичный файл, а маленькие документы дают понятные изменения в последующих запусках. Источник, репозиторий и каталог восстановления находятся в разных подпапках одного учебного запуска.

Полезно сразу задавать осмысленные host и tag. Они помогают отличать данные разных серверов и задач, выбирать нужные снимки и позже применять политику хранения к понятной группе. Имя хоста не является механизмом авторизации: это метаданные процесса, поэтому права доступа к backend всё равно настраиваются отдельно.

После выполнения смотрите код завершения и итоговую статистику. Наличие нового снимка само по себе не доказывает, что прочитаны абсолютно все необходимые файлы. Ошибка доступа к одному важному документу должна попасть в журнал и мониторинг. Наш runner считает любой ненулевой код ошибкой и не сообщает PASS, пока не завершит восстановление и сравнение хешей.

restic --repo REPO --password-file PASSWORD_FILE backup data \
  --exclude-file exclude.txt --host aen-restic-lab --tag lab

Повторный запуск: что действительно означает incremental

Во втором опыте содержимое не меняется. Restic снова обходит источник, сравнивает его состояние и создаёт ещё одну точку восстановления, используя уже сохранённые данные. В журнале видны пять неизменённых файлов, ноль новых и data_added равный нулю. Можно открыть оба снимка и убедиться, что SHA256 файлов совпадают.

Это полезно для часто запускаемых задач: не нужно заранее решать, какой день недели будет «полным», а какой «дифференциальным», и затем вручную собирать эту цепочку при аварии. Пользователь выбирает сохранённую версию. Однако репозиторий остаётся общим хранилищем, и его потеря затрагивает все содержащиеся в нём снимки.

Время повторного запуска не обязано быть нулевым. Сканирование каталогов, проверка метаданных, сетевые обращения и запись снимка всё равно требуют ресурсов. На большом количестве маленьких файлов эти затраты могут заметно отличаться от копирования нескольких крупных объектов. Наш маленький набор демонстрирует механику, а не обещает конкретную скорость для вашего VPS.

Exclude: не сохранять лишнее и не потерять нужное

В демонстрации исключены cache/**, файлы с расширением .log и фиктивный .env. После первого бэкапа мы проверяем фактический список файлов в снимке. Это важнее, чем просто увидеть правила в текстовом файле: неожиданное совпадение шаблона может оставить за пределами копии нужный документ, а слишком узкое правило — включить гигабайты временных данных.

Исключение настоящего .env не является универсальной рекомендацией. Настройки и секреты нужны для восстановления сервиса; их либо резервируют в защищённом составе, либо сохраняют отдельным процессом и явно описывают получение. В нашем наборе .env содержит лишь искусственную строку, чтобы показать работу правила без реальных учётных данных.

Будьте внимательны к пустым каталогам: исключение файлов журнала не обязательно убирает сам каталог logs из дерева. Для пользователя это обычно нормально, но автоматический тест должен проверять именно требуемое свойство. В источниках проекта сравниваются включённые файлы и их содержимое; мы не объявляем ошибкой наличие пустого каталога, который ничего секретного не содержит.

cache/**
*.log
.env

Официальная документация: backup, исключения и особенности источников.

Snapshots и diff: выбираем момент до ошибки

В нашей истории третий снимок содержит обновлённые guide.txt и orders.csv. В четвёртом исчезает obsolete.txt и появляется recovery.txt. В пятом снова обновляется инструкция. Благодаря этому мастерская показывает несколько типичных случаев: неизменённый файл, изменение содержимого, появление нового документа и удаление старого.

Команда snapshots показывает доступные точки, а diff сравнивает две выбранные версии. Между первым и последним снимком получаются два изменения, одно добавление и одно удаление. Это помогает понять, когда произошло событие, но не отвечает на вопрос о правильности текста документа. Для важных данных потребуется восстановить файл и проверить его содержимое предметно.

Идентификаторы в браузерной мастерской относятся к сохранённому опыту автора. У вас после запуска будут другие ID, даже при похожем наборе файлов. Поэтому вспомогательная команда explore.py читает собственный report.json и выбирает снимки автоматически. Так читатель может повторить опыт, не копируя чужой ID и не пытаясь найти его в другом репозитории.

python3 tools/explore.py --run linux-demo --action snapshots
python3 tools/explore.py --run linux-demo --action diff

Полное восстановление: сначала отдельный каталог

Самый важный шаг — вернуть данные из выбранной версии. В опыте мы восстанавливаем первый и последний снимки в разные новые папки. Затем вычисляем SHA256 каждого файла и сравниваем с тем состоянием, которое существовало на момент соответствующего бэкапа. Получаются две отдельные проверки по пять файлов, а не одно поверхностное сравнение количества имён.

Раздельный каталог защищает процесс от поспешного смешивания старых и новых данных. Если сразу восстанавливать поверх работающего сайта, можно получить набор файлов из разных состояний или затереть нужные изменения. Сначала изучите результат, проверьте права и содержимое, подготовьте приложение и только затем планируйте переключение в рабочее место.

Explore.py при каждом восстановлении создаёт новый путь с уникальным окончанием внутри учебного запуска. Он не принимает произвольный target. Это позволяет повторить проверку несколько раз и сохранить результаты для сравнения. В рабочей процедуре подобное разделение полезно дополнить журналом выбранного снимка, времени начала и окончания, ответственного человека и результата запуска приложения.

python3 tools/explore.py --run linux-demo --action restore --snapshot first
python3 tools/explore.py --run linux-demo --action restore --snapshot latest

Один файл из прошлого: include и путь внутри снимка

Часто авария затрагивает один документ, а не весь сервер. Тогда удобнее извлечь нужный файл в отдельную папку и передать его владельцу, сохранив действующий проект на месте. В демонстрации мы берём guide.txt из третьего снимка: это промежуточная версия, которая отличается и от первой, и от последней.

Важно различать путь источника на компьютере и путь внутри дерева снимка. Наш backup запускается для относительного каталога data, поэтому документ находится в снимке по адресу /data/docs/guide.txt. Восстановление с include выбирает именно этот файл. Нельзя без проверки перенести путь из чужого примера на собственный снимок с другой структурой.

Отдельная тонкость касается параметра –path: в restore он помогает выбрать снимок по источнику, а не заменяет фильтр извлекаемых файлов. Для выборочного восстановления изучите ls и используйте подходящий include либо предусмотренную возможность указать поддерево снимка. После извлечения всё равно проверяйте, что получена нужная версия документа, а не просто файл с ожидаемым именем.

restic --repo REPO --password-file PASSWORD_FILE restore THIRD_ID \
  --target FRESH_DIRECTORY --include /data/docs/guide.txt --verify

Официальная документация: полное и выборочное восстановление.

Check и SHA256: что именно мы проверили

Проверка репозитория и проверка восстановленного файла дополняют друг друга. Check анализирует внутреннюю целостность, а вариант –read-data дополнительно читает сохранённые данные. В нашем маленьком репозитории полный проход завершился сообщением об отсутствии ошибок. Его фактический вывод доступен в мастерской, включая число обработанных снимков и пакетов.

SHA256 сравнивает байты восстановленного файла с ожидаемыми байтами синтетического источника. Эта проверка подтверждает, что в конкретном опыте мы получили правильное содержимое. Она не проверяет бизнес-смысл CSV, возможность авторизации в приложении или корректность внешней интеграции. Поэтому рабочий restore drill должен включать запуск сервиса и прикладные проверки.

На большом удалённом репозитории полное чтение займёт время и может стоить денег за трафик и запросы. Планируйте его отдельно от ежедневного копирования и учитывайте блокировки обслуживания. Не превращайте дорогую проверку в формальность, запускаемую слишком редко для обнаружения повреждений: частоту выбирают по требованиям и наблюдаемым затратам.

python3 tools/explore.py --run linux-demo --action check

Официальная документация: работа с репозиторием и проверка данных.

Хранение истории: сначала dry-run, затем решение

История не может расти бесконечно, но её сокращение требует понятной политики. В учебной части мы сравниваем три простых варианта: сохранить один, два или три последних снимка. Каждая команда использует –dry-run, фильтры host и tag и явную группировку host,paths. После всех просмотров снова запрашивается список снимков и проверяется, что он не изменился.

Для рабочего сервиса обычно важны дневные, недельные и месячные точки. Их количество выбирают по задержке обнаружения ошибок, доступному месту и обязательствам перед пользователями. Несколько серверов или разные наборы путей могут образовать отдельные группы. Поэтому «оставить последние два» без понимания группировки может означать не то, что вы ожидали по общей таблице.

В интерфейсе специально написано «план удаления». Это не оценка освобождаемого места: несколько снимков могут разделять одни данные. Перед реальным изменением политики посмотрите полный план, проверьте самые старые нужные версии и наличие независимой копии. В скачиваемом проекте и его systemd-шаблоне нет автоматического удаления истории.

restic --repo REPO --password-file PASSWORD_FILE forget \
  --keep-daily 7 --keep-weekly 4 --keep-monthly 6 \
  --group-by host,paths --dry-run

Forget и prune: почему это разные операции

Forget меняет набор доступных снимков. Prune занимается данными, которые больше не нужны оставшимся снимкам. Из-за совместного использования блоков удаление одной точки не означает, что освободится объём, равный полному размеру всех её файлов. Именно поэтому репозиторий обслуживается командами restic, а не ручным удалением случайных подпапок.

В нашем runner реальные операции удаления заблокированы: forget разрешён только с –dry-run, а prune вообще отсутствует в разрешённом наборе команд. Это позволяет изучать политики на собственном учебном репозитории без риска случайно превратить просмотр в очистку. Обычный бинарник restic такими учебными ограничениями, конечно, не связан.

На рабочем сервере обслуживание нужно согласовать по времени, ресурсам и правам. Не стоит выдавать повседневному процессу больше возможностей, чем требует выбранная архитектура хранения, а затем надеяться только на пароль шифрования. Важно отдельно продумать, кто может удалить историю, как обнаруживается такое событие и где находится копия, недоступная этому же набору учётных данных.

Официальная документация: политики хранения и очистка.

Windows: повторяем опыт без изменения системных настроек

Распакуйте архив в личную папку и откройте PowerShell в корне restic-project. Нужен установленный Python 3.11 или новее. Installer создаст локальный бинарник, а runner выполнит полный цикл в .runtime/windows-demo. Для начала не требуется менять системный PATH, выдавать доступ ко всему диску или запускать терминал администратора.

После завершения откройте report.json своего запуска либо используйте explore.py. Для мастерской включите простой HTTP-сервер только на loopback и только с каталогом public. Если отдать корень проекта, рядом окажутся runtime-данные и парольные файлы: это лишняя и опасная привычка даже в учебном окружении.

В архиве есть оболочка PowerShell, но основные Python-команды работают и без запуска .ps1. Поэтому менять глобальную execution policy ради урока не нужно. На настоящем Windows-сервере дополнительно учитывайте открытые файлы, права службы и требования VSS. Параметр –use-fs-snapshot может помочь получить файловый снимок, однако согласованность конкретной базы или приложения всё равно требует отдельного решения.

python tools/install.py
python tools/run_lab.py --run windows-demo
python tools/explore.py --run windows-demo --action restore --snapshot single
python -m http.server 8133 --directory public --bind 127.0.0.1

Linux и Docker: тот же сценарий в изолированном томе

На Linux используется python3 и тот же исходный runner. Разница между оболочками не меняет модель опыта: создаются собственные файлы, собственный пароль и отдельный репозиторий. В архиве есть Bash-обёртка, которая сначала проверяет наличие локального бинарника через installer, затем запускает выбранное имя опыта.

Docker-вариант полезен, когда хочется проверить именно Linux, оставаясь на Windows. Во время сборки образ получает restic с проверкой checksum. Во время самого опыта сеть отключена, портов нет, корень контейнера доступен только для чтения, а запись идёт в отдельный именованный том и временную папку. Каталоги пользователя в контейнер не подключаются.

Том сохраняется после завершения команды: в нём находится учебный репозиторий вместе с паролем. Поэтому повторный запуск с тем же именем корректно завершится отказом, а новый опыт требует нового имени. Не используйте глобальную очистку Docker ради одного урока. Если решите убрать учебные данные, сначала точно установите, какой том принадлежит именно этому проекту.

python3 tools/install.py
python3 tools/run_lab.py --run linux-demo

# Альтернатива: полноценный Linux-опыт в Docker
docker compose build
docker compose run --name restic-lab-example lab --run docker-demo
docker compose run --entrypoint python lab tools/explore.py \
  --run docker-demo --action restore --snapshot latest

Linux VPS: отдельный сервер и SFTP-хранилище

Локальная папка рядом с источником показывает механику, но не защищает от потери физического диска. Для рабочего сайта нужен другой носитель или сервер с независимым доступом. Один из понятных вариантов — SFTP. Вы выделяете на backup-сервере отдельную учётную запись и каталог, а на исходном VPS настраиваете ключ SSH для этой конкретной задачи.

Перед автоматизацией проверьте fingerprint SSH-сервера по независимому каналу и сохраните known_hosts. В шаблоне включены BatchMode и строгая проверка ключа: задача должна предсказуемо завершаться ошибкой, если доверие нарушено, а не молча соглашаться с новым сервером. Не отключайте StrictHostKeyChecking ради того, чтобы расписание наконец «позеленело».

Адрес ниже условный: backup.example заменяется вашим подготовленным сервером, путь — выделенным каталогом. Пароль репозитория хранится отдельно от SSH-ключа; это разные уровни доступа. Сначала выполните маленький тестовый backup и restore в этом backend, проверьте права и свободное место. Только после этого подключайте согласованный источник рабочего приложения и расписание.

RESTIC_REPOSITORY=sftp:restic-backup:/srv/restic/site
RESTIC_PASSWORD_FILE=/etc/restic/site.password
RESTIC_CACHE_DIR=/var/cache/restic-site

S3-compatible: endpoint, credentials и цена чтения

Для объектного хранилища задаётся адрес backend и отдельные credentials. Важны правильный endpoint, bucket, регион и права на необходимые операции. Учётные данные помещают в защищённый EnvironmentFile либо другой управляемый механизм секретов, а не в публикуемый пример и не в историю терминала. В README показан формат настройки без настоящих ключей.

Помимо стоимости занимаемого места посчитайте чтение, запись и исходящий трафик. Полная проверка данных и восстановление большого сервиса могут заметно отличаться по цене от ежедневного небольшого прироста. Проверьте ограничения провайдера на своём тестовом наборе и оцените время восстановления через реальный канал связи.

Версионирование и Object Lock требуют отдельного проектирования. Нельзя считать любую включённую галочку гарантированной совместимостью с операциями restic, его блокировками и обслуживанием. Проверьте конкретный backend на отдельном bucket и убедитесь, что умеете восстановиться при ограничении удаления. В нашей статье внешний аккаунт не создаётся: рабочие команды опыта используют только локальные репозитории.

RESTIC_REPOSITORY=s3:https://storage.example/bucket/site
# AWS_ACCESS_KEY_ID и AWS_SECRET_ACCESS_KEY задаются отдельно
# в защищённой конфигурации конкретного сервера.

База данных и живое приложение: сначала согласованное состояние

Копирование каталога работающей базы не обязательно даёт пригодный для восстановления набор файлов. У базы есть свои механизмы журналов, транзакций и согласованных экспортов. Для простого процесса часто удобнее сначала получить завершённый dump штатными средствами, проверить его код завершения, а затем включить этот файл в резервирование.

Чтобы backup не захватил недописанный экспорт, сохраняйте его под временным именем и переименовывайте в окончательное только после успешного завершения. Исключите временный шаблон и следите за свободным местом. Если выгрузка не состоялась, нельзя выдавать старый dump за свежую успешную копию: в журнале должны быть дата экспорта и результат проверки.

Файлы загрузок и данные базы также могут требовать согласования между собой. Приложение должно понимать, что делать с вложением, которое появилось между двумя этапами. Для серьёзного сервиса выбирайте подходящий режим обслуживания, журналирование или штатный механизм консистентных снимков. Наш набор с CSV объясняет файловое восстановление и не изображает проверку настоящей СУБД, которой в опыте нет.

Systemd и расписание: запуск, журнал и пропущенная ночь

В архиве есть шаблоны службы и таймера. Служба работает от отдельного пользователя, читает защищённый EnvironmentFile и резервирует явно выбранный backup-source. В ней нет forget и prune. Перед установкой нужно адаптировать пути, создать учётную запись, дать необходимые права чтения, настроить SSH и проверить бинарник по указанному абсолютному пути.

Сначала запустите службу вручную, изучите status и journalctl, затем выполните восстановление. Только после успешного опыта включайте таймер. В примере используется ежедневное окно с небольшим случайным сдвигом; время трактуется по часовому поясу сервера. Persistent помогает догнать пропущенный запуск после включения, но не заменяет наблюдение за результатом.

Cron тоже подходит, однако потребует явного PATH, загрузки окружения, контроля параллельных запусков, журналов и реакции на ошибку. Не настраивайте два независимых расписания для одной задачи по забывчивости. Важен один понятный владелец процесса и проверяемый результат. Мониторинг должен замечать не только красную ошибку, но и отсутствие ожидаемого свежего снимка.

sudo systemctl daemon-reload
sudo systemctl start restic-site.service
sudo systemctl status restic-site.service --no-pager
sudo journalctl -u restic-site.service -n 80 --no-pager
# После проверки восстановления:
sudo systemctl enable --now restic-site.timer
systemctl list-timers restic-site.timer

Наблюдение и restore drill: проверяем не только exit code

Успешный код завершения — необходимая часть контроля. Для backup код 3 означает, что некоторые исходные данные не удалось прочитать: это неполный результат, который нельзя автоматически считать нормальным. Неизвестный код тоже трактуется как ошибка. Конструкция «команда || true» может скрыть как раз тот случай, ради которого нужна система наблюдения.

Дополнительно контролируйте возраст последнего успешного снимка, длительность задания, количество и объём данных, доступность backend и свободное место. Резкое уменьшение размера может означать корректную очистку источника, а может — потерю нужного пути. Такие сигналы требуют контекста, поэтому полезно сохранять структурированный журнал и историю ожидаемых объёмов.

Регулярная учебная авария проверяет весь путь: новый каталог или отдельный хост, доступ к паролю, выбор снимка, restore, проверка файлов, импорт базы и запуск приложения. Изолируйте внешние действия восстановленного сервиса, чтобы он не отправлял настоящие письма и вебхуки во время теста. Запишите фактическое время и найденные недостающие шаги: это превращает абстрактный план в рабочую инструкцию.

Официальная документация: коды завершения, окружение и JSON для автоматизации.

Шифрование, ransomware и независимая копия

Шифрование защищает содержимое от чтения без ключа, но не делает файлы репозитория неуничтожимыми. Если злоумышленник получил права удалить хранилище, он может лишить вас резервных копий, не расшифровывая их. Поэтому пароль restic и ограничение доступа к backend решают разные части задачи и должны рассматриваться вместе.

Практический план включает независимые учётные данные, разделение административных полномочий и копию, недоступную обычному процессу записи. Это может быть отключённый носитель, отдельный контур или продуманное хранилище с ограничениями удаления. Конкретное решение проверяется восстановлением и моделью доступа; само слово «облако» не гарантирует независимость, если всё управляется одним скомпрометированным аккаунтом.

Не забывайте о сроке обнаружения атаки. Если испорченные данные регулярно сохранялись и политика уже вытеснила здоровую историю, последние снимки не помогут. Для важных систем нужна разумная глубина хранения и проверка содержимого на нескольких временных точках. Учебная мастерская показывает механизм снимков, а организационные сроки и права остаются решением владельца сервиса.

Обновление, границы проверки и готовые исходники

Обновляйте restic через отдельный проверенный релиз: сохраните рабочий бинарник, прочитайте изменения, повторите учебный цикл и проверьте восстановление своей копии в согласованное окно. Не совмещайте бездумно обновление программы с миграцией формата репозитория. Откат бинарника может не помочь, если старый клиент уже не понимает новую структуру хранения.

В этой публикации действительно выполнены Windows- и Linux-прогоны: по пять снимков, два полных восстановления, одно выборочное, одиннадцать совпавших SHA256 за прогон, чтение данных через check и три dry-run политики. В обоих случаях история сохранилась. Исходники включают тесты записанных результатов, проверки недопустимого имени запуска, оболочки, Docker и подробные шаблоны VPS. Внешний SFTP/S3 и ваш сервер при подготовке материала не использовались.

Собственный код и синтетические файлы доступны под MIT, restic распространяется под BSD-2-Clause. Бинарник, реальные репозитории и парольные файлы в архив не включены. Возьмите из проекта главное: ограниченный источник, явную версию инструмента, понятную историю, отдельное восстановление и проверяемый результат. Затем адаптируйте этот процесс к своим данным, расписанию и требованиям сервиса.