Привіт! Я Kernelka і сьогодні покажу, як зробити надійне резервне копіювання системи на Btrfs без магії й болю. Ви навчитеся створювати снапшоти через snapper, відправляти їх на інший диск за допомогою btrfs send/receive та автоматизувати все це через cron та systemd timers. Усе робитимемо в термінал Linux — чітко, швидко й повторювано 🙂

Передумови та швидкі перевірки

Вам потрібні:

  • Система на Btrfs (бажано окремі субтоми для / і /home).
  • Диск або розділ для бекапів (також у Btrfs, щоб працював btrfs receive).
  • Доступ root (sudo) і базове розуміння автоматизація задач.

Перевіряємо, що файлові системи — Btrfs:

lsblk -f
btrfs subvolume list -p /

How-to: налаштування snapper для снапшотів

1) Встановлення snapper

Оберіть команду для вашого дистрибутива:

# Debian/Ubuntu
sudo apt update && sudo apt install -y snapper

# Fedora
sudo dnf install -y snapper

# Arch/Manjaro
sudo pacman -S --needed snapper

# openSUSE (зазвичай вже є)
sudo zypper in -y snapper

2) Увімкнути квоти для контрольованого простору

Так snapper краще керує чисткою снапшотів за обсягом:

sudo btrfs quota enable /
sudo btrfs qgroup rescan /

3) Створення конфігів для кореня і домашнього

Ці команди створять службовий субтом .snapshots у відповідних точках монтування.

sudo snapper -c root create-config /
sudo snapper -c home create-config /home

# Переконайтеся, що каталоги створені
sudo snapper -c root list
sudo snapper -c home list

4) Налаштування політик знімків і чистки

Встановимо адекватні ліміти таймлайн‑снапшотів.

sudo snapper -c root set-config \
  "TIMELINE_CREATE=yes" \
  "TIMELINE_MIN_AGE=1800" \
  "TIMELINE_LIMIT_HOURLY=6" \
  "TIMELINE_LIMIT_DAILY=7" \
  "TIMELINE_LIMIT_WEEKLY=4" \
  "TIMELINE_LIMIT_MONTHLY=6" \
  "TIMELINE_LIMIT_YEARLY=1"

sudo snapper -c home set-config \
  "TIMELINE_CREATE=yes" \
  "TIMELINE_MIN_AGE=1800" \
  "TIMELINE_LIMIT_HOURLY=6" \
  "TIMELINE_LIMIT_DAILY=7" \
  "TIMELINE_LIMIT_WEEKLY=4" \
  "TIMELINE_LIMIT_MONTHLY=6" \
  "TIMELINE_LIMIT_YEARLY=1"

5) Увімкнення таймерів snapper

Вони створюють таймлайн‑снапшоти та чистять старі.

sudo systemctl enable --now snapper-timeline.timer snapper-cleanup.timer
systemctl status snapper-timeline.timer --no-pager

6) Ручні снапшоти перед оновленнями

Зручно до і після великих змін:

sudo snapper -c root create -d "before system upgrade"
sudo snapper -c root create -d "after system upgrade"

Резервне копіювання через btrfs send/receive

Btrfs може «стрімити» read-only снапшоти на інший Btrfs-том. Це швидко й економно до місця.

1) Підготовка диска для бекапів

Увага: форматування знищить дані на диску!

# Приклад: створити Btrfs з міткою BACKUP (ОБЕРЕЖНО)
sudo mkfs.btrfs -L BACKUP /dev/sdX1

# Монтуємо бекап-том
sudo mkdir -p /mnt/backup
sudo mount -o compress=zstd,autodefrag LABEL=BACKUP /mnt/backup

# Створимо каталог для прийому снапшотів
sudo mkdir -p /mnt/backup/root /mnt/backup/home

2) Перша (повна) передача снапшоту

Знайдіть номер потрібного снапшоту (див. snapper -c root list) і відправте його:

SN=100   # приклад номера снапшоту
sudo btrfs send /.snapshots/$SN/snapshot | sudo btrfs receive /mnt/backup/root

3) Інкрементальні передачі

Інкремент працює, якщо на цільовому томі вже є «батьківський» снапшот.

PARENT=100
CHILD=120
sudo btrfs send -p /.snapshots/$PARENT/snapshot /.snapshots/$CHILD/snapshot | \
  sudo btrfs receive /mnt/backup/root

4) Автоматизація через systemd timers

Зробимо простий скрипт, який синхронізує найсвіжіший снапшот кореня. Це чиста автоматизація задач без кривого cron.

# 4.1 Скрипт синхронізації
sudo tee /usr/local/bin/btrfs-sync-root.sh >/dev/null <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
CONF=root
SRC=/.snapshots
DST=/mnt/backup/root
LAST_FILE="$DST/.last"

