Я дважды терял данные на серверах. Первый раз — когда хостер молча удалил VPS за неоплату (письмо ушло в спам). Второй — когда rm -rf оказался чуть более рекурсивным, чем планировалось. После второго раза решил, что бэкапы — это не «надо бы настроить», а «надо настроить сегодня».

Почему restic

Пробовал разное: tar + cron (неудобно, нет дедупликации), Borg (хороший, но сложнее в настройке удалённого хранилища), Duplicity (медленный). Restic попал в золотую середину: быстрый, простой, шифрует по умолчанию, умеет лить в S3, SFTP, и кучу других бэкендов.

Установка

apt install -y restic
# Или свежую версию:
wget https://github.com/restic/restic/releases/latest/download/restic_0.17.3_linux_amd64.bz2
bunzip2 restic_*.bz2
chmod +x restic_*
mv restic_* /usr/local/bin/restic

Инициализация репозитория

Я использую SFTP на отдельный сервер. Можно использовать S3 (Minio, Backblaze B2, Wasabi — что угодно).

export RESTIC_REPOSITORY="sftp:backupuser@backup-server:/backups/vps1"
export RESTIC_PASSWORD="СИЛЬНЫЙ_ПАРОЛЬ"

restic init

Пароль шифрует весь репозиторий. Без него данные — мусор. Храните его в менеджере паролей, а не в голове.

Скрипт бэкапа

#!/bin/bash
export RESTIC_REPOSITORY="sftp:backupuser@backup-server:/backups/vps1"
export RESTIC_PASSWORD_FILE="/root/.restic-password"

restic backup \
  /etc/nginx \
  /var/www \
  /home \
  --exclude="*.log" \
  --exclude="node_modules" \
  --exclude=".cache"

# Чистка: хранить 7 ежедневных, 4 еженедельных, 6 ежемесячных
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune

# Проверка целостности (раз в неделю достаточно)
if [ "$(date +%u)" -eq 7 ]; then
  restic check
fi

Автоматизация

chmod +x /root/backup.sh
echo "RESTIC_PASSWORD" > /root/.restic-password
chmod 600 /root/.restic-password

# Каждый день в 4:00
echo "0 4 * * * /root/backup.sh >> /var/log/restic.log 2>&1" | crontab -

Восстановление

# Посмотреть снапшоты
restic snapshots

# Восстановить последний снапшот
restic restore latest --target /tmp/restore

# Восстановить конкретный файл
restic restore latest --target /tmp/restore --include "/etc/nginx/sites-available/mysite"

Что я бэкаплю

На каждом сервере — /etc (конфиги), /var/www (сайты), /home (пользовательские данные). Базы данных дампаю перед бэкапом отдельным скриптом (pg_dump / mysqldump), потому что бэкапить файлы живой БД — лотерея.

Restic дедуплицирует на уровне блоков, поэтому ежедневные бэкапы сайта в 500 MB занимают не 500 MB × 30 = 15 GB, а скорее 600-700 MB за месяц. Экономия ощутимая.

Теперь сплю спокойнее.