Backups
A frame is a snapshot stored on the same disk as the system, so it is not a backup. Frames help after a mistake such as a bad update or a deleted file. They are lost with the disk, with a damaged filesystem, with a stolen or destroyed machine, and when root deletes /run/scram/top/.scram. To make a real backup, you must copy frames to another machine with scram send, and copy the data that frames leave out.
What a frame contains
| In a frame | The subvolumes @ and @home: /etc with accounts, password hashes and SSH host keys, /var/log, the Nix store, the package profiles and lists in /rod, the containers, the services and every file in /home. The stream of scram send holds these and the frame id. |
| Not in a frame | The directories that are left out (by default /rod/nixpkgs, /var/cache, /var/tmp and any you added, such as ~/Downloads), the boot partition, other disks and filesystems, and memory (/tmp, /run). |
| Not in a stream | Also the note of the frame, its keep mark and the kernel copy. A received frame boots with the kernel of the boot partition. |
scram boot rebuilds the boot partition from the profile in @: the kernel, the initramfs, limine and the menu. Files you added to the partition yourself are lost. See boot.
The Nix store is part of @, so a full stream carries every installed package and is large. The index in /rod/nixpkgs is left out, and rod +s fetches it again after a restore.
What a flash does not undo
A flash returns @ and @home to a frame. Left-out directories, the boot partition, other disks and the LUKS header stay as they are. /etc/shadow returns too, so a password changed after the frame is the old one again, and users and home directories created after the frame are removed. Everything the flash replaced is in the pre-flash frame on the same disk.
The boot partition keeps the kernel it had. After a flash run scram boot so the menu and the kernels match the restored root.
Copy the data that frames leave out
Left-out directories are not in any stream. Directories you left out yourself, such as ~/Downloads or a database directory, need another tool like rsync. A running database needs its own dump, or a stop before the copy.
For an encrypted root, keep a copy of the LUKS header on another medium: cryptsetup luksHeaderBackup DEVICE --header-backup-file FILE. A damaged header makes the disk and every frame on it unreadable.
Send a frame
The stream is a tar archive with three members: id, the frame id, @.send, the output of btrfs send for @, and @home.send, the same for @home. It goes to standard output. Run it as root:
# scram roll
# scram send FRAME > full.tar
Send over ssh without a file in between:
# scram send FRAME | ssh backup@host "cat > /backup/full.tar"
scram writes both streams to a temporary directory, $TMPDIR or /tmp, before it packs the archive. On UraniumOS /tmp is a tmpfs of half the memory, so a larger stream fails with an error. Point TMPDIR at a directory on the disk with enough room:
# mkdir -p /var/tmp/send
# TMPDIR=/var/tmp/send scram send FRAME | ssh backup@host "cat > /backup/full.tar"
/var/tmp is a left-out directory, so the temporary files do not end up in your next snapshot.
The streams are not compressed or encrypted, even when the root is encrypted. They hold every file in the frame, including password hashes, SSH keys and home directories. Encrypt the archive before it leaves the machine, or send it only to storage you control.
Incremental streams
With -p the streams hold only what changed since a parent frame, so the stream is small:
# scram send -p FRAME1 FRAME2 > increment.tar
The parent must still exist on the sending side and must be the same snapshot that the receiving side holds. scram prune deletes automatic frames, so run scram keep FRAME1 on the frame you use as a parent first. A parent that does not exist gives an error.
Receive
scram receive reads the archive from standard input, creates .scram/ID and recieves both streams into it. The receiving machine needs btrfs, scram, a mounted top level and enough room in the temporary directory. It prints the id:
# scram receive < full.tar
20261102-165551-install
# scram receive < increment.tar
20261102-165552-kernel
Receive an increment after the frame it was made from. The recieved frame shows in scram roll and in the boot menu after the next scram boot. It has no note and no kernel copy.
On a machine without scram, unpack the archive and use btrfs receive. Receive each frame into its own directory, because the stream carries the subvolume names @ and @home:
$ mkdir /mnt/backup/FRAME
$ tar -xf full.tar
$ btrfs receive /mnt/backup/FRAME < @.send
$ btrfs receive /mnt/backup/FRAME < @home.send
The destination has to be a btrfs filesystem.
Restore
To go back to a frame that is still on the disk use scram flash FRAME or scram restore PATH FRAME, see scram.
To restore a received frame on a new or emptied disk:
- Install UraniumOS from the live medium. The installer erases the disk and creates the layout from storage.
- Run
scram receive < full.tar, and the increments in order. - Run
scram flash --boot FRAMEand reboot. The initramfs replaces@and@homewith the received frame and keeps apre-flashframe of the fresh install. - Run
scram bootso the menu and the kernels match the restored system, androd +sto fetch the package index. Copy the left-out directories back from your other backup.
The restored system has the hostname, accounts, SSH host keys and home directories of the machine the frame came from. If the new disk has a different layout, or the old system was encrypted, the labels and the kernel line in /etc/cmdline have to fit the new disk before scram boot.
Keep a frame
scram keep FRAME protects a frame from scram prune and from the hourly clean-up, which keeps the newest 48 automatic frames. Run it again to release the frame. A kept frame holds the blocks that differ from the live system, so they are not freed. See storage.