До недавнего времени я делал бэкапы своих устройств на внешний 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)
vvbob
04.06.2023 16:59Я у себя просто все что не хочу потерять в случае чего копирую в папки, синхронизированные через облака, на нескольких компьютерах все синхронизируется и в случае поломки какого-либо компьютера, я просто возьму данные из облака или с папки на другом устройстве.
borovinskiy
04.06.2023 16:59А если словите шифровальщика, синхронизируете зашифрованные файлы на все компьютеры?
vvbob
04.06.2023 16:59У меня компы начиная с девяностых самые разные, за все время на домашний ни одного вируса не ловил и ни одного байта из-за этого не потерял (на рабочих бывало - из локалки какая-то зараза прилетала)
khajiit
04.06.2023 16:59Йа тыщщу раз так делал это так себе ответ.
Правильный ответ — минимум два физически подконтрольных вам разнесенных инстанса, и в обоих настроено то или иное версионирование.
Harliff
А в чём профит именно S3-бэкенда (при развёртывании у себя)?
vikarti
Возможно в том, что это стандартное решение и можно при желании переехать еще куда?
classx
думаю чтобы не платить Амазону
Loxmatiymamont
Модно же. У всех s3, значит и у меня s3 должен быть.
Veelim Автор
Все так)
Veelim Автор
В сценарии домашнего бэкапа профита может не быть. Это просто один из вариантов бэкенда. Для меня профит в том, что S3 API по историческим причинам был предпочтительнее.