home > notes

Building and running machines with systemd-nspawn and mkosi on Debian Trixie

created: 2026-06-16

I’m interested in using systemd-nspawn and mkosi to shift workloads from k3s and virtual machines to systems just running systemd.

To build a bare bones systemd container:

$ mkdir test1
$ cd test1
$ mkosi \
    --distribution=debian \
    --include=mkosi-vm \
    --root-password=hashed: \
    build

--include=mkosi-vm includes the /usr/lib/python3/dist-packages/mkosi/resources/mkosi-vm/mkosi.conf config files and files within the mkosi.conf.d of the same directory for the build. These config file installs a set of base packages, depending on the --=distribution.

--root-password with a literal value of hashed: creates the root account as unlocked without any password.

On a Dell OptiPlex 7070, NVMe SSD and 32GB system, this took 1m14s.

The mkosi build command will produce a disk imaged based container called image.raw which can now be booted with systemd-nspawn. Using root as the username and no password (thanks to --root-password=hashed:) will get you a login shell.

$ sudo systemd-nspawn --image=image.raw  --boot 
[...]
root@image:~# uname -a && cat /etc/debian_version
Linux image 6.12.90+deb13-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.90-1 (2026-05-22) x86_64 GNU/Linux
13.5

To exit from the shell and kill the container press control+]]] (3 right brackets within 1 second of each other).

Config for mkosi can be created in mkosi.conf:

[Distribution]
Distribution=debian
Release=trixie

[Output]
Output=debian-stable-base
Format=disk
CompressOutput=zstd

[Content]
RootPassword=hashed:
Packages=
        systemd
        openssh-server
        apt

[Include]
Include=mkosi-vm

Building arm64 images on amd64

I mentioned that mkosi took 1m14s to build a minimal image but the same build took 17 minutes on a RaspberryPi 4 with a USB connected SSD.

mkosi supports building for different architectures. I found I needed to install qemu-user so that mkosi emulates arm64 when installing packages:

$ sudo apt install qemu-user

Within mkosi.conf set Architecture within Distribution and update the kernel package name to refer to the target architecture:

[Distribution]
Distribution=debian
Release=trixie
Architecture=arm64

[Content]
Packages=
    linux-image-arm64