Snow Linux

Modern Atomic Linux

mkosi · bootc* · systemd-sysext

Snow is Not Only Windows

The State of Linux Desktops

Traditional Approach

  • Mutable root filesystem — any package can change anything
  • apt upgrade can leave you in a broken, half-applied state
  • Config drift across machines is inevitable
  • No rollback after a bad update
  • "Works on my machine" — hard to reproduce

What We Want

  • Reproducible builds from declarative configs
  • Atomic updates — all or nothing
  • Instant rollback to the previous version
  • Identical images across every machine
  • Separation of OS from user state
  • Most apps are installed in userspace

What If Your OS Worked Like Containers?

You already know the pattern — immutable images, versioned deployments, declarative configs. Apply it to the OS itself.

Container Image

Dockerfile defines layers. docker pull to deploy. docker rollback if broken.

Same Idea

Declarative config defines the OS. Pull an OCI image to update. Reboot into the previous image if broken.

Read-only /usr

The OS image is read-only. User data lives separately. Updates swap the entire image atomically.

"Treat your OS like a container — build it, ship it, version it, roll it back."

Enabling Technologies

Three systemd-era tools that make this possible

bootc* — Image-Based OS Deployment

A bootc-managed system treats the OS as a single OCI container image, pulled from a registry and booted directly.

How it works

  • OS images are standard OCI images stored in registries (ghcr.io, Docker Hub, etc.)
  • bootc switch pulls a new image and stages it for next boot
  • bootc rollback reverts to the previous image instantly
  • Uses systemd-boot and OSTree or ComposeFS for atomic updates

Why it matters

  • Atomic updates — no partial states, ever
  • Reproducible — same image hash = same system
  • Familiar workflow — push to a registry, pull to deploy
  • No package manager at runtime — the image IS the OS

bootc switch ghcr.io/frostyard/snow:latest  →  reboot  →  new OS

* bootc support for Linux variants outside the RHEL ecosystem is a work in progress

mkosi — Declarative Image Builder

mkosi builds bootable OS images from INI-style config files. Think "Dockerfile for real operating systems."

Key concepts

  • Declarative configs — INI files define packages, repos, scripts, and output format
  • ComposableInclude= directives chain fragments together
  • Profile system — build variants from shared components
  • Script pipeline — Build → PostInstall → Finalize → PostOutput

Outputs

  • Bootable disk images (GPT, raw, qcow2)
  • Directory trees (for OCI packaging)
  • System extensions (sysexts)
  • Initramfs / portable services

Supports Debian, Ubuntu, Fedora, Arch, openSUSE, and more.

systemd-sysext — Modular Extensions

System extensions overlay files onto /usr at runtime without modifying the base image.

How sysexts work

  • A sysext is a signed image containing files under /usr
  • systemd-sysext merges them into the live filesystem via OverlayFS
  • The base image remains untouched — extensions are additive
  • systemd-sysupdate handles versioned downloads and updates

Why this is powerful

  • Add Docker, Tailscale, or dev tools without rebuilding the base
  • Users pick their extensions — compose their own stack
  • Each extension is independently versioned and updated

docker

podman

dev

tailscale

1password-cli

incus

+ nix, emdash, debdev

Putting It Together

How snosi wires mkosi, bootc, and sysext into a build system

snosi (Snow + mkosi) Architecture

Base Image

Debian Trixie foundation with core packages, firmware, systemd-boot, and sysupdate metadata.

All images and sysexts build on this.

Desktop/Server Profiles

Compose base + kernel variant + GNOME desktop + optional extras into bootable OCI images.

cayo, cayoloaded, snow, snowloaded, snowfield, snowfieldloaded

Sysext Overlays

Independent extensions selected by user. Each adds tooling under /usr without touching the base.

docker, podman, dev, tailscale, nix, ...

Filesystem contract:/usr read-only  ·  /etc overlay (persists config)  ·  /var writable state  ·  /opt → /var/opt

Configuration Composition

mkosi's Include= directive lets snosi compose images from reusable fragments — like imports for your OS definition.

Directory structure

snosi/
├── mkosi.conf            # root: dependencies
├── mkosi.images/
│   ├── base/             # foundation image
│   ├── docker/           # sysext
│   ├── podman/           # sysext
│   └── ...
├── mkosi.profiles/
│   ├── snow/             # desktop variant
│   └── snowfield/        # Surface variant
└── shared/
    ├── packages/snow/    # package sets
    ├── kernel/backports/ # kernel config
    └── outformat/image/  # OCI packaging

How a profile composes

The snow profile includes:

  • shared/packages/snow/ — GNOME desktop packages
  • shared/kernel/backports/ — kernel config
  • shared/outformat/image/ — directory output + OCI packaging
  • Build, postinstall, finalize, and postoutput scripts

snowfield swaps in shared/kernel/surface/ — everything else is the same.

The Build Pipeline

BuildScripts

in chroot

PostInstall

after APT

Finalize

cleanup

PostOutput

package

Desktop images → OCI

  • mkosi outputs a directory tree (not a tarball)
  • buildah mount + cp -a preserves SUID, xattrs, and capabilities
  • Pushed to ghcr.io with cosign signatures
  • CI smoke-tests SUID on /usr/bin/sudo

Sysexts → Frostyard repo

  • mkosi outputs sysext .raw images
  • Postoutput script extracts version from package manifest
  • Renamed: docker_27.5.1_13_x86-64.raw.zst
  • Published to Cloudflare R2 with GPG signatures

