

Depends on what you consider self-hosted. Web applications I use over LAN include Home Assistant, NextRSS, Syncthing, cockpit-machines (VM host), and media stuff (Jellyfin, Kavita, etc). Without web UI, I also run servers for NFS, SMB, and Joplin sync. Nothing but a Wireguard VPN is public-facing; I generally only use it for SSH and file transfer but can access anything else through it.
I’ve had NextCloud running for a year or two but honestly don’t see much point and will probably uninstall it.
I’ve been planning to someday also try out Immich (photo sync), Radicale (calendar), ntfy.sh, paperless-ngx, ArchiveBox (web archive), Tube Archivist (YouTube archive), and Frigate NVR.
The command you’re looking for is
btrfs send
. Seeman btrfs-send
.I know of at least one tool, btrbk, which automates both automatic periodic snapshots and incremental sync, but here’s an example manual process so you can know the basic idea. Run all this in a root shell or sudo.
As initial setup:
btrfs subvolume create /mnt/mybtrfs/stuff
on the sender, substituting the actual mount point of your btrfs filesystem and the name you want to use for a subvolume under it.-o subvol=stuff
if you want to treat the subvolume as its own separate mount from its parent.mkdir /mnt/mybtrfs/snapshots; btrfs subvolume snapshot /mnt/mybtrfs/stuff /mnt/mybtrfs/snapshots/stuff-20250511
.btrfs send /mnt/mybtrfs/snapshots/stuff-20250511 | btrfs receive /mnt/backup
. You can runbtrfs receive
through SSH if the receiver is a separate system.For incremental syncs after that:
btrfs subvolume snapshot /mnt/mybtrfs/stuff /mnt/mybtrfs/snapshots/stuff-20250518
.-p
option to specify a subvolume of the last successful sync to make it incremental.btrfs send -p /mnt/mybtrfs/snapshots/stuff-20250511 /mnt/mybtrfs/snapshots/stuff-20250518 | btrfs receive /mnt/backup
.If you want to script a process like this, make sure the receiver stores the name of the latest synced snapshot somewhere only after the receive completes successfully, so that you aren’t trying to do incremental syncs based on a parent that didn’t finish syncing.