aboutsummaryrefslogtreecommitdiff
path: root/backup
diff options
context:
space:
mode:
authorbenj <benj@rse8.com>2026-04-01 22:14:57 +0800
committerbenj <benj@rse8.com>2026-04-01 22:14:57 +0800
commit511733d2e11566bd85dec9728403baff3ad2e62b (patch)
treef0fd1d6c7ffc2a590eb934672be19fe8b2b19417 /backup
parentdd6884a7e290bfedf94ba8c8088ace6df43af02a (diff)
downloadmycfg-master.tar
mycfg-master.tar.gz
mycfg-master.tar.bz2
mycfg-master.tar.lz
mycfg-master.tar.xz
mycfg-master.tar.zst
mycfg-master.zip
cloud backup config for ad3HEADmaster
Diffstat (limited to '')
-rw-r--r--backup/ad3/.restic-env4
-rw-r--r--backup/ad3/README.org111
-rwxr-xr-xbackup/ad3/backup-cloud30
-rw-r--r--backup/ad3/backup-cloud.service10
-rw-r--r--backup/ad3/backup-cloud.timer10
-rw-r--r--backup/ad3/restic-exclude.txt77
6 files changed, 242 insertions, 0 deletions
diff --git a/backup/ad3/.restic-env b/backup/ad3/.restic-env
new file mode 100644
index 0000000..f5fb078
--- /dev/null
+++ b/backup/ad3/.restic-env
@@ -0,0 +1,4 @@
+export B2_ACCOUNT_ID=""
+export B2_ACCOUNT_KEY=""
+export RESTIC_REPOSITORY="b2:benj-ad3"
+export RESTIC_PASSWORD="" \ No newline at end of file
diff --git a/backup/ad3/README.org b/backup/ad3/README.org
new file mode 100644
index 0000000..abb96b9
--- /dev/null
+++ b/backup/ad3/README.org
@@ -0,0 +1,111 @@
+* Overview
+# sudo cp /root/.restic-env
+# sudo cp /root/restic-exclude.txt
+# sudo chmod 600 /root/.restic-env
+# sub the values for /root/.restic-env
+
+You need to initialize the restic repository first before you can back up to it. This is a one-time step:
+
+#+begin_src sh
+sudo bash -c 'source /root/.restic-env && restic init'
+#+end_src
+
+sudo systemctl daemon-reload
+sudo systemctl enable --now backup-cloud.timer
+
+# Verify
+systemctl list-timers backup-cloud.timer
+
+** Restoring from Restic
+
+#+begin_src sh
+sudo bash -c 'source /root/.restic-env && restic snapshots' # list snapshots
+sudo bash -c 'source /root/.restic-env && restic ls latest /home/benj' # browse
+sudo bash -c 'source /root/.restic-env && restic restore latest --target /tmp/restore' # full restore
+sudo bash -c 'source /root/.restic-env && restic restore latest --target /tmp/restore --include /home/benj/somefile' # specific file
+#+end_src
+
+** Disaster Recovery ISO
+
+This creates a bootable ISO that contains your disk layout, bootloader config, and everything needed to do a bare-metal restore onto a new or wiped machine.
+
+*** Install
+
+#+begin_src sh
+# From AUR
+paru -S rear # or yay -S rear
+#+end_src
+
+*** Configure
+
+Edit =/etc/rear/local.conf=:
+
+#+begin_src conf
+OUTPUT=ISO
+OUTPUT_URL=file:///root/rear-output/
+BACKUP=NETFS
+BACKUP_URL=file:///mnt/backup/rear/
+BACKUP_PROG_EXCLUDE=("${BACKUP_PROG_EXCLUDE[@]}" '/var/lib/docker' '/var/cache/pacman/pkg' '/home/benj/.cache' '/home/benj/.rustup' '/home/benj/.ghcup' '/home/benj/.stack' '/home/benj/.espressif' '/home/benj/go/pkg' '/home/benj/Android' '/home/benj/.npm/_cacache' '/home/benj/.cargo/registry' '/home/benj/.cargo/git' '/home/benj/.android/avd' '/var/log/journal' '/var/lib/systemd/coredump')
+#+end_src
+
+*** Create Recovery ISO
+
+#+begin_src sh
+# With external drive mounted at /mnt/backup:
+sudo mkdir -p /root/rear-output /mnt/backup/rear
+sudo rear -v mkbackup
+#+end_src
+
+This produces:
+- =/root/rear-output/rear-*.iso= — bootable recovery ISO
+- =/mnt/backup/rear/= — the backup archive
+
+*/ Using Rear to Restore
+
+1. Write the ISO to a USB stick: =sudo dd if=/root/rear-output/rear-*.iso of=/dev/sdX bs=4M status=progress=
+2. Boot from it on the new/wiped machine
+3. Select "Recover" from the menu
+4. Rear automatically:
+ - Recreates your partition layout
+ - Sets up LUKS (it will ask for your passphrase)
+ - Creates LVM
+ - Restores all files
+ - Installs the bootloader
+5. Reboot into your restored system
+
+** When to Regenerate the ISO
+
+- After major system changes (new partitions, bootloader changes)
+- Monthly alongside your regular backups
+- After adding/removing LUKS keyslots
+
+** Verification (Montly)
+
+Create =/usr/local/bin/backup-verify=:
+
+#+begin_src bash
+#!/bin/bash
+set -euo pipefail
+source /root/.restic-env
+
+echo "=== B2 Snapshots ==="
+restic snapshots --latest 10
+
+echo ""
+echo "=== Repository Integrity (sampling 5%) ==="
+restic check --read-data-subset=5%
+
+echo ""
+echo "=== Repository Size ==="
+restic stats
+
+echo ""
+echo "=== Rear ISO ==="
+ls -lh /root/rear-output/rear-*.iso 2>/dev/null || echo "WARNING: No Rear ISO found! Run: sudo rear -v mkbackup"
+
+echo ""
+echo "=== LUKS Header Backup ==="
+ls -lh /root/luks-header-backup 2>/dev/null || echo "WARNING: No LUKS header backup! Run the backup immediately."
+#+end_src
+
+
diff --git a/backup/ad3/backup-cloud b/backup/ad3/backup-cloud
new file mode 100755
index 0000000..82b5a1b
--- /dev/null
+++ b/backup/ad3/backup-cloud
@@ -0,0 +1,30 @@
+set -euo pipefail
+
+if [ "$(id -u)" -ne 0 ]; then
+ echo "Run with sudo"
+ exit 1
+fi
+
+source /root/.restic-env
+
+# Backup LUKS header into a location restic will pick up
+cryptsetup luksHeaderBackup /dev/nvme0n1p2 \
+ --header-backup-file /root/luks-header-backup.tmp
+mv /root/luks-header-backup.tmp /root/luks-header-backup
+
+# Run backup (/ and /boot since /boot is a separate partition)
+restic backup / /boot \
+ --exclude-file=/home/benj/.mycfg/backup/ad3/restic-exclude.txt \
+ --exclude-caches \
+ --verbose
+
+# Retention: 4 weekly, 6 monthly, 1 yearly
+restic forget \
+ --keep-weekly 4 \
+ --keep-monthly 6 \
+ --keep-yearly 1 \
+ --prune
+
+echo ""
+echo "=== Latest snapshots ==="
+restic snapshots --latest 5 \ No newline at end of file
diff --git a/backup/ad3/backup-cloud.service b/backup/ad3/backup-cloud.service
new file mode 100644
index 0000000..472ea75
--- /dev/null
+++ b/backup/ad3/backup-cloud.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=Restic backup to Backblaze B2
+Wants=network-online.target
+After=network-online.target
+
+[Service]
+Type=oneshot
+ExecStart=/home/benj/.mycfg/backup/ad3/backup-cloud
+Nice=19
+IOSchedulingClass=idle \ No newline at end of file
diff --git a/backup/ad3/backup-cloud.timer b/backup/ad3/backup-cloud.timer
new file mode 100644
index 0000000..e67bbfd
--- /dev/null
+++ b/backup/ad3/backup-cloud.timer
@@ -0,0 +1,10 @@
+[Unit]
+Description=Weekly cloud backup to B2
+
+[Timer]
+OnCalendar=Sun 02:00
+RandomizedDelaySec=1h
+Persistent=true
+
+[Install]
+WantedBy=timers.target \ No newline at end of file
diff --git a/backup/ad3/restic-exclude.txt b/backup/ad3/restic-exclude.txt
new file mode 100644
index 0000000..4d19e57
--- /dev/null
+++ b/backup/ad3/restic-exclude.txt
@@ -0,0 +1,77 @@
+# Virtual/temp
+/dev
+/proc
+/sys
+/tmp
+/run
+/mnt
+/media
+/lost+found
+/swapfile
+
+# Caches
+/var/lib/docker
+/var/cache/pacman/pkg
+/var/cache/man
+/var/cache/fontconfig
+/var/cache/fwupd
+/var/log/journal
+/var/lib/systemd/coredump
+/home/benj/.cache
+/home/benj/.local/share/Trash
+/home/benj/.local/share/Steam
+
+# Home caches and toolchains
+/home/benj/.rustup
+/home/benj/.cargo/registry
+/home/benj/.cargo/git
+/home/benj/.ghcup
+/home/benj/.stack
+/home/benj/.cabal
+/home/benj/.espressif
+/home/benj/.nvm
+/home/benj/.npm
+/home/benj/.virtualenvs
+/home/benj/.opam
+/home/benj/.gradle
+/home/benj/.m2
+/home/benj/go/pkg
+/home/benj/Android
+/home/benj/.android/avd
+/home/benj/.local/share/uv
+
+/home/benj/.config/Slack/Service Worker
+/home/benj/.config/Slack/Cache
+/home/benj/.config/chromium/Profile 1
+/home/benj/.config/chromium/Default/Service Worker
+/home/benj/.config/chromium/GrShaderCache
+/home/benj/.config/chromium/component_crx_cache
+/home/benj/.config/chromium/extensions_crx_cache
+/home/benj/.config/discord/Cache
+/home/benj/.config/discord/0.0.60
+/home/benj/.config/figma-linux/Code Cache
+/home/benj/.config/Insomnia/responses
+/home/benj/.config/Signal/attachments.noindex
+
+/home/benj/.claude
+/home/benj/Downloads
+
+**/target
+**/node_modules
+**/build
+**/CMakeFiles
+**/__pycache__
+**/.tox
+**/dist
+**/*.egg-info
+**/.gradle
+**/.cabal-sandbox
+
+/home/benj/.cabal
+/home/benj/.gradle
+/home/benj/.m2
+/home/benj/.nvm
+/home/benj/.virtualenvs
+/home/benj/.opam
+/home/benj/.npm
+/home/benj/.claude \ No newline at end of file