Skip to content

Floe

Floe is Frostyard’s headless server image. It is a Debian Trixie bootc/composefs image for x86-64 machines with UEFI, built from the same Base as the other Frostyard images, and it ships Podman. Use it for containers and services on a machine that has no desktop.

The system lives in a read-only /usr that updates as one piece, and you can roll back to the previous version. Your homes, container storage, and service data live under /var. Floe has no core Flatpak set.

Firn is the installer. It needs UEFI and erases the disk you pick. It works with or without Secure Boot, TPM 2.0, and disk encryption, and asks you about each one. Use a disk of at least 30 GiB, and more for container images, volumes, and several updates. The installer runs from RAM and needs at least 4.5 GiB of memory.

  1. Download the installer and its checksums:
  2. Check the signing key’s fingerprint and the ISO, then write the ISO to a USB stick. The installation guide has the exact gpgv and sha256sum commands and the commands to write the stick. Read its warning on picking the right device.
  3. Boot the stick. In Firn, pick the bootc Floe product, review the recipe Firn builds, and confirm the exact target disk.
  4. If Firn shows a recovery key, store it somewhere other than this disk before you continue.
  5. If Secure Boot is on, enroll the MOK when asked. Without it, the MOK-signed boot stage is not trusted while Secure Boot is enforced.

The native in the ISO address is an old folder name. It does not mean an A/B install.

Floe starts without a desktop. Log in on the console as the user you created in Firn, or over SSH. SSH is on by default: add your key in Firn.

Check that the system is healthy:

Terminal window
systemctl is-system-running
sudo bootc status
sudo snosi-update-status --check
systemctl list-timers bootc-update-stage.timer

systemctl is-system-running prints running when every unit has started, and degraded when a unit failed. bootc status shows the booted and staged deployments, and names the image it follows. If it shows null, see Troubleshooting. snosi-update-status --check tells you whether a newer image is published. The timer is listed with its next run.

Install workloads as containers or as system extensions. Do not install APT packages into /usr: an image update does not keep them. The image turns off the APT daily update and upgrade timers and services.

Updates are automatic. Every hour, bootc-update-stage.timer checks the followed image, pulls it with Podman, and stages a new version. The timer adds a random delay of up to 15 minutes. The new version starts at your next normal reboot. The stager does not force a reboot.

Enabled system extensions update on their own. A new version is staged and starts at the next boot. See Automatic updates.

The stager runs the bootc commands itself. You do not need to run them. On the first staged update, while the host does not yet follow the image from containers-storage, it runs bootc switch --transport containers-storage. From then on, in steady state, it runs bootc upgrade, because a second bootc switch to the same image would do nothing. Both paths verify the staged digest before they report success.

To go back to the previous version:

Terminal window
sudo bootc rollback
sudo systemctl reboot

Homes, container storage, and service data in /var are shared by all versions, so a rollback keeps them. After a rollback, the updater does not stage the version you rolled back from again. It waits for the next published image.

Keep about twice the image size free in /var. The updater pulls each new image into /var before it stages it.

Floe checks itself for problems 3 to 8 minutes after boot, then about every hour. It records:

  • a system service that failed
  • an image update that could not be staged
  • a system-extension update that failed
  • a boot into an older image
  • an encrypted disk that the TPM opened only after a retry, or that needed a passphrase or the recovery key
  • an integrity error
  • a crash of a system program
  • a problem that a Frostyard system service recorded

The records stay on this server.

List them:

Terminal window
snosi-health --list

Any user can run it. Each line shows when the problem was last seen, its kind, a short summary, how many times it was seen, and whether the record is a valid problem report. With no problems, it prints No problems recorded and the time of the last check. Before the first check, it prints No problem record yet. snosi-health --list sends nothing.

To check now instead of waiting for the next run:

Terminal window
sudo systemctl start snosi-health.service
snosi-health --list

systemctl list-timers snosi-health.timer shows the next run. Members of the sudo group can read the full unit names and up to 5 journal messages for each problem in /var/lib/snosi-health/details.json. If the command is missing, the image is older than this feature: let it update, then reboot.

Floe can send problem reports. Reporting is off until you turn it on. Each login shows Problem reporting is off. See `snosi-health reporting --help`. until you choose.

Any user can print the exact reports. This sends nothing:

Terminal window
snosi-health send --dry-run

Turn reporting on or off:

Terminal window
sudo snosi-health reporting on
sudo snosi-health reporting off

Any user can see the choice:

Terminal window
snosi-health reporting status

A timer sends once a day, at most 20 problems a day and 1 count a week. Crashes are never sent. /var/lib/snosi-health/sent.jsonl lists the sent reports, each with its report_id. A send run that posts at least 1 report and does not stop early drops the entries older than 90 days. Any other run drops nothing. A run that starts after reporting is turned off drops nothing. Only a run already in progress can still finish its cleanup. After that, the file keeps its entries until an administrator deletes it. On an older image, snosi-health reporting status prints the usage text: let it update, then reboot.

Read what a report holds and how to have one deleted in Problem reports. Read how Floe decides to send in snosi ADR-0030.

