Install, update, and roll back
This guide is the one procedure for every Frostyard image. Use it to install with Firn, to check that updates arrive, to update by hand, to roll back, and to leave an old nbc or A/B install. What each image ships stays on its own page.
Choose an image
Section titled “Choose an image”Firn offers four images: Snow, Snowfield, Sundog, and Floe. Each page says what the image is for and what it ships. Base is the shared foundation, not a choice. The documentation index lists everything else.
Download and check Firn
Section titled “Download and check Firn”Firn needs UEFI and erases the disk you pick. Use a target disk of at least 30 GiB, and a larger one if you can: applications, containers, Flatpaks, homes, and updates all use disk space. The installer runs from RAM and needs at least 4.5 GiB of memory. Back up what you need, and read the backup from another machine before you boot the installer.
-
Download the installer ISO:
Terminal window curl -fL \https://repository.frostyard.org/isos/native/v1/snosi-installer-latest-x86-64.iso \-o snosi-installer.isoThe
nativein the address is an old folder name. It does not mean an A/B install. The file is saved assnosi-installer.iso. -
Download the signed checksums and the signing key, and check the key’s fingerprint:
Terminal window base=https://repository.frostyard.org/isos/native/v1curl -fL "$base/SHA256SUMS" -o SHA256SUMScurl -fL "$base/SHA256SUMS.gpg" -o SHA256SUMS.gpgcurl -fL \https://raw.githubusercontent.com/frostyard/snosi/main/shared/native-ab/keys/import-pubring.gpg \-o snosi-native-update-pubring.gpgfingerprint="$(gpg --batch --show-keys --with-colons snosi-native-update-pubring.gpg |awk -F: '$1 == "fpr" { print $10; exit }')"test "$fingerprint" = F37282A35CB6BDFEBFC8FE775A2EAC5C8216FD68The
testcommand prints nothing and exits 0 when the fingerprint matches. -
Check the signature, then check the ISO against it:
Terminal window gpgv --keyring ./snosi-native-update-pubring.gpg \SHA256SUMS.gpg SHA256SUMSexpected="$(awk '$2 ~ /^snosi-installer_[0-9]{14}_x86-64\.iso$/ {print $1exit}' SHA256SUMS)"test -n "$expected"printf '%s %s\n' "$expected" snosi-installer.iso |sha256sum -c -gpgvreports a good signature, andsha256sumprintssnosi-installer.iso: OK. Stop if the fingerprint, the signature, or the checksum fails. Download the files again before you try once more.
Write and boot the installer
Section titled “Write and boot the installer”Use a disk-imaging tool’s Restore Disk Image operation, or write the ISO from
a Linux terminal. The target is the whole USB device, such as /dev/sdb, not
a partition such as /dev/sdb1.
-
Insert the USB drive and find it by size, model, and serial:
Terminal window lsblk -o NAME,PATH,SIZE,MODEL,SERIAL,TRAN,MOUNTPOINTSYour USB drive is in the list. Unmount every mounted partition on it.
-
Write the ISO:
Terminal window ISO=snosi-installer.isoDISK=/dev/sdX # replace with the whole disposable USB devicetest -f "$ISO"test -b "$DISK"lsblk -o NAME,PATH,SIZE,MODEL,SERIAL,TRAN,MOUNTPOINTS "$DISK"sudo dd if="$ISO" of="$DISK" bs=4M status=progress conv=fsyncsyncThe last
lsblkshows the USB drive you expect, andddends with a byte count.ddoverwrites the device for good, so stop if thatlsblkshows any other drive. -
Reboot and open the firmware’s one-time boot menu. Pick the UEFI entry for the USB drive, not the disk you will install onto.
The boot menu waits 5 seconds, then starts the default entry, Install snosi (console). It runs Firn as a terminal wizard. Pick Install snosi (graphical) for Firn’s graphical installer. It falls back to the terminal wizard when the machine has no usable display.
Install with Firn
Section titled “Install with Firn”Firn runs on the local display. The terminal wizard also runs on the serial
console (ttyS0), so you can install a headless machine over serial. Run only
one installation at a time.
-
Pick the image you chose.
-
If the image or the optional applications must be downloaded, connect the network first. The installer has NetworkManager, so
nmcliworks from the console. -
Pick the target disk. Firn lists each disk by path, model, serial, size, and transport. It refuses the installer drive, mounted or ambiguous disks, and disks too small for the image.
-
Pick the filesystem. Then choose encryption, TPM use, and MOK enrollment, as far as Firn offers them for your hardware. A TPM can open the disk on its own. Without a TPM, pick a passphrase or recovery-key mode.
-
Set the hostname, locale, timezone, and keyboard. Add SSH keys if you want them, create the first user, and choose system Flatpaks if you want them.
-
Read the recipe Firn shows. Type the exact path of the target disk to confirm the erase. A wrong path stops the install before anything is written.
-
Wait for the install to finish. Firn checks the image against the Frostyard Cosign key before it writes the disk. If Firn shows a recovery key, copy it to a password manager, to separate removable media, or to paper before you close the screen. If you lose both TPM access and the recovery key, you can lose the data on an encrypted disk.
-
Reboot and remove the USB drive.
The new system starts. If you chose MOK enrollment, the blue MokManager screen comes first.
Enroll the MOK
Section titled “Enroll the MOK”If Secure Boot is on and you chose MOK enrollment, MokManager appears on the first boot:
- Press a key before the countdown ends.
- Choose Enroll MOK.
- Choose Continue, then Yes.
- Enter the one-time MOK password you set in Firn.
The machine reboots and starts Frostyard. Without the enrollment, the boot stage that the MOK signs is not trusted while Secure Boot is on.
After installation
Section titled “After installation”Log in as the user you created. Check the system:
systemctl is-system-runningsudo bootc statussudo snosi-update-status --checksystemctl list-timers bootc-update-stage.timersystemctl is-system-runningprintsrunning. It printsdegradedwhen a unit failed: runsystemctl --failed.bootc statusnames the image the machine follows. If it names none, see Troubleshooting.snosi-update-status --checkprints aRegistry:line. It ends withthis machine is currentwhen no newer image is published.- The timer is listed with its next run.
How updates arrive
Section titled “How updates arrive”Every image runs bootc-update-stage.timer. It fires every hour, with a random
delay of up to 15 minutes. A run that the machine missed while it was off
starts at the next boot. Each run does this:
- Prunes the Podman transfer cache, then pulls the image the machine follows.
- Stops if the pulled image is already running or already staged.
- Stops if the pulled image is the one you rolled back from. See Roll back.
- Stages the new version with bootc, and checks that bootc staged the image it pulled.
The staged version starts at your next normal reboot. The stager does not
force a reboot. Keep about twice the image size free in /var, because the
pull lands there first.
Check the state:
sudo snosi-update-statussudo snosi-update-status --pkg-diffjournalctl -u bootc-update-stage.servicesnosi-update-status needs root. Its output starts like this:
Running: snosi <version>Following: <image>Last check: up to date (<time>)The Running: line has your version, and Following: has the image you
installed. The Last check: line is one of:
| You see | It means |
|---|---|
up to date |
The running image is the published one. |
update to <version> staged |
A new version is staged. A Staged: line follows and ends with reboot to apply. |
published image equals the rollback deployment |
You rolled back, and no newer image is published yet. |
FAILED |
The last run failed. Read the journal command above. |
none recorded this boot |
The timer has not run since the boot. |
--pkg-diff lists the Debian package changes between the running and the
staged image. --check also queries the registry and compares versions.
You get the same news in two other places:
- On a login to a headless machine, the message of the day says
A system update is stagedand names the digest, or says the last check failed. - On a desktop, a notification titled
System update readyappears once for each staged update.
The check result lives in /run/snosi, so a reboot clears it until the next
run.
System extension updates
Section titled “System extension updates”Enabled extensions update on their own: a new version is staged and starts at the next boot. See Automatic updates. To stop the automatic updates on a machine, run:
sudo systemctl mask --now updex-update.timerUpdate now by hand
Section titled “Update now by hand”Run the stager yourself instead of waiting for the timer:
sudo systemctl start bootc-update-stage.servicesudo snosi-update-statusThe first command returns when the pull and the staging are done. The second
shows update to <version> staged and a Staged: line. If it shows
up to date, there is nothing new.
Do not run bootc upgrade by hand. It does not pull a new image: it only
stages what is already in local storage, and it skips the update status record.
Then apply the update:
sudo systemctl rebootAfter the reboot, sudo bootc status shows the new version as the booted
deployment.
Roll back
Section titled “Roll back”Roll back to the previous version:
sudo bootc rollbacksudo systemctl rebootAfter the reboot, sudo bootc status shows the previous version as the booted
deployment. Your data in /var (homes, Podman, the journal) is shared by all
versions, so a rollback keeps what you wrote after the update.
The updater does not stage the version you rolled back from again. The next
hourly run records published image equals the rollback deployment in
snosi-update-status. A headless login says an update is available but not
applied. The updater stages the next published image as usual.
bootc rollback does not change your system extensions. They stay in /var
and merge again on the older image. bootc rollback creates no extension
rollback hold. Enabled extensions keep their normal updates, subject to their
own rollback holds and to the image requirement. An extension
built for a newer image can fail on an older one. If it does, roll it back,
stop its updates, or remove it, as in
Roll back an extension.
Move from an nbc or A/B install
Section titled “Move from an nbc or A/B install”Old nbc and native A/B installs got no new images or updates after 2026-09-30. An nbc host cannot convert to bootc in place: it has no bootc deployment to adopt. You back up, install fresh with Firn, and restore.
The bootc install and single-hop updates are tested in QEMU/KVM. Update chains of three or more hops, power loss during an update, and a two-week soak on real hardware are not tested yet. Move one machine first, and keep its backup for longer.
Find out what you have
Section titled “Find out what you have”Run these on the host:
bootc status --format json | jq .spec.imagegrep -o 'composefs=[^ ]*' /proc/cmdline- A bootc install prints the image reference, and the second command prints
a
composefs=value. - An nbc install prints
null, and the second command prints nothing.
An old image can also show an end-of-life notice at login. If you have a bootc install, you have nothing to move: stop here.
Back up first
Section titled “Back up first”The reinstall erases the target disk. Save these to storage that is not the target disk:
| What | Where | Note |
|---|---|---|
Your /etc changes |
Archive /etc, or diff it against /usr/etc |
On the new system, restore only the changes: hostname, NetworkManager profiles, your own config files. Do not copy the old /etc over the new one. |
| Machine identity (optional) | /etc/ssh/ssh_host_*, /etc/machine-id |
Keep them only if you need the same SSH host keys or machine ID. Otherwise the first boot makes new ones. |
| Homes and app data | /var/home, and the data directories your services use |
/home is a bind to /var/home. |
| Podman | Named volumes (podman volume export), the image list, Quadlet and systemd units |
Images can be pulled again. Volumes cannot. |
| Tailscale | /var/lib/tailscale |
With it, the node keeps its identity. Without it, run tailscale up and authorize the node again. |
| Himmelblau and Entra | /var/lib/himmelblau, and /etc/himmelblau if you changed it |
Without them, join Entra again and enroll cached credentials again. |
| Enabled system extensions | ls /etc/sysupdate.* |
Extensions start switched off. Write down which ones you enabled. |
| Other changes | Crontabs, timers you added, anything you installed by hand | A hand-installed package does not survive. Put it in a system extension or reinstall it. |
Read the backup from another machine before you go on.
Nothing on the host changes until the installer writes the disk, so you can power off before that and lose nothing. After the write starts, there is no way back to the old system on that disk. If you cannot accept that, image the disk first, or install onto a replacement disk and keep the old disk.
Reinstall and restore
Section titled “Reinstall and restore”- Follow Download and check Firn through
Install with Firn. Pick a current image. Older
variants such as
snowloadedare not offered. - Restore the data in
/var: homes into/var/home, Podman volumes, and app data. Keep the owners and UIDs the same as the users you created at install. - Restore your
/etcchanges only. Usehostnamectl set-hostname,nmcli, or a drop-in file in preference to a copied directory. - Restore
/var/lib/tailscale, or runtailscale up. Restore or rejoin Himmelblau. - Enable your system extensions again with Updex. Then
check them with
systemd-sysext status. - Recreate your Podman workloads from the volumes and unit files, and pull the images.
Check that the host is migrated:
sudo bootc statussystemctl is-system-runningsystemctl --failedsystemctl list-timers bootc-update-stage.timerjournalctl -u bootc-update-stage.servicebootc status shows an image reference, not null. is-system-running
prints running, and --failed lists 0 units. The timer shows a next run.
After its first run, the journal says the update was pulled or that there is
nothing to stage.
Last, check your workloads: login and home contents, Tailscale, Entra sign-in, Podman services, and the merged extensions.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Check | Fix |
|---|---|---|
bootc status --format json | jq .spec.image prints null |
The host is not managed by bootc. It is an old nbc or native A/B install. | See Move from an nbc or A/B install. |
| The fingerprint, the signature, or the checksum fails | The download is damaged or is not the published one | Stop. Do not write the ISO. Download the files again. |
snosi-update-status shows Last check: FAILED |
journalctl -u bootc-update-stage.service |
Check the network and the free space in /var, then update by hand. |
| Staging fails for lack of space | Free space in /var against the image size |
Free space or grow the disk. Keep about twice the image size free. |
| No update is staged | systemctl list-timers bootc-update-stage.timer |
Wait for the next hourly run, or update by hand. |
snosi-update-status shows published image equals the rollback deployment |
You rolled back, and no newer image is published | Nothing to fix. The updater waits for the next published image. |
| The machine does not trust the boot stage with Secure Boot on | The MOK enrollment | The MOK-signed stage is not trusted without the enrollment. See Enroll the MOK. |
See also
Section titled “See also”- Install a Frostyard image
- Snow
- Snowfield
- Sundog
- Floe
- Base
- Updex
- nbc to bootc migration runbook
- Bootc Secure Operations runbook
Sources
Section titled “Sources”Reviewed 2026-10-27 against snosi commit
b2858ca0222814c395cf8248db98f3e096d57dc9
(tag 2026-10-26.7).
README.mddocs/installing.mddocs/nbc-to-bootc-migration.mddocs/2026-07-03-bootc-migration-record.mddocs/bootc-secure-operations.mddocs/adr/0015-retire-native-ab-images-and-nbc-installs.mddocs/adr/0018-remove-native-ab-and-nbc-lanes.mdshared/native-ab/keys/import-pubring.gpgmkosi.images/base/mkosi.extra/usr/libexec/bootc-update-stagemkosi.images/base/mkosi.extra/usr/lib/systemd/system/bootc-update-stage.servicemkosi.images/base/mkosi.extra/usr/lib/systemd/system/bootc-update-stage.timermkosi.images/base/mkosi.extra/usr/lib/systemd/system-preset/04-bootc-update.presetmkosi.images/base/mkosi.extra/usr/bin/snosi-update-statusmkosi.images/base/mkosi.extra/usr/libexec/bootc-update-notifymkosi.images/base/mkosi.extra/etc/update-motd.d/86-bootc-update-staged- snosi
docs/design/sysexts.md - Updex ADR-0016
- Murbella’s review: extensions after
bootc rollback(frostyard-org#27)