Comparison¶
| Tool | Authoring input | Runs code to build | Scope |
|---|---|---|---|
| contemper | any OCI image | no | image โ bootable disk |
| bootc | Containerfile on a bootc base |
yes (ostree) | image โ disk and in-place updates |
| d2vm | Dockerfile or a Docker image |
yes (docker build, chroot) |
image โ disk, several formats |
| Packer | provisioner scripts | yes (boots an instance) | broad; many clouds, Windows too |
| mkosi | declarative config and packages | yes (distro installers) | OS images, systemd-centric |
| distrobuilder | YAML definitions | yes | Incus/LXC images |
| virt-builder | existing cloud image | yes | customizing existing images |
| KubeVirt containerDisk | pre-built disk image | no | transport only, not authoring |
bootc¶
The closest comparison is bootc, which validates the same thesis, that container-authoring ergonomics suit OS images, with real vendor backing. It differs in three ways that matter:
- Base images. bootc's base images are prescriptive: you start from one built for bootc. contemper accepts any base you install a kernel and init system into, Alpine and OpenRC included.
- Scope. Transactional in-place updates with
bootc switchare bootc's actual point. contemper has no image-based update mechanism of its own: it stops at producing a disk. A bootloader image can still be updated in place by the distro's package manager, but that is the guest's business, not contemper's. - Semantics. bootc's ostree-based conversion gives
atomically-upgraded-host semantics:
/usrread-only,/etcand/varmerged forward. contemper's default (UKI) gives container-like ones: a writable root that is kept across reboots and replaced on redeploy, with persistent data on volumes. Bootloader images can instead run as long-lived VMs, as in choosing a boot mode.
d2vm¶
d2vm is the closest in workflow: a Dockerfile or Docker image goes in, a VM disk comes out, from a Go CLI. The differences:
- Conversion model. d2vm detects the distribution from
/etc/os-releaseand supports Ubuntu, Debian, Alpine, CentOS, Rocky Linux and AlmaLinux; distroless images are not supported. Unless--rawis given, it installs a kernel, an init system and a bootloader into the image with per-distribution templates run throughdocker build. contemper is an authoring tool instead: the image brings its own kernel, initrd and init system, for any distro, and there is no template list. - What runs at conversion. d2vm builds the disk with loop devices,
partitioning tools and mounts, so it needs root, or runs itself in a
privileged Docker container. It installs GRUB by chrooting into the
image and running the image's
grub-install. contemper runs nothing from the image, andconvertneeds no root and no container runtime. - Boot and configuration. d2vm supports BIOS (syslinux, GRUB) and
UEFI (GRUB) and can set a root password, hostname, DNS,
/etc/hostsentries, network manager and kernel command line at build time, and encrypt the root with LUKS. contemper is UEFI only, either a UKI it builds or the image's own bootloader, and keeps machine configuration in the image. - Output. d2vm writes qcow2, raw, qed, vdi, vhd or vmdk, and can
push a KubeVirt containerDisk image. contemper produces a bundle
(qcow2 plus
contemper.json), adds targets through support images, and hasdeploy.
The others¶
- Packer and virt-builder, in their common cloud-image workflow, start from an existing image that already has a kernel installed, and customize it by running code, either by booting an instance or through libguestfs. (Packer can also drive a full install from an ISO, which installs the kernel itself.) contemper builds the OS from your container build instead and runs nothing at conversion time.
- mkosi and distrobuilder also build an OS from packages, as contemper does, but through their own configuration formats and by running distro installers. contemper's input is whatever your container tooling already produces.
- KubeVirt containerDisk wraps a finished disk image in an OCI image as an opaque payload. It solves transport, not authoring.