Converted my daily driver to my vm/docker host. I assumed all my images would be included in timeshift’s snapshots, but… nope!
Fortunately I figured it out before I needed it. was testing my backups as part of prep for wiping everything and going to headless debian, found libvirt was missing.
Edit: Added rsync tag to reflect the comments section, which really deserves its own thread.


That’s the reason why I chose to learn rsync. I was frustrated with Timeshift. It failed to restore some changes multiple times. It gave me issues with docker. It also had default excludes that were annoying to change as well.
I then learned how to make a complete system backup with rsync itself.
/,/boot/and/boot/efi/has to be done on separate rsync commands. Basically one command per partition.A restore involves flipping the source and destination in the rsync command. It also allows me to boot into a live USB and perform a restore in the event that I really mess up and can’t perform a restore normally through the installed OS.
By leaving behind the GUI, I got a lot more flexibility. It’s also a lot more reliable and I’ve had a lot less restore issues.
I was looking into this recently and un-convinced myself that rsync was handling all the symlinks and permissions correctly.
What’s your command options? I was using
-Prvtzfor ages, then thought I needed anAatoo (from memory)I’m going to post all the commands I use because I think that may be easier to follow. All the commands I’m posting will include the
--dry-runoption so if anyone tries to copy/paste this into their terminal, no actions will be taken. Instead it will show you what is going to happen if you ran the command without any changes.As I mentioned before, each partition will require it’s own command. The easiest way is using
lsblk. Below is my current setup and here you can see I have 5 partitions. One partition is aswapso I will only be working with 4 partitions,/,/boot,/boot/efiand/home:It’s good to first check what partitions you are using. My Raspberry Pi’s (ARM) only have
/and/bootfor example.The following
rsynccommands are what I use to make a complete backup of my system. I do exclude a number of directories because they are for temporary stuff like ram, processes or even devices/drives. It’s also important to exclude the specified backup directory to avoid recursing into the backup directory and filling up your storage space.I have a manual backup location and automated backup location. The following is for my manual backup location in
/backup/mainon my system. This location can be changed to wherever you want your backup.# Backup # / rsync --dry-run --archive --acls --one-file-system --xattrs --hard-links --sparse --verbose --human-readable --partial --progress --numeric-ids --delete --exclude=/backup/* --exclude=/boot/* --exclude=home/* --exclude=proc/* --exclude=sys/* --exclude=dev/* --exclude=tmp/* --exclude=run/* --exclude=mnt/* --exclude=media/* '/' '/backup/main/' # /boot/ rsync --dry-run --archive --acls --one-file-system --xattrs --hard-links --sparse --verbose --human-readable --partial --progress --numeric-ids --delete --exclude=lost+found '/boot/' '/backup/main/boot/' # /boot/efi/ rsync --dry-run --archive --acls --one-file-system --xattrs --hard-links --sparse --verbose --human-readable --partial --progress --numeric-ids --delete --exclude=lost+found '/boot/efi/' '/backup/main/boot/efi/' # /home/ rsync --dry-run --archive --acls --one-file-system --xattrs --hard-links --sparse --verbose --human-readable --partial --progress --numeric-ids --delete --exclude=lost+found --exclude=.cache/* '/home/' '/backup/main/home/'rsyncrestore commands# Restore # / rsync --dry-run --archive --acls --one-file-system --xattrs --hard-links --sparse --verbose --human-readable --partial --progress --numeric-ids --delete --exclude=/backup/* --exclude=/boot/* --exclude=home/* --exclude=proc/* --exclude=sys/* --exclude=dev/* --exclude=tmp/* --exclude=run/* --exclude=mnt/* --exclude=media/* '/backup/main/' '/' # /boot/ rsync --dry-run --archive --acls --one-file-system --xattrs --hard-links --sparse --verbose --human-readable --partial --progress --numeric-ids --delete --exclude=lost+found '/backup/main/boot/' '/boot/' #/boot/efi/ rsync --dry-run --archive --acls --one-file-system --xattrs --hard-links --sparse --verbose --human-readable --partial --progress --numeric-ids --delete --exclude=lost+found '/backup/main/boot/efi/' '/boot/efi/' # /home rsync --dry-run --archive --acls --one-file-system --xattrs --hard-links --sparse --verbose --human-readable --partial --progress --numeric-ids --delete --exclude=lost+found --exclude=.cache/* '/backup/main/home/' '/home/'It’s been a while since I last researched these options so I’ll give a brief explanation of the types of options I used. I’d suggest having a look online or at the
manpage to get a better idea of what each option does.Options:
--dry-runOnly displays whatrsyncwill do, remove this once you are ready to commit any syncs/changesarchive --acls --one-file-system --xattrs --hard-links --sparseHelps preserve file attributes and other information. I think hard-links is also used to reduce backup size. There are manyrsyncguides that will give a better explanation of how hard-links workverbose --human-readable --partial --progresswill display visual data about whatrsyncwill do--numeric-idsI use this because I store multiple device backups on a single drive which gets copied to other storage devices. This stores file ownership information as numeric values to prevent ownership issues when restoring--deletethis will force the destination directory to match the source directory completely. If you delete a file from the source directory, when you perform a sync, it will delete the same fie in the destination directory. This can be dangerous if you are not prepared for it. This is why--dry-runis so important and useful.Extra options: My automated scripts use 2 additional options. I keep a rolling set of 4 backups (One month of weekly backups). I create a new directory
/backup/updatingand use a symlink from/backup/latestthat points to the most recent automated backup. After the backup is created, I rename/backup/updatingto something with a timestamp like/backup/backup_2026-07-01_1782882013--mkpathwill create any non existing directories specified in the command--link-dest=/backup/latest/will use the unchanged files from this directory to help reduce backup sizes. I think this is called an incremental backupThis has been the most reliable way to handle backups for myself. I do run into issues with
docker/podmancontainers sometimes and will have to manually delete those directories. I haven’t figured out how to deal with that issue yet but fortunately it’s easy to find those directories. Running the command will give errors about what directories can’t be removed which makes it easy to hand delete them in another terminal window.