До недавнего времени я делал бэкапы своих устройств на внешний HDD. Такой способ меня устраивал потому, что бэкапил данные редко - раз в неделю. Когда задумался о ежедневных бэкапах, понял, что бегать с внешним HDD будет непрактично. Хочу рассказать про удобное (по крайней мере для меня) решение для ежедневных бекапов без проводов.

restic

Для создания самих бэкапов я пользуюсь программой restic. Это простая CLI программа, работает на всех популярных ОС т.к написана на Go. Позволяет делать бэкапы локально, на внешние устройства и в облачные сервисы из коробки. Довольно эффективно сжимает файлы, например, бэкап моей домашней директории размером в ~111GB получился всего в 20GB. При первом запуске он делает полный снапшот указанной директории, при последующих уже бэкапит дельту и сохраняет отдельными снапшотами только изменения. Снапшот - это содержимое директории в определенный момент времени.

MinIO

Бэкапы нужно где-то хранить, я выбрал для этого S3 хранилище MinIO. Его довольно легко развернуть на своем сервере, в веб-интерфейсе несложно разобраться и вообще это production ready решение, его успешно используют во многих крупных проектах для хранения данных.

Установка и настройка

Скачать restic можно из github репозитория или с помощью пакетного менеджера вашей ОС.

В первую очередь инициализируем репозиторий:

restic -r RESTIC_REPOSITORY init

Репозиторием может быть директория или адрес облачного сервиса, например, если делать бэкап прямо на том же компьютере в папку backup-repo, то команда будет выглядеть так:

restic -r /home/backup-repo init
enter password for new repository:
enter password again:

restic попросить ввести пароль от репозитория, пароль терять нельзя, иначе доступ к данным будут утерян.

Команда для запуска процесса бэкапа выглядит следующим образом:

restic -r /home/backup-repo --verbose backup /documents

Флаг --verbose нужен для подробного вывода информации. Этой коммандой мы запустили бэкап директории documents в директорию backup-repo.

Восстановить данные из бэкапа можно следующей командой:

restic -r /home/backup-repo restore latest --target /restore_folder

latest - это самый последний снапшот, можно указать id нужного снапшота, если требуется. restic позволяет восстанавливать отдельные файлы и директории для этого после флага --path необходимо указать нужный путь.

Развернуть MinIO удобнее всего в docker контейнере на вашем сервере:

docker run \
   -p 9000:9000 \
   -p 9090:9090 \
   --name minio \
   -v /mnt/my-storage:/data \
   -e "MINIO_ROOT_USER=ROOTNAME" \
   -e "MINIO_ROOT_PASSWORD=CHANGEME123" \
   quay.io/minio/minio server /data --console-address ":9090"
  • -p пробрасывает порты между контейнером и машиной на которой он запускается.

  • 9000 порт самого сервиса, 9090 порт веб-интерфейса.

  • -v указание директории в которой будут храниться данные на хостовой машине, сервис будет зеркалировать данные в директорию /data.

  • -e переменные окружения, нужны для доступа к веб-интерфейсу.

  • --console-address адрес по которому будет доступен веб-интерфейс.

После установки MinIO нужно зайти в консоль и создать ключ доступа (access key), чтобы restic мог подключаться к хранилищу.

Теперь можно сделать бэкап в MinIO:

# задаем переменные окружения с ID и SECRET, созданными ранее в веб-интерфейсе
export AWS_ACCESS_KEY_ID=my_key_id
export AWS_SECRET_ACCESS_KEY=my_key_secret

# создаем новый репозиторий и указываем пароль
restic -r s3:http://localhost:9000/backup-repo init
enter password for new repository:
enter password again:

# запускаем процесс бэкапа
restic backup -r s3:http://localhost:9000/backup-repo --verbose /documents

Вместо http://localhost:9000 будет ваш адрес на котором поднят MinIO.

В целом так и работает резервное копирование с restic и MinIO, но каждый день делать бэкапы руками быстро надоест, поэтому этот процесс нужно автоматизировать, чтобы процесс бэкапа был полностью автономным.

systemd

Я использую систему инициализации sytstemd для этих целей, но вместо systemd можно использовать cron на Linux или планировщик заданий на Windows для запуска скрипта по расписанию.

В первую очередь нужно создать файл в котором будут переменные окружения для работы restic ~/.config/restic-backup.conf

# ID и SECRET MinIO
AWS_ACCESS_KEY_ID=my_key_id
AWS_SECRET_ACCESS_KEY=my_key_secret
# адрес репозитория MinIO
RESTIC_REPOSITORY=s3:http://localhost:9000/backup-repo
# пароль от репозитория
RESTIC_PASSWORD=restic_pass
# путь к директории, которую бэкапим
BACKUP_PATH="/documents"
# за сколько дней нужно хранить бэкапы
RETENTION_DAYS=7

И сам файл сервиса systemd ~/.config/systemd/user/restic-backup.service

[Unit]
Description=Restic backup service
[Service]
Type=oneshot
ExecStart=restic backup --verbose $BACKUP_PATH
ExecStartPost=restic forget --verbose --keep-daily $RETENTION_DAYS
EnvironmentFile=%h/.config/restic-backup.conf

Комманда forget нужна для удаления старых снапшотов, флаг --keep-daily позволяет настроить политику хранения снапшотов т.е. за последние n дней, которые имеют один или более снапшотов, сохранять только самый последний для каждого дня. forget удаляет только снапшоты, но не сами данные.

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

Второй сервис ~/.config/systemd/user/restic-prune.service

[Unit]
Description=Restic backup service (data pruning)
[Service]
Type=oneshot
ExecStart=restic prune
EnvironmentFile=%h/.config/restic-backup.conf

Команда prune будет очищать данные на которые ссылаются удаленные снапшоты.

Теперь сделаем таймеры для сервисов в той же директории.

~/.config/systemd/user/restic-backup.timer

[Unit]
Description=Backup with restic daily
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target

OnCalendar задает время запуска, у меня сервис запускается ежедневно в 12 ночи, поэтому стоит значение daily.

~/.config/systemd/user/restic-prune.timer

[Unit]
Description=Prune data from the restic repository monthly
[Timer]
# This will run on the 1st of every month at 2AM
OnCalendar=*-*-01 02:00:00
Persistent=true
[Install]
WantedBy=timers.target

Сервис для очистки будет запускаться раз в месяц, каждое первое число в 2 часа ночи . Я указал 2 часа ночи, чтобы не было конфликта у сервисов с доступом к репозиторию.

Для работы сервисов нужно перезапустить менджер systemd, чтобы они подхватились:

systemctl --user daemon-reload

И запустить таймеры:

systemctl --user enable --now restic-backup.timer
systemctl --user enable --now restic-prune.timer

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

Полезные ссылки

Restic Documentation
MinIO docker install documentation
systemd service
systemd timer

Комментарии (15)


  1. Harliff
    04.06.2023 16:59
    +1

    А в чём профит именно S3-бэкенда (при развёртывании у себя)?


    1. vikarti
      04.06.2023 16:59
      +1

      Возможно в том, что это стандартное решение и можно при желании переехать еще куда?


    1. classx
      04.06.2023 16:59
      +1

      думаю чтобы не платить Амазону


    1. Loxmatiymamont
      04.06.2023 16:59

      Модно же. У всех s3, значит и у меня s3 должен быть.


      1. Veelim Автор
        04.06.2023 16:59

        Все так)


    1. Veelim Автор
      04.06.2023 16:59

      В сценарии домашнего бэкапа профита может не быть. Это просто один из вариантов бэкенда. Для меня профит в том, что S3 API по историческим причинам был предпочтительнее.


  1. theurus
    04.06.2023 16:59
    -1

    S3 это какая то профдеформация? restic не гордый, может и обычный ssh использовать в качестве цели.


    1. Veelim Автор
      04.06.2023 16:59
      +1

      Вы правы, можно и более простой вариант для репозитория выбрать


  1. vvbob
    04.06.2023 16:59

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


    1. Veelim Автор
      04.06.2023 16:59
      +2

      Возможно вам будет полезен Syncthing


      1. vvbob
        04.06.2023 16:59

        Возможно :)


    1. borovinskiy
      04.06.2023 16:59

      А если словите шифровальщика, синхронизируете зашифрованные файлы на все компьютеры?


      1. vvbob
        04.06.2023 16:59

        У меня компы начиная с девяностых самые разные, за все время на домашний ни одного вируса не ловил и ни одного байта из-за этого не потерял (на рабочих бывало - из локалки какая-то зараза прилетала)


        1. khajiit
          04.06.2023 16:59

          Йа тыщщу раз так делал это так себе ответ.
          Правильный ответ — минимум два физически подконтрольных вам разнесенных инстанса, и в обоих настроено то или иное версионирование.


    1. Ryav
      04.06.2023 16:59

      Попробуйте Duplicati.