A crash keeps no core file. The journal keeps the crash entry. It has a stack trace only when the core is 1 GiB or smaller. To keep core files while you debug a crash, set Storage=external in /etc/systemd/coredump.conf.d/90-debug.conf:

[Coredump]
Storage=external

The image sets Storage=none in 50-snosi.conf, and the file that sorts last wins. Give your file a name that sorts after 50-snosi.conf.

Apply it before you reproduce the crash:

Terminal window
sudo systemctl reload systemd-coredumpd.service

If that service is not running, there is nothing to reload: each crash then reads the file. A reboot also applies it.

Floe is Base plus the bootc runtime, the bootc security setup, the server packages, a kernel, and the image output format.

Layer What you get
Base Debian Trixie userspace, systemd, the hourly update stager, Updex, and the system-extension definitions
Bootc runtime bootc, libostree-1-1, and the packages OCI bootc needs
Server tools systemd-container for systemd-nspawn and systemd-vmspawn, tuned, tuned-ppd, dbus-broker, and locales-all
Containers podman, distrobox, buildah, crun, fuse-overlayfs, slirp4netns, passt, and criu
Networking NetworkManager, OpenSSH, mDNS with avahi-daemon, IPv4 forwarding, the BBR congestion control, and larger inotify limits
Kernel linux-image-amd64/forky for now, with most firmware and Mesa from trixie-backports
Homebrew brew-setup.service, brew-update.timer, brew-upgrade.timer, bbrew-helper, and the CLI bundle at /usr/share/floe/bundles/cli.Brewfile
Logs A journal that keeps its logs on disk across reboots
Core Flatpak set None

Floe uses the linux-image-amd64/forky kernel until the Trixie backports kernel is complete. The build file for it is still called backports; the name is out of date. Most firmware and Mesa come from trixie-backports, pinned in the same file.

SSH, mDNS (Avahi), and tuned run by default. The image ships no enablement links in /etc; the presets enable these services at first boot.

brew-setup.service unpacks the Homebrew archive to /var/home/linuxbrew at first boot. The two brew timers update and upgrade an installed Homebrew. bbrew-helper installs bbrew when it is absent, then runs it. The CLI bundle lists the recommended command-line tools.

The initramfs includes the LVM, crypt, and bootc composefs modules, plus FIDO2, TPM2, PKCS#11, and PCR phase modules for encrypted disks.

Choose Floe for a headless server that runs containers and services. It has no desktop, no graphical session, and no core Flatpak set. Do not use it as a workstation. The other products are:

  • Snow: the general-purpose GNOME desktop.
  • Snowfield: GNOME for Microsoft Surface devices. It is untested on representative Surface hardware; its hardware gate was waived for catalog inclusion.
  • Sundog: KDE Plasma, bootc only.

Base is the shared foundation, not a fifth installer choice. Floe has the Trixie userspace with a newer kernel.

Podman, Distrobox, and Buildah are in the image. systemd-container adds systemd-nspawn and systemd-vmspawn, and Base ships the QEMU runtime that systemd-vmspawn uses.

Every image carries a definition for each system extension, switched off. The extension itself is not in the image: Updex turns it on and downloads it. Floe creates /var/lib/extensions for merged extensions. The extension catalog lists every extension and the Updex steps. Three extensions have a guide:

Symptom Check Fix
bootc status shows spec.image: null The host is not managed by bootc. It is most likely an old nbc or native A/B install. See Moving from an nbc or A/B install.
sudo snosi-update-status says published image equals the rollback deployment You rolled back, and no newer image is published yet Nothing to fix. The updater holds until a newer image is published.
No update is staged systemctl list-timers bootc-update-stage.timer and journalctl -u bootc-update-stage.service Wait for the hourly run. Check the network and the free space in /var.
Staging fails for lack of space Compare the free space in /var with the image size Free space or grow the disk. The updater needs room for the download, the new version, and the previous one.
A unit fails at boot systemctl --failed Read the unit’s log with journalctl -u <unit>, then correct the service or its configuration.
Secure Boot or TPM does not behave as you expect bootc status and the firmware settings Check the firmware settings, then read the Bootc Secure Operations runbook. Secure Boot is not production-ready yet.

Old nbc and native A/B installs get no new images or updates after 2026-09-30. There is no in-place conversion. Back up, install fresh with Firn, and restore your data.

The migration runbook lists what to save: your /etc changes, homes, Podman volumes, /var/lib/tailscale if you use Tailscale, and /var/lib/himmelblau and /etc/himmelblau if you use Himmelblau. Record which system extensions you enabled, so you can enable them again. Check the backup from another machine before you erase the disk.

Reviewed 2026-10-27 against snosi commit b2858ca0222814c395cf8248db98f3e096d57dc9.

The Problems section was reviewed 2026-11-05 against snosi commit b6e5e0769c605b920686c12bc7f0962caac10586.

The reporting part was reviewed 2026-11-05 against snosi commit a1bf8d2547ecdfe78941e910bf604a30bffe6945 (snosi#1227).

Privacy