Бэкапы домашнего сервера на restic
Два года у меня был rsync в папку с датой. Работало, пока не понадобилось достать файл трёхмесячной давности — и выяснилось, что места хватило только на две недели, а я этого не знал.
Что получилось
Один репозиторий на внешнем диске, второй — на удалённом хранилище. Дедупликация у restic блочная, поэтому ежедневные снимки почти ничего не стоят.
export RESTIC_REPOSITORY=/mnt/backup/restic
export RESTIC_PASSWORD_FILE=/etc/restic/passwd
restic backup \
--exclude-file=/etc/restic/excludes \
--tag daily \
/home /etc /var/lib/postgresql /srv
Файл исключений — половина успеха, иначе в снимок уезжают кеши:
/home/*/.cache
/home/*/.local/share/Trash
**/node_modules
**/.venv
*.iso
Политика хранения
restic forget --prune \
--keep-daily 14 \
--keep-weekly 8 \
--keep-monthly 12 \
--keep-yearly 3
forget без --prune только убирает снимок из списка, место не освобождает. Я это понял не сразу и месяц удивлялся, почему диск не худеет.
Проверка — не опция
Бэкап, который никогда не восстанавливали, — это не бэкап. Раз в неделю по таймеру:
restic check --read-data-subset=5%
И раз в месяц руками — реальное восстановление во временный каталог с прогонкой diff:
restic restore latest --target /tmp/verify --include /etc/nginx
diff -r /etc/nginx /tmp/verify/etc/nginx && echo OK
Что я делал неправильно
- Хранил пароль от репозитория в том же репозитории. Звучит глупо, потому что это и есть глупо. Пароль теперь лежит отдельно, в том числе на бумаге.
- Бэкапил живой каталог PostgreSQL. Файлы копируются в произвольный момент, снимок получается несогласованным. Правильно —
pg_dumpилиpg_basebackupв отдельный файл, и уже его класть в restic. - Не следил за успешностью. Теперь сервис после удачного прогона дёргает healthcheck-URL, и если тишина дольше суток — приходит письмо.
- Держал оба репозитория на одной машине. Шифровальщик или кривой
rmубирают оба разом. Удалённая копия должна быть append-only.