Skip to content

Instantly share code, notes, and snippets.

@MrZoidberg
Created October 1, 2025 11:46
Show Gist options
  • Save MrZoidberg/dc38aae1f29cb9539acb9d61f868c149 to your computer and use it in GitHub Desktop.
Save MrZoidberg/dc38aae1f29cb9539acb9d61f868c149 to your computer and use it in GitHub Desktop.
Proxmox Host Backup script
#!/bin/bash
set -euo pipefail
# Configure where to store the backup and what to exclude, as it changes
# regularly and only contains ephemeral data.
if [ -f /etc/pve/local/pve-backup.env ] ; then
source /etc/pve/local/pve-backup.env
else
echo "File /etc/pve/local/pve-backup.env missing" > /dev/stderr
exit 1
fi
# Exclude list
# Use a trailing '#' to keep directory structure/permissions but exclude file data inside it.
exclude=(
'/bin'
'/boot'
'/dev'
'/lib'
'/lib64'
'/local-zfs'
'/lost+found'
'/mnt'
'/opt'
'/proc'
'/run'
'/sbin'
'/sys'
'/tmp'
'/usr'
'/var/lib/lxcfs'
'/dev/shm'
'/var/cache'
'/var/lib/rrdcached'
'/var/tmp'
'/var/lib/vz#'
'/var/log#'
)
# Convert the list of exclusions into command line arguments for the PBS client.
# Treat entries with trailing '#' specially (keep dirs, drop contents).
exdirs=
for ex in "${exclude[@]}"; do
base="${ex%#}"
# exclude files/dirs within the path
exdirs+=" --exclude ${base}/?*"
# if it had '#', also exclude deeper contents but keep the directory skeleton
if [ "$base" != "$ex" ]; then
exdirs+=" --exclude ${base}/**/?* --exclude !${base}/**/"
fi
done
# Take advantage of ZFS to create an atomic snapshot for backing up.
# We keep this snapshot around afterwards, as it is useful for quickly
# repairing accidentally damaged systems.
root="$(zfs list / | awk 'NR==2{ print $1 }')"
zfs destroy "${root}@backup" >&/dev/null || :
zfs snapshot "${root}@backup"
[ -d "/.zfs/snapshot/" ] || zfs set snapdir=visible "${root}"
# Backup our snapshot to the PBS server, excluding ephemeral/system data.
#set -f # pathname expansion is already controlled; keep disabled unless needed
proxmox-backup-client backup "proxmox-root.pxar:/.zfs/snapshot/backup" \
--change-detection-mode=metadata ${exdirs}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment