Bases and the container builder
A base is a read-only template that every VM starts from: a patched guest kernel, a root filesystem image and a record of what the base is and what it supports. A VM never writes to its base. It gets its own disk layered on top, so many VMs can share one base and Reset disk to base… returns a VM to it.
This page describes Antinomie 0.8.0, which is in development. The current release is 0.7.1. What exists only in 0.8.0 is marked New in 0.8.0.
The three bases
Section titled “The three bases”| Base | For | Needs | Notes |
|---|---|---|---|
| BusyBox | Small command-line programs and quick tests | About 256 MiB RAM and 1 GiB disk | Tiny and fast to boot. A console guest; programs run in the app’s terminal. |
| Debian 13 Minimal (console) | Programs that need a real Debian userspace without a desktop | At least 1024 MiB RAM and 4 GiB disk | Debian 13 (trixie) as the Debian installer leaves it with no desktop chosen. Boots on BusyBox’s kernel. New in 0.7.1. |
| Debian 13 desktop | Programs that need a graphical session | About 4 GiB RAM and 16 GiB disk | Adds a desktop; programs can run in the guest desktop or a terminal on the VM screen. |
The sizes for BusyBox and the desktop base are the catalogue’s recommendations; real programs can need more. Debian Minimal’s minimum is enforced by the New VM dialog. Its bundle is about 890 MB.
Both Debian bases ask for a guest account (Username and Password) when
you create a VM, and set it up for that VM alone. Creating, resetting and
growing their disks needs guestfish (libguestfs-tools on Debian and
Ubuntu); Tools → App dependencies checks for it.
When you build the desktop base yourself, the wizard offers the desktops the
Debian installer offers: GNOME, Xfce, GNOME Flashback, KDE Plasma, Cinnamon,
MATE, LXDE and LXQt. A downloaded desktop base names its desktop in its
catalogue entry, for example Debian 13 (Xfce).
Getting a base
Section titled “Getting a base”Installed bases are listed on the Base images page: open Library → Base images in the sidebar. The page is a sortable table with each base’s status, size, the number of VMs using it and its guest. Above the table are Import base…, Download base… and Build base…; File → Add base offers the same. Select a base for New VM from this base…, Open directory or Delete base… (also on right-click). Deleting is refused while any VM still uses the base. See Library.
Download base…
Section titled “Download base…”Download base… opens the base catalogue: a list of published bases read
from the catalogue’s index.json on Hugging Face
(huggingface.co/buckets/MoreMorePwn/antinomie-bases). The Getting started
window reads the same catalogue on first launch, and Refresh catalog reads
it again.
- Bases for this app come first, under For Antinomie 0.8.0, then Other bases. Show older bases (N) adds bases built for earlier versions.
- Each row gives the base’s name and the Antinomie version it is for, its Linux version, its size, its minimum RAM and disk, and the first characters of its identity.
- Download fetches and installs it. A row already installed says
Installed. A base built for a newer Antinomie cannot be downloaded: its
button is disabled with
Built for a newer Antinomie. - One download runs at a time, with progress and Cancel above the list. A cancelled download keeps its files so the next attempt can resume.
Verification
Section titled “Verification”Each downloaded file is checked against the catalogue for its size and SHA-256 before the base is installed; the catalogue itself is fetched over HTTPS. Antinomie checks no signature on the catalogue. Bases you import or build are used as supplied.
A base’s identity is a hash over its files. When the app starts it checks the installed bases (Checking base images…), and before a VM starts it checks that VM’s base again. Files that have not changed since the last check reuse their recorded checksums, so the check is quick.
Import base…
Section titled “Import base…”Import base… installs a base bundle folder you already have, for example
one built on another computer. A base made for a newer app is refused, with
this base needs Antinomie X or newer (its recorded minimum app version) or
this base is for a newer Antinomie than this one (its guest revision); update
Antinomie first.
Build base…
Section titled “Build base…”Build base… builds a base with the app’s own build kit and installs the result. The guest kernel is compiled from the patch series this app carries, so a base you build always matches the app. A short wizard asks installer-style questions:
- Base: BusyBox (minimal), Debian 13 (minimal, console) or Debian 13 (desktop).
- Build mode: where the build runs (below).
- For Debian: Language and locale, Keyboard, Time zone, Software selection (the desktop, for the desktop base, and Standard system utilities) and Package mirror with an optional HTTP proxy that is not kept in the image.
- Hostname of the guest.
- Summary, then Build. The build shows its steps (kit and kernel source, patch kernel, compile kernel, memory analysis symbols, build image, install base) and its log; Cancel build stops it.
SSH servers, guest agents and cloud-init are never offered: the app talks to the guest only through its kernel. The wizard estimates time and space before you start:
| Base | Kernel not yet built | Kernel already built |
|---|---|---|
| BusyBox | About 10 minutes for the kernel, cached afterwards | Fast |
| Debian 13 Minimal | About 10 minutes, about 11 GiB free | About 6 GiB free |
| Debian 13 desktop | 1 to 2 hours, about 50 GiB free | About 20 GiB free |
Debian Minimal shares BusyBox’s kernel, so once that kernel is cached it builds in minutes.
Where the build runs
Section titled “Where the build runs”In 0.7.1 a base builds on this host or in a QEMU builder VM. 0.8.0 adds a container builder: Build mode offers Automatic plus four choices.
| Mode | What it needs | Notes |
|---|---|---|
| Native (on this Linux host) | The kernel and image tool suite on this host | Fastest. Debian Minimal builds natively only on a Debian 13 host (below). |
| Podman container | Podman | A pinned Debian 13 container. Rootless Podman needs no root access. |
| Docker container | Docker | The same container. Docker needs root-equivalent access (membership in the docker group). |
| QEMU builder | QEMU and curl |
A builder VM that downloads Debian’s cloud image once. Without KVM it can take many hours. |
Automatic takes the first that can run here: Native (only when the host’s toolchain is Debian 13’s), then Podman (rootless preferred), then Docker, then the QEMU builder. A choice that cannot run says why, for example no Debian 13 toolchain, the engine is missing, its daemon cannot be reached, you lack permission, or the image is not available.
The container image (antinomie-builder:<id>) is Debian 13 pinned by digest,
with every package at an exact version from a snapshot.debian.org timestamp.
It is built from the app’s Dockerfile the first time, which needs the network
once, and kept so later builds start at once. If Automatic cannot get it
(offline), it falls through to the QEMU builder and the log says why. The
Builder images section lists kept images with a Remove button. A build
leaves no container behind. From a shell, scripts/build-base.py --container
does the same.
Debian 13 Minimal in detail
Section titled “Debian 13 Minimal in detail”Debian Minimal is meant to look like a Debian 13 machine someone installed, not like a sandbox image. Since 0.7.1:
- Packages are what the Debian installer installs with no desktop: the standard system utilities with recommends (exim4 for local mail, timesyncd, lsof, dig, man pages and documentation), tasksel and its language task. There is no desktop, display manager or SSH server. APT and the package indexes stay.
- Nothing names Antinomie or the build host. The build fails if such a trace comes back. Files keep the times their installation gave them, and the filesystem’s history reads like an installer’s.
- Per VM: each new or reset VM gets its own root filesystem UUID, directory
hash seed and machine ID. The account gets the installer’s groups and is
hashed by the guest’s own
chpasswd, so it is stored as Debian 13 stores it (yescrypt); the password never sits in a file on the disk. - Disk: partitioned as the installer does it (MBR, root at 1 MiB, a swap
partition sized for the VM’s RAM), with GRUB’s Debian command line
(
root=UUID=…,ro quiet). The root is mounted by UUID, so a stealth profile can put the disk on SATA or NVMe. /bootholds Debian’s genuinelinux-image-6.12.94+deb13-amd64andlinux-image-amd64packages, checked against Debian’s signed archive index, sodpkg --verifyreports nothing. QEMU boots the Antinomie kernel directly; the guest does not hold it anywhere.- Network: the address comes from ifupdown and dhcpcd on the interface the
stealth profile’s machine would have:
enp0s31f6for the Intel desktops and laptops with an I219,eno1for the Supermicro servers,enp0s25otherwise. See Stealth profile.
0.8.0 goes further:
- A UEFI PC’s disk for UEFI VMs. New in 0.8.0
A Debian Minimal VM whose stealth profile boots UEFI gets GPT with an EFI
system partition, GRUB for UEFI and the shim installed as the Debian
installer installs them (no
grub-pc),/boot/efiinfstab, and adebianboot entry first in the VM’s firmware. The app lays this disk out once per base, beside it, for the base’s first UEFI VM: a progress window shows the steps, and it needs about the base’s size in free space (it is refused cleanly without the room). Later UEFI VMs share it; BIOS VMs are unchanged. This needs a base built by 0.8.0. An existing VM’s firmware cannot be switched between BIOS and UEFI; create a new VM instead. - GRUB’s boot code on the disk. New in 0.8.0
Provisioning runs
grub-installas the installer does, so the VM’s MBR and/boot/grubhold GRUB (and debconf its install device) instead of an empty boot sector. - Debian’s exact kernel banner. New in 0.8.0
/proc/versionmatches the banner of Debian’s own/boot/vmlinuzexactly, down to the compiler and linker versions (gcc-14 14.2.0-19, binutils 2.44). Debian Minimal therefore builds natively only on a Debian 13 host; elsewhere Automatic builds it in the container or the QEMU builder, and the build fails if the banner differs./boot/System.mapstays Debian’s placeholder, as on every Debian install. - An installed system’s initramfs. New in 0.8.0
Each VM’s
/boot/initrd.img-*names its own resume device (the swap partition’s UUID, ornone), with the installed disk’s device and inode numbers instead of the build machine’s. The base’s initramfs carries Debian’s modules again. The modules need a new base; the resume device needs this app’s provisioning. - Kernel BTF. New in 0.8.0 The BusyBox and
Debian Minimal kernel provides
/sys/kernel/btf/vmlinuxand module BTF like Debian’s, so systemd’sbpf-restrict-fsno longer fails at boot and eBPF tooling finds what it expects. The recorder’s own types and functions are removed from it. The desktop kernel’s BTF no longer names the recorder either. Building the kernel now needspahole(dwarves).
Which bases an app runs
Section titled “Which bases an app runs”Each base records the app version that built it, the oldest app version that can run it, and its guest revision: the version of the contract between the guest kernel and the app. Each app version speaks one revision and runs every older base, without the features the older guest lacks. It refuses to import, download or start a base whose revision, or minimum app version, is newer than its own.
| App | Revision of its bases | Bases it runs |
|---|---|---|
| 0.7.1 (current release) | 17 | Revision 17 as Current; 16 and older as Outdated |
| 0.8.0 (in development) | 18 | Revision 18 as Current; 17 and older as Outdated |
A 0.7.x base (revision 17) keeps working under 0.8.0. What it lacks are the revision-18 records New in 0.8.0:
- the real position of each read and write in a file, and the operands of
sendfile,splice,copy_file_range, reflink clones andfallocate, so appends and shared descriptors land at their real offsets in Per-file history; - writes through shared file mappings (
MAP_SHARED), written back bymsyncor dropped bymunmap,execor exit; - typed layouts for group lists, directory entries and LDT reads in the Syscall Trace.
The Debian Minimal changes above that say they need a new base, and kernel BTF, also need a base built by 0.8.0. Bases built before 0.7.0 (revision 16 and older) still use the temporary resource collector described in Stealth profile.
Updating the app never replaces an installed base or a VM’s disk: existing VMs keep their pinned base. To use a new base, create a VM from it, or keep the old VM when you need its installed software or history. See Compatibility and Upgrading.