Backup and recovery
Raft exports portable workspace archives and restores them onto compatible hosts for disaster recovery, migration, or offline archiving.
Target workspace handle
Commands in this guide require a stopped workspace:
raft list
box="lab:rf-a1b2c3d4e5f60718" # Replace with your actual workspace handle
raft stop "$box"Exporting a backup
Specify a destination archive path on the controller:
raft backup "$box" ./my-workspace-backup.tar.gzraft backup exports container metadata, root filesystem, and snapshots into a gzip-compressed archive.
Security and storage requirements
Archives contain sensitive data
Backup archives contain the entire guest filesystem, including credentials, SSH keys, shell history, and private files. Native Incus archive configuration is not sanitized. Import only trusted archives created by Raft, and store backups on encrypted private storage off the source host for disaster recovery.
Raft enforces safeguards during export:
- Private permissions: Destination mode must be
0600. Group and world permissions must be zero before export begins. - Atomic link publication: After export and
fsync, Raft publishes the archive usingos.link(archive.name, destination). Hard-link support is checked at final publication rather than preflight; export can succeed while publication fails if the filesystem lacks hard-link support. - No overwriting: The destination file must not already exist.
- Lifecycle lock: Export holds
/run/lock/raft-incus.lock. Expiry checks for other containers on the host are delayed while the lock is held.
Recovering an archive
Import the archive onto the target location:
recovered=$(raft recover ./my-workspace-backup.tar.gz --location lab)
echo "Recovered workspace: $recovered"Recovery process details
- Architecture compatibility: Target host must match the native CPU architecture (ARM64 to ARM64, AMD64 to AMD64). Cross-architecture recovery is not supported.
- Fresh network identity: The container receives a new name in project
raft, a new MAC address onrfbr0, and no inherited TTL deadline. - Stopped initial state: Recovered workspaces remain stopped until started with
raft resume "$recovered" --ttl <SECONDS>. - Enforced admission limit: The destination location must hold fewer than four boxes.
- Interrupted recovery: Follow Host crash during recovery. Inspect the reported handle and container state before deleting any staging file.
Start and verify the recovered workspace:
raft resume "$recovered" --ttl 600
raft exec "$recovered" -- ls -la /workspaceCross-host migration workflow
Follow these steps to migrate a workspace to a second host:
1. Select and stop source workspace
raft list
source_box="lab:rf-a1b2c3d4e5f60718"
raft stop "$source_box"2. Export archive to local controller storage
raft backup "$source_box" ./migration.tar.gz3. Import archive onto destination host
target_box=$(raft recover ./migration.tar.gz --location second-host)4. Resume workspace on destination host
raft resume "$target_box" --ttl 18005. Verify application files and operations
raft exec "$target_box" -- ls -la /workspaceAfter verifying the recovered workspace, optionally destroy the source container:
raft destroy "$source_box"Preserve backup archives
Do not delete your local backup archive until you confirm that the destination workspace operates normally.