# Створюємо новий снапшот (на випадок, якщо timeline ще не спрацював)
sudo snapper -c "$CONF" create -d "auto-backup $(date -Iseconds)"

mkdir -p "$DST"
last_parent=""
[[ -f "$LAST_FILE" ]] && last_parent=$(cat "$LAST_FILE") || true

latest=$(snapper -c "$CONF" list --columns number | tail -n1 | tr -d ' ')
src_path="$SRC/$latest/snapshot"

if [[ -n "$last_parent" && -d "$SRC/$last_parent/snapshot" ]]; then
  sudo btrfs send -p "$SRC/$last_parent/snapshot" "$src_path" | sudo btrfs receive "$DST"
else
  sudo btrfs send "$src_path" | sudo btrfs receive "$DST"
fi

echo "$latest" | sudo tee "$LAST_FILE" >/dev/null
EOF
sudo chmod +x /usr/local/bin/btrfs-sync-root.sh

# 4.2 Юніт та таймер systemd
sudo tee /etc/systemd/system/btrfs-sync-root.service >/dev/null <<'EOF'
[Unit]
Description=Sync Btrfs root snapshots to backup
RequiresMountsFor=/mnt/backup
After=snapper-timeline.timer

[Service]
Type=oneshot
ExecStart=/usr/local/bin/btrfs-sync-root.sh
EOF

sudo tee /etc/systemd/system/btrfs-sync-root.timer >/dev/null <<'EOF'
[Unit]
Description=Daily Btrfs snapshot sync (root)

[Timer]
OnCalendar=hourly
Persistent=true
Unit=btrfs-sync-root.service

[Install]
WantedBy=timers.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now btrfs-sync-root.timer
systemctl list-timers --all | grep btrfs-sync-root

Альтернативні способи

  • btrbk — спеціалізований інструмент для Btrfs-бекапів з простими конфігами, ротацією та інкрементами «з коробки».
  • Timeshift (Btrfs) — зручний для робочих станцій, має GUI та автоматичні снапшоти; проте для складних сценаріїв btrfs send/receive гнучкіший.

GUI-спосіб (якщо любите віконця)

Можна встановити snapper-gui і керувати снапшотами безпосередньо з графічного інтерфейсу: створення, порівняння, відкат. Це не замінює btrfs send/receive, але допомагає з повсякденними задачами. Команди встановлення залежать від дистрибутива; пошукайте пакет snapper-gui у вашому репозиторії.

FAQ

Чому snapper не створює конфіг для / або /home?

Переконайтеся, що це Btrfs-субтоми й вони змонтовані. Якщо каталог /.snapshots вже існує, але не є субтомом, приберіть або перемістіть його перед create-config.

Отримую «No space left on device» під час receive

Звільніть місце, видаліть старі бекапи, запустіть баланс:

sudo btrfs balance start -dusage=75 -musage=75 /mnt/backup

І перевірте, чи не вимкнені квоти на джерелі: btrfs quota enable /.

Інкрементальний send не працює

На приймаючому томі має існувати точний батьківський снапшот (той самий UUID вмісту). Перевіряйте, що ви не перейменовували/не змінювали їх вміст.

Таймер systemd не запускається

Дивіться статуси:

systemctl status btrfs-sync-root.timer btrfs-sync-root.service
journalctl -u btrfs-sync-root.service -b

Також переконайтеся, що /mnt/backup змонтований до моменту запуску таймера (або використайте RequiresMountsFor як у прикладі).

Як зробити відкат до снапшоту?

На робочих станціях часто достатньо sudo snapper rollback (уважно прочитайте мануал для вашого дистро). Для системного розділу може знадобитися завантаження з live-носія або grub-запис із снапшотом.

Чи можна шифрувати бекапи?

btrfs send не шифрує потік сам по собі. Передавайте його через SSH: btrfs send ... | ssh host btrfs receive ..., або зберігайте на зашифрованому LUKS-томі.

Порада від Kernelka

Вмикайте стиснення Zstd на обох томах і тримайте ліміти snapper «помірними». Регулярно тестуйте відновлення на окремому середовищі — краще перевірити все в спокої, ніж панікувати під час реального інциденту 🚀

Підсумок

  • Snapper автоматично створює й чистить снапшоти Btrfs.
  • btrfs send/receive забезпечує швидкі й надійні передавання снапшотів на інший том.
  • systemd timers спрощують регулярні бекапи без ручної рутини.
  • Рішення підходить як для робочих станцій, так і для серверів.
  • Не забувайте про квоти, монтування бекап-диска і перевірку логів.

Все! Тепер ваші снапшоти та резервні копії живуть своїм автоматизованим життям — а ви спокійно оновлюєте систему й творите щось круте 😺