What snosi Produces

4 Desktop Images

snow

GNOME + backports kernel

snowloaded

snow + dev tools, VSCode, Edge

snowfield

GNOME + Surface kernel

snowfieldloaded

snowfield + dev tools

Pushed to ghcr.io · Deployed via bootc* switch

2 Server Images

cayo

server

cayoloaded

server + virt and extras

Pushed to ghcr.io · Deployed via bootc* switch

9 System Extensions

docker

podman

dev

debdev

tailscale

1password

incus

nix

emdash

Published to Frostyard repo · Updated via updex

Frostyard Tooling

nbc · updex · intuneme · repogen

nbc — Not BootC *stop-gap*

nbc installs bootc-compatible OCI images directly to physical disks — no bootc command required.

What it does

  • Partitions disk with A/B root layout for atomic updates and rollback
  • Pulls OCI images using built-in Go libraries — no container runtime needed
  • Extracts rootfs, installs bootloader, configures /etc overlay persistence
  • nbc update installs to the inactive partition, reboot to switch

Key features

  • LUKS2 encryption with optional TPM2 auto-unlock
  • Secure Boot chain with shim detection
  • /etc overlay — user config persists across A/B updates via OverlayFS
  • Image linting — checks for bootc compatible layout before install

nbc install --image ghcr.io/frostyard/snow:latest --device /dev/nvme0n1

updex — Sysext Update Manager

updex manages systemd-sysext images — a systemd-sysupdate replacement for distros that don't ship it (like Debian Trixie).

Feature-based management

  • Reads standard .transfer and .feature config files
  • updex features enable docker --now downloads and activates
  • SHA256 verification via SHA256SUMS manifests
  • Optional GPG signature verification
  • Automatic decompression (xz, gz, zstd)

SDK-first architecture

  • Go library at updex/updex — import for programmatic control
  • CLI is a thin wrapper around the SDK
  • Automatic update daemon via systemd timers
  • Version retention with configurable InstancesMax
  • JSON output for scripting and integration

intuneme — Intune on Immutable Linux

intuneme runs Microsoft Intune inside a systemd-nspawn container on an immutable host — corporate compliance without compromising the OS model.

How it works

  • Provisions a systemd-nspawn container with Intune agent
  • Handles enrollment, compliance checks, and corporate resource access
  • Broker proxy for host-side SSO — Edge, VS Code, and other MSAL apps authenticate seamlessly
  • Device hotplug — YubiKey and webcam passthrough via udev rules

Desktop integration

  • GNOME Quick Settings extension for start/stop
  • Desktop shortcuts for Edge and Intune Portal
  • Full lifecycle: init, start, stop, destroy, recreate
  • Minimal host changes — everything stays in the container

intuneme init  →  intuneme start  →  enrolled and compliant

repogen — Universal Repo Generator

repogen generates static package repository metadata from a directory of artifacts — servable by any web server or object store.

Supported formats

Debian / APT

RPM / Yum

Alpine / APK

Arch / Pacman

Homebrew

systemd-sysext

How snosi uses it

  • CI builds sysexts → repogen generates SHA256SUMS and repo metadata
  • GPG-signed repositories published to Cloudflare R2
  • Auto-detects package types via magic bytes
  • Static output — no database, no server process
  • Used as a GitHub Action in the build pipeline

Why This Matters

Azure Relevance

Customers can build custom Linux images with simple, open tooling — and manage their own update cycle using cloud-native workflows they already know.

Build

Declarative mkosi configs in a Git repo. CI builds produce OCI images — same pipeline pattern as any containerized app.

Ship

Push to any OCI registry — ghcr.io, ACR, Docker Hub. Sysexts publish to static repos on blob storage. No special infrastructure.

Update

Atomic image swaps with instant rollback. Sysexts update independently. Customers own the cadence — no vendor-gated release trains.

GitHub Actions + OCI registries + object storage — the same cloud-native building blocks, applied to the OS layer

cayo — A Server Image Example

Same build system, no desktop. cayo is a headless server image built from the same base — showing how customers can target server workloads with the same tooling.

What's included

  • Podman + Buildah — container runtime baked in, no sysext needed
  • Distrobox — run any distro as a dev container
  • Server tuning — BBR congestion control, IPv4 forwarding, persistent mounts
  • CLI tooling — ripgrep, bat, gh, starship, chezmoi via Homebrew

cayoloaded variant

  • Everything in cayo, plus:
  • Docker — full docker-ce with buildx and compose
  • Incus — VM and container hypervisor for nested workloads
  • Ready for container orchestration and lightweight VM hosting

No GUI overhead

Same atomic updates

Same sysext overlays

Key Takeaways

 Reliability

Atomic updates eliminate "half-upgraded" systems. Every machine running the same image tag is identical. Rollback is one reboot away.

 Modularity

Sysexts let users compose their own toolchain without rebuilding the OS. Need Docker? Enable it. Don't? Leave it off.

 Reproducibility

Declarative mkosi configs, pinned downloads with SHA256 checksums, and CI-driven builds mean every image is traceable and repeatable.

 The Direction of Linux

Fedora (Silverblue/Kinoite), NixOS, and GNOME OS all point the same way. Immutable, image-based, systemd-native. This is where desktop Linux is heading.

snosi · github.com/frostyard/snosi