Provided by: mkosi_25.3-5ubuntu2_all 

NAME
mkosi — Build Bespoke OS Images
SYNOPSIS
mkosi [options...] summary
mkosi [options...] cat-config
mkosi [options...] build [command line...]
mkosi [options...] shell [command line...]
mkosi [options...] boot [nspawn settings...]
mkosi [options...] vm [vmm parameters...]
mkosi [options...] ssh [command line...]
mkosi [options...] journalctl [command line...]
mkosi [options...] coredumpctl [command line...]
mkosi [options...] sysupdate [command line...]
mkosi [options...] sandbox [command line ...]
mkosi [options...] clean
mkosi [options...] serve
mkosi [options...] burn <device>
mkosi [options...] bump
mkosi [options...] genkey
mkosi [options...] documentation [manual]
mkosi [options...] completion [shell]
mkosi [options...] dependencies
mkosi [options...] help
DESCRIPTION
mkosi is a tool for easily building customized OS images. It’s a fancy wrapper around dnf, apt, pacman
and zypper that may generate disk images with a number of bells and whistles.
Command Line Verbs
The following command line verbs are known:
summary
Show a human-readable summary of all options used for building the images. This will parse the
command line and configuration files, but only print what it is configured for and not actually
build or run anything.
cat-config
Output the names and contents of all loaded configuration files. mkosi loads a bunch of files
from different locations and this command makes it easier to figure out what is configured where.
build Build the image-based on the settings passed on the command line and in the configuration files.
This command is the default if no verb is specified. Any command line arguments specified after
the verb will be passed directly to the build script, if one is defined.
shell This builds the image if it is not built yet, and then invokes systemd-nspawn to run an
interactive shell in the image. This doesn’t require booting the system, it’s like a better
chroot. An optional command line may be specified after the shell verb, to be invoked in place of
the shell in the container. Use -f in order to rebuild the image unconditionally before acquiring
the shell, see below. This command must be executed as root.
boot Similar to shell, but instead of spawning a shell, it boots systemd in the image using
systemd-nspawn. An optional command line may be specified after the boot verb, which can contain
extra nspawn options as well as arguments which are passed as the kernel command line to the init
system in the image.
vm Similar to boot, but uses the configured virtual machine monitor (by default qemu) to boot up the
image, i.e. instead of container virtualization, virtual machine virtualization is used. How
extra command line arguments are interpreted depends on the configured virtual machine monitor.
See VirtualMachineMonitor= for more information.
ssh When the image is built with the Ssh=yes option, this command connects to a booted virtual machine
via SSH. Make sure to run mkosi ssh with the same config as mkosi build so that it has the
necessary information available to connect to the running virtual machine via SSH. Specifically,
the SSH private key from the SshKey= setting is used to connect to the virtual machine. Use mkosi
genkey to automatically generate a key and certificate that will be picked up by mkosi. Any
arguments passed after the ssh verb are passed as arguments to the ssh invocation. To connect to
a container, use machinectl login or machinectl shell.
The Machine= option can be used to give the machine a custom hostname when booting it which can
later be used to ssh into the image (e.g. mkosi --machine=mymachine vm followed by mkosi
--machine=mymachine ssh).
journalctl
Uses journalctl to inspect the journal inside the image. Any arguments specified after the
journalctl verb are appended to the journalctl invocation.
coredumpctl
Uses coredumpctl to look for coredumps inside the image. Any arguments specified after the
coredumpctl verb are appended to the coredumpctl invocation.
sysupdate
Invokes systemd-sysupdate with the --transfer-source= option set to the output directory and the
--definitions= option set to the directory configured with SysupdateDirectory=. Any arguments
specified after the sysupdate verb are passed directly to systemd-sysupdate invocation.
sandbox
Run arbitrary commands inside of the same sandbox used to execute other verbs such as boot, shell,
vm and more. This means /usr will be replaced by /usr from the tools tree if one is used while
everything else will remain in place. If no command is provided, $SHELL will be executed or bash
if $SHELL is not set.
clean Remove build artifacts generated on a previous build. If combined with -f, also removes
incremental build cache images. If -f is specified twice, also removes any package cache.
serve This builds the image if it is not built yet, and then serves the output directory (i.e. usually
mkosi.output/, see below) via a small embedded HTTP server, listening on port 8081. Combine with
-f in order to rebuild the image unconditionally before serving it. This command is useful for
testing network-based acquisition of OS images, for example via machinectl pull-raw ... and
machinectl pull-tar ....
burn <device>
This builds the image if it is not built yet, and then writes it to the specified block device.
The partition contents are written as-is, but the GPT partition table is corrected to match sector
and disk size of the specified medium.
bump Bumps the image version from mkosi.version and writes the resulting version string to
mkosi.version. This is useful for implementing a simple versioning scheme: each time this verb is
called the version is bumped in preparation for the subsequent build. Note that --auto-bump/-B
may be used to automatically bump the version after each successful build.
genkey Generate a pair of SecureBoot keys for usage with the SecureBootKey=/--secure-boot-key= and
SecureBootCertificate=/--secure-boot-certificate= options.
documentation
Show mkosi’s documentation. If no argument is given, the mkosi man page is shown, but the
arguments mkosi, mkosi-initrd, initrd, mkosi-sandbox, sandbox, mkosi.news and news are supported
and respectively show the man pages for mkosi, mkosi-initrd, mkosi-sandbox and mkosi’s NEWS file.
By default this verb will try several ways to output the documentation, but a specific option can
be chosen with the --doc-format option. Distro packagers are encouraged to add a file mkosi.1
into the mkosi/resources directory of the Python package, if it is missing, as well as to install
it in the appropriate search path for man pages. The man page can be generated from the markdown
file mkosi/resources/man/mkosi.1.md e.g via pandoc -t man -s -o mkosi.1 mkosi.1.md.
completion
Generate shell completion for the shell given as argument and print it to stdout. The arguments
bash, fish, and zsh are understood.
dependencies
Output the list of packages required by mkosi to build and boot images.
This list can be piped directly to a package manager to install the packages. For example, if the
host system uses the dnf package manager, the packages could be installed as follows:
mkosi dependencies | xargs -d '\n' dnf install
help This verb is equivalent to the --help switch documented below: it shows a brief usage explanation.
Commandline-only Options
Those settings cannot be configured in the configuration files.
--force, -f
Replace the output file if it already exists, when building an image. By default when building an
image and an output artifact already exists mkosi will refuse operation. Specify this option once
to delete all build artifacts from a previous run before re-building the image. If incremental
builds are enabled, specifying this option twice will ensure the intermediary cache files are
removed, too, before the re-build is initiated. If a package cache is used (also see the Files
section below), specifying this option thrice will ensure the package cache is removed too, before
the re-build is initiated. For the clean operation this option has a slightly different effect:
by default the verb will only remove build artifacts from a previous run, when specified once the
incremental cache files are deleted too, and when specified twice the package cache is also
removed.
--directory=, -C
Takes a path to a directory. mkosi switches to this directory before doing anything. Note that
the various configuration files are searched for in this directory, hence using this option is an
effective way to build a project located in a specific directory.
--debug
Enable additional debugging output.
--debug-shell
When executing a command in the image fails, mkosi will start an interactive shell in the image
allowing further debugging.
--debug-workspace
When specified, the workspace directory will not be deleted and its location will be logged when
mkosi exits.
--debug-sandbox
Run mkosi-sandbox with strace.
--version
Show package version.
--help, -h
Show brief usage information.
--genkey-common-name=
Common name to be used when generating keys via mkosi’s genkey command. Defaults to mkosi of %u,
where %u expands to the username of the user invoking mkosi.
--genkey-valid-days=
Number of days that the keys should remain valid when generating keys via mkosi’s genkey command.
Defaults to two years (730 days).
--auto-bump=, -B
If specified, after each successful build the version is bumped in a fashion equivalent to the
bump verb, in preparation for the next build. This is useful for simple, linear version
management: each build in a series will have a version number one higher then the previous one.
--doc-format
The format to show the documentation in. Supports the values markdown, man, pandoc, system and
auto. In the case of markdown the documentation is shown in the original Markdown format. man
shows the documentation in man page format, if it is available. pandoc will generate the man page
format on the fly, if pandoc is available. system will show the system-wide man page for mkosi,
which may or may not correspond to the version you are using, depending on how you installed
mkosi. auto, which is the default, will try all methods in the order man, pandoc, markdown,
system.
--json Show the summary output as JSON-SEQ.
--wipe-build-dir, -w
Wipe the build directory if one is configured before building the image.
Supported output formats
The following output formats are supported:
• Raw GPT disk image, created using systemd-repart (disk)
• Plain directory, containing the OS tree (directory)
• Tar archive (tar)
• CPIO archive (cpio)
The output format may also be set to none to have mkosi produce no image at all. This can be useful if
you only want to use the image to produce another output in the build scripts (e.g. build an RPM).
When a GPT disk image is created, repart partition definition files may be placed in mkosi.repart/ to
configure the generated disk image.
It is highly recommended to run mkosi on a file system that supports reflinks such as XFS and btrfs and
to keep all related directories on the same file system. This allows mkosi to create images very quickly
by using reflinks to perform copying via copy-on-write operations.
Configuration Settings
The following settings can be set through configuration files (the syntax with SomeSetting=value) and on
the command line (the syntax with --some-setting=value). For some command line parameters, a
single-letter shortcut is also allowed. In the configuration files, the setting must be in the
appropriate section, so the settings are grouped by section below.
Configuration is parsed in the following order:
• The command line arguments are parsed.
• mkosi.local.conf or mkosi.local is parsed if it exists. This file or directory should be in .gitignore
(or equivalent) and is intended for local configuration.
• Any default paths (depending on the option) are configured if the corresponding path exists.
• mkosi.conf is parsed if it exists in the directory configured with --directory= or the current working
directory if --directory= is not used.
• mkosi.conf.d/ is parsed in the same directory if it exists. Each directory and each file with the
.conf extension in mkosi.conf.d/ is parsed. Any directory in mkosi.conf.d is parsed as if it were a
regular top level directory.
• If any profiles are configured, their configuration is parsed from the mkosi.profiles/ directory.
• Subimages are parsed from the mkosi.images directory if it exists.
Note that settings configured via the command line always override settings configured via configuration
files. If the same setting is configured more than once via configuration files, later assignments
override earlier assignments except for settings that take a collection of values. Also, settings read
from mkosi.local or mkosi.local.conf will override settings from configuration files that are parsed
later, but not settings specified on the CLI.
For settings that take a single value, the empty assignment (SomeSetting= or --some-setting=) can be used
to override a previous setting and reset to the default.
Settings that take a collection of values are merged by appending the new values to the previously
configured values. Assigning the empty string to such a setting removes all previously assigned values,
and overrides any configured default values as well. The values specified on the CLI are appended after
all the values from configuration files.
To conditionally include configuration files, the [Match] section can be used. A [Match] section
consists of individual conditions. Conditions can use a pipe symbol (|) after the equals sign
(...=|...), which causes the condition to become a triggering condition. The config file will be
included if the logical AND of all non-triggering conditions and the logical OR of all triggering
conditions is satisfied. To negate the result of a condition, prefix the argument with an exclamation
mark. If an argument is prefixed with the pipe symbol and an exclamation mark, the pipe symbol must be
passed first, and the exclamation second.
Note that [Match] conditions compare against the current values of specific settings, and do not take
into account changes made to the setting in configuration files that have not been parsed yet (settings
specified on the CLI are taken into account). Also note that matching against a setting and then
changing its value afterwards in a different config file may lead to unexpected results.
The [Match] section of a mkosi.conf file in a directory applies to the entire directory. If the
conditions are not satisfied, the entire directory is skipped. The [Match] sections of files in
mkosi.conf.d/ and mkosi.local.conf only apply to the file itself.
If there are multiple [Match] sections in the same configuration file, each of them has to be satisfied
in order for the configuration file to be included. Specifically, triggering conditions only apply to
the current [Match] section and are reset between multiple [Match] sections. As an example, the
following will only match if the output format is one of disk or directory and the architecture is one of
x86-64 or arm64:
[Match]
Format=|disk
Format=|directory
[Match]
Architecture=|x86-64
Architecture=|arm64
The [TriggerMatch] section can be used to indicate triggering match sections. These are identical to
triggering conditions except they apply to the entire match section instead of just a single condition.
As an example, the following will match if the distribution is debian and the release is bookworm or if
the distribution is ubuntu and the release is noble.
[TriggerMatch]
Distribution=debian
Release=bookworm
[TriggerMatch]
Distribution=ubuntu
Release=noble
The semantics of conditions in [TriggerMatch] sections is the same as in [Match], i.e. all normal
conditions are joined by a logical AND and all triggering conditions are joined by a logical OR. When
mixing [Match] and [TriggerMatch] sections, a match is achieved when all [Match] sections match and at
least one [TriggerMatch] section matches. The absence of match sections is valued as true. Logically
this means:
(⋀ᵢ Matchᵢ) ∧ (⋁ᵢ TriggerMatchᵢ)
Command line options that take no argument are shown without = in their long version. In the config
files, they should be specified with a boolean argument: either 1, yes, or true to enable, or 0, no,
false to disable.
[Distribution] Section
Distribution=, --distribution=, -d
The distribution to install in the image. Takes one of the following arguments: fedora, debian,
kali, ubuntu, arch, opensuse, mageia, centos, rhel, rhel-ubi, openmandriva, rocky, alma, azure or
custom. If not specified, defaults to the distribution of the host or custom if the distribution
of the host is not a supported distribution.
Release=, --release=, -r
The release of the distribution to install in the image. The precise syntax of the argument this
takes depends on the distribution used, and is either a numeric string (in case of Fedora Linux,
CentOS, ..., e.g. 29), or a distribution version name (in case of Debian, Kali, Ubuntu, ...,
e.g. artful). Defaults to a recent version of the chosen distribution, or the version of the
distribution running on the host if it matches the configured distribution.
Architecture=, --architecture=
The architecture to build the image for. The architectures that are actually supported depends on
the distribution used and whether a bootable image is requested or not. When building for a
foreign architecture, you’ll also need to install and register a user mode emulator for that
architecture.
One of the following architectures can be specified per image built: alpha, arc, arm, arm64, ia64,
loongarch64, mips64-le, mips-le, parisc, ppc, ppc64, ppc64-le, riscv32, riscv64, s390, s390x,
tilegx, x86, x86-64.
Mirror=, --mirror=, -m
The mirror to use for downloading the distribution packages. Expects a mirror URL as argument.
If not provided, the default mirror for the distribution is used.
The default mirrors for each distribution are as follows (unless specified, the same mirror is
used for all architectures):
x86-64 aarch64
───────────────────────────────────────────────────────────────────────────────────
debian http://deb.debian.org/debian
arch https://geo.mirror.pkgbuild.com http://mirror.archlinuxarm.org
opensuse http://download.opensuse.org
kali http://http.kali.org/kali
ubuntu http://archive.ubuntu.com http://ports.ubuntu.com
centos https://mirrors.centos.org
rocky https://mirrors.rockylinux.org
alma https://mirrors.almalinux.org
fedora https://mirrors.fedoraproject.org
rhel-ubi https://cdn-ubi.redhat.com
mageia https://www.mageia.org
openmandriva http://mirrors.openmandriva.org
azure https://packages.microsoft.com/
LocalMirror=, --local-mirror=
The mirror will be used as a local, plain and direct mirror instead of using it as a prefix for
the full set of repositories normally supported by distributions. Useful for fully offline builds
with a single repository. Supported on deb-, rpm-, and pacman-based distributions. Overrides
--mirror= but only for the local mkosi build, it will not be configured inside the final image,
--mirror= (or the default repository) will be configured inside the final image instead.
RepositoryKeyCheck=, --repository-key-check=
Controls signature/key checks when using repositories, enabled by default. Useful to disable
checks when combined with --local-mirror= and using only a repository from a local filesystem.
RepositoryKeyFetch=, --repository-key-fetch=
Controls whether mkosi will fetch distribution GPG keys remotely. Enabled by default on Ubuntu
when not using a tools tree or when using Ubuntu tools trees to build Arch Linux or RPM-based
distributions. Disabled by default on all other distributions. When disabled, the distribution
GPG keys for the target distribution have to be installed locally on the host system alongside the
package manager for that distribution.
This setting is only implemented for distributions using dnf, pacman or zypper as their package
manager. For other distributions the distribution GPG keys are always looked up locally
regardless of the value of this setting. To make the distribution GPG keys for distributions
available without enabling this setting, the corresponding package has to be installed on the
host. This is usually one of archlinux-keyring, debian-keyring, kali-archive-keyring,
ubuntu-keyring or distribution-gpg-keys (for RPM-based distributions).
Repositories=, --repositories=
Enable package repositories that are disabled by default. This can be used to enable the EPEL
repos for CentOS or different components of the Debian/Kali/Ubuntu repositories.
[Output] Section
Format=, --format=, -t
The image format type to generate. One of directory (for generating an OS image directly in a
local directory), tar (similar, but a tarball of the OS image is generated), cpio (similar, but a
cpio archive is generated), disk (a block device OS image with a GPT partition table), uki (a
unified kernel image with the OS image in the .initrd PE section), esp (uki but wrapped in a disk
image with only an ESP partition), oci (a directory compatible with the OCI image specification),
sysext, confext, portable, addon or none (the OS image is solely intended as a build image to
produce another artifact).
If the disk output format is used, the disk image is generated using systemd-repart. The repart
partition definition files to use can be configured using the RepartDirectories= setting or via
mkosi.repart/. When verity partitions are configured using systemd-repart’s Verity= setting,
mkosi will automatically parse the verity hash partition’s roothash from systemd-repart’s JSON
output and include it in the kernel command line of every unified kernel image built by mkosi.
If the none output format is used, the outputs from a previous build are not removed, but clean
scripts (see CleanScripts=) are still executed. This allows rerunning a build script (see
BuildScripts=) without removing the results of a previous build.
ManifestFormat=, --manifest-format=
The manifest format type or types to generate. A comma-delimited list consisting of json (the
standard JSON output format that describes the packages installed), changelog (a human-readable
text format designed for diffing). By default no manifest is generated.
Output=, --output=, -o
Name to use for the generated output image file or directory. Defaults to image or, if ImageId=
is specified, it is used as the default output name, optionally suffixed with the version set with
ImageVersion= or if a specific image is built from mkosi.images, the name of the image is
preferred over ImageId. Note that this option does not allow configuring the output directory,
use OutputDirectory= for that.
Note that this only specifies the output prefix, depending on the specific output format,
compression and image version used, the full output name might be image_7.8.raw.xz.
CompressOutput=, --compress-output=
Configure compression for the resulting image or archive. The argument can be either a boolean or
a compression algorithm (xz, zstd). zstd compression is used by default, except CentOS and
derivatives up to version 8, which default to xz, and OCI images, which default to gzip. Note
that when applied to block device image types, compression means the image cannot be started
directly but needs to be decompressed first. This also means that the shell, boot, vm verbs are
not available when this option is used. Implied for tar, cpio, uki, esp, oci and addon.
CompressLevel=, --compress-level=
Configure the compression level to use. Takes an integer. The possible values depend on the
compression being used.
OutputDirectory=, --output-directory=, -O
Path to a directory where to place all generated artifacts. If this is not specified and the
directory mkosi.output/ exists in the local directory, it is automatically used for this purpose.
OutputMode=, --output-mode=
File system access mode used when creating the output image file. Takes an access mode in octal
notation. If not set, uses the current system defaults.
ImageVersion=, --image-version=
Configure the image version. This accepts any string, but it is recommended to specify a series
of dot separated components. The version may also be configured by reading a mkosi.version file
(in which case it may be conveniently managed via the bump verb or the --auto-bump option) or by
reading stdout if it is executable (see the Scripts section below). When specified the image
version is included in the default output file name, i.e. instead of image.raw the default will be
image_0.1.raw for version 0.1 of the image, and similar. The version is also passed via the
$IMAGE_VERSION to any build scripts invoked (which may be useful to patch it into
/usr/lib/os-release or similar, in particular the IMAGE_VERSION= field of it).
ImageId=, --image-id=
Configure the image identifier. This accepts a freeform string that shall be used to identify the
image with. If set the default output file will be named after it (possibly suffixed with the
version). The identifier is also passed via the $IMAGE_ID to any build scripts invoked. The
image ID is automatically added to /usr/lib/os-release.
SplitArtifacts=, --split-artifacts
The artifact types to split out of the final image. A comma-delimited list consisting of uki,
kernel, initrd and partitions. When building a bootable image kernel and initrd correspond to
their artifact found in the image (or in the UKI), while uki copies out the entire UKI.
When building a disk image and partitions is specified, pass --split=yes to systemd-repart to have
it write out split partition files for each configured partition. Read the
https://www.freedesktop.org/software/systemd/man/systemd-repart.html#--split=BOOL man page for
more information. This is useful in A/B update scenarios where an existing disk image shall be
augmented with a new version of a root or /usr partition along with its Verity partition and
unified kernel. By default uki, kernel and initrd are split out.
RepartDirectories=, --repart-directory=
Paths to directories containing systemd-repart partition definition files that are used when mkosi
invokes systemd-repart when building a disk image. If mkosi.repart/ exists in the local
directory, it will be used for this purpose as well. Note that mkosi invokes repart with --root=
set to the root of the image root, so any CopyFiles= source paths in partition definition files
will be relative to the image root directory.
SectorSize=, --sector-size=
Override the default sector size that systemd-repart uses when building a disk image.
Overlay=, --overlay
When used together with BaseTrees=, the output will consist only out of changes to the specified
base trees. Each base tree is attached as a lower layer in an overlayfs structure, and the output
becomes the upper layer, initially empty. Thus files that are not modified compared to the base
trees will not be present in the final output.
This option may be used to create systemd system extensions or portable services.
Seed=, --seed=
Takes a UUID as argument or the special value random. Overrides the seed that systemd-repart uses
when building a disk image. This is useful to achieve reproducible builds, where deterministic
UUIDs and other partition metadata should be derived on each build. If not specified explicitly
and the file mkosi.seed exists in the local directory, the UUID to use is read from it.
Otherwise, a random UUID is used.
CleanScripts=, --clean-script=
Takes a comma-separated list of paths to executables that are used as the clean scripts for this
image. See the Scripts section for more information.
[Content] Section
Packages=, --package=, -p
Install the specified distribution packages (i.e. RPM, deb, ...) in the image. Takes a
comma-separated list of package specifications. This option may be used multiple times in which
case the specified package lists are combined. Use BuildPackages= to specify packages that shall
only be installed in an overlay that is mounted when the prepare scripts are executed with the
build argument and when the build scripts are executed.
The types and syntax of package specifications that are allowed depend on the package installer
(e.g. dnf for RPM-based distros or apt for deb-based distros), but may include package names,
package names with version and/or architecture, package name globs, package groups, and virtual
provides, including file paths.
See PackageDirectories= for information on how to make local packages available for installation
with Packages=.
Example: when using a distro that uses dnf, the following configuration would install the meson
package (in the latest version), the 32-bit version of the libfdisk-devel package, all available
packages that start with the git- prefix, a systemd RPM from the local file system, one of the
packages that provides /usr/bin/ld, the packages in the Development Tools group, and the package
that contains the mypy python module.
Packages=meson
libfdisk-devel.i686
git-*
/usr/bin/ld
@development-tools
python3dist(mypy)
BuildPackages=, --build-package=
Similar to Packages=, but configures packages to install only in an overlay that is made available
on top of the image to the prepare scripts when executed with the build argument and the build
scripts. This option should be used to list packages containing header files, compilers, build
systems, linkers and other build tools the mkosi.build scripts require to operate. Note that
packages listed here will be absent in the final image.
VolatilePackages=, --volatile-package=
Similar to Packages=, but packages configured with this setting are not cached when Incremental=
is enabled and are installed after executing any build scripts.
Specifically, this setting can be used to install packages that change often or which are built by
a build script.
PackageDirectories=, --package-directory=
Specify directories containing extra packages to be made available during the build. mkosi will
create a local repository containing all packages in these directories and make it available when
installing packages or running scripts. If the mkosi.packages/ directory is found in the local
directory it is also used for this purpose.
VolatilePackageDirectories=, --volatile-package-directory=
Like PackageDirectories=, but any changes to the packages in these directories will not invalidate
the cached images if Incremental= is enabled.
Additionally, build scripts can add more packages to the local repository by placing the built
packages in $PACKAGEDIR. The packages placed in $PACKAGEDIR are shared between all image builds
and thus available for installation in all images using VolatilePackages=.
WithRecommends=, --with-recommends=
Configures whether to install recommended or weak dependencies, depending on how they are named by
the used package manager, or not. By default, recommended packages are not installed. This is
only used for package managers that support the concept, which are currently apt, dnf and zypper.
WithDocs=, --with-docs
Include documentation in the image. Enabled by default. When disabled, if the underlying
distribution package manager supports it documentation is not included in the image. The
$WITH_DOCS environment variable passed to the mkosi.build scripts is set to 0 or 1 depending on
whether this option is enabled or disabled.
BaseTrees=, --base-tree=
Takes a comma-separated list of paths to use as base trees. When used, these base trees are each
copied into the OS tree and form the base distribution instead of installing the distribution from
scratch. Only extra packages are installed on top of the ones already installed in the base
trees. Note that for this to work properly, the base image still needs to contain the package
manager metadata by setting CleanPackageMetadata=no (see CleanPackageMetadata=).
Instead of a directory, a tar file or a disk image may be provided. In this case it is unpacked
into the OS tree. This mode of operation allows setting permissions and file ownership
explicitly, in particular for projects stored in a version control system such as git which retain
full file ownership and access mode metadata for committed files.
SkeletonTrees=, --skeleton-tree=
Takes a comma-separated list of colon-separated path pairs. The first path of each pair refers to
a directory to copy into the OS tree before invoking the package manager. The second path of each
pair refers to the target directory inside the image. If the second path is not provided, the
directory is copied on top of the root directory of the image. The second path is always
interpreted as an absolute path. Use this to insert files and directories into the OS tree before
the package manager installs any packages. If the mkosi.skeleton/ directory is found in the local
directory it is also used for this purpose with the root directory as target (also see the Files
section below).
Note that skeleton trees are cached and any changes to skeleton trees after a cached image has
been built (when using Incremental=) are only applied when the cached image is rebuilt (by using
-ff or running mkosi -f clean).
As with the base tree logic above, instead of a directory, a tar file may be provided too.
mkosi.skeleton.tar will be automatically used if found in the local directory.
To add extra package manager configuration files such as extra repositories, use SandboxTrees= as
mkosi invokes the package managers from outside the image and not inside so any package manager
configuration files provided via SkeletonTrees= won’t take effect when mkosi invokes a package
manager to install packages.
ExtraTrees=, --extra-tree=
Takes a comma-separated list of colon-separated path pairs. The first path of each pair refers to
a directory to copy from the host into the image. The second path of each pair refers to the
target directory inside the image. If the second path is not provided, the directory is copied on
top of the root directory of the image. The second path is always interpreted as an absolute
path. Use this to override any default configuration files shipped with the distribution. If the
mkosi.extra/ directory is found in the local directory it is also used for this purpose with the
root directory as target (also see the Files section below).
As with the base tree logic above, instead of a directory, a tar file may be provided too.
mkosi.extra.tar will be automatically used if found in the local directory.
RemovePackages=, --remove-package=
Takes a comma-separated list of package specifications for removal, in the same format as
Packages=. The removal will be performed as one of the last steps. This step is skipped if
CleanPackageMetadata=no is used.
RemoveFiles=, --remove-files=
Takes a comma-separated list of globs. Files in the image matching the globs will be purged at
the end.
CleanPackageMetadata=, --clean-package-metadata=
Enable/disable removal of package manager databases and repository metadata at the end of
installation. Can be specified as true, false, or auto (the default). With auto, package manager
databases and repository metadata will be removed if the respective package manager executable is
not present at the end of the installation.
SourceDateEpoch=, --source-date-epoch=
Takes a timestamp in seconds since the UNIX epoch as argument. File modification times of all
files will be clamped to this value. The variable is also propagated to systemd-repart and
scripts executed by mkosi. If not set explicitly, SOURCE_DATE_EPOCH from --environment and from
the host environment are tried in that order. This is useful to make builds reproducible. See
SOURCE_DATE_EPOCH for more information.
SyncScripts=, --sync-script=
Takes a comma-separated list of paths to executables that are used as the sync scripts for this
image. See the Scripts section for more information.
PrepareScripts=, --prepare-script=
Takes a comma-separated list of paths to executables that are used as the prepare scripts for this
image. See the Scripts section for more information.
BuildScripts=, --build-script=
Takes a comma-separated list of paths to executables that are used as the build scripts for this
image. See the Scripts section for more information.
PostInstallationScripts=, --postinst-script=
Takes a comma-separated list of paths to executables that are used as the post-installation
scripts for this image. See the Scripts section for more information.
FinalizeScripts=, --finalize-script=
Takes a comma-separated list of paths to executables that are used as the finalize scripts for
this image. See the Scripts section for more information.
PostOutputScripts=, --postoutput-script
Takes a comma-separated list of paths to executables that are used as the post output scripts for
this image. See the Scripts section for more information.
Bootable=, --bootable=
Takes a boolean or auto. Enables or disables generation of a bootable image. If enabled, mkosi
will install an EFI bootloader, and add an ESP partition when the disk image output is used. If
the selected EFI bootloader (see Bootloader=) is not installed or no kernel images can be found,
the build will fail. auto behaves as if the option was enabled, but the build won’t fail if
either no kernel images or the selected EFI bootloader can’t be found. If disabled, no bootloader
will be installed even if found inside the image, no unified kernel images will be generated and
no ESP partition will be added to the image if the disk output format is used.
Bootloader=, --bootloader=
Takes one of none, systemd-boot, uki, grub, systemd-boot-signed, uki-signed or grub-signed.
Defaults to systemd-boot. If set to none, no EFI bootloader will be installed into the image. If
set to systemd-boot, systemd-boot will be installed and for each installed kernel, a UKI will be
generated and stored in EFI/Linux in the ESP. If set to uki, a single UKI will be generated for
the latest installed kernel (the one with the highest version) which is installed to
EFI/BOOT/BOOTX64.EFI in the ESP. If set to grub, for each installed kernel, a UKI will be
generated and stored in EFI/Linux in the ESP. For each generated UKI, a menu entry is appended to
the grub configuration in grub/grub.cfg in the ESP which chainloads into the UKI. A shim grub.cfg
is also written to EFI/<distribution>/grub.cfg in the ESP which loads grub/grub.cfg in the ESP for
compatibility with signed versions of grub which load the grub configuration from this location.
The signed variants will only install pre-signed EFI binaries shipped by the distribution.
Kernels need to be placed into the root filesystem (for example using ExtraTrees=) under
/usr/lib/modules/$version, named vmlinux or vmlinuz. The $version is as produced by Kbuild’s
kernelversion make target.
BiosBootloader=, --bios-bootloader=
Takes one of none or grub. Defaults to none. If set to none, no BIOS bootloader will be
installed. If set to grub, grub is installed as the BIOS boot loader if a bootable image is
requested with the Bootable= option. If no repart partition definition files are configured,
mkosi will add a grub BIOS boot partition and an EFI system partition to the default partition
definition files.
Note that this option is not mutually exclusive with Bootloader=. It is possible to have an image
that is both bootable on UEFI and BIOS by configuring both Bootloader= and BiosBootloader=.
The grub BIOS boot partition should have UUID 21686148-6449-6e6f-744e-656564454649 and should be
at least 1MB.
Even if no EFI bootloader is installed, we still need an ESP for BIOS boot as that’s where we
store the kernel, initrd and grub modules.
ShimBootloader=, --shim-bootloader=
Takes one of none, unsigned, or signed. Defaults to none. If set to none, shim and MokManager
will not be installed to the ESP. If set to unsigned, mkosi will search for unsigned shim and
MokManager EFI binaries and install them. If SecureBoot= is enabled, mkosi will sign the unsigned
EFI binaries before installing them. If set to signed, mkosi will search for signed EFI binaries
and install those. Even if SecureBoot= is enabled, mkosi won’t sign these binaries again.
Note that this option only takes effect when an image that is bootable on UEFI firmware is
requested using other options (Bootable=, Bootloader=).
Note that when this option is enabled, mkosi will only install already signed bootloader binaries,
kernel image files and unified kernel images as self-signed binaries would not be accepted by the
signed version of shim.
UnifiedKernelImages=, --unified-kernel-images=
Specifies whether to use unified kernel images or not when Bootloader= is set to systemd-boot or
grub. Takes a boolean value or auto. Defaults to auto. If enabled, unified kernel images are
always used and the build will fail if any components required to build unified kernel images are
missing. If set to auto, unified kernel images will be used if all necessary components are
available. Otherwise Type 1 entries as defined by the Boot Loader Specification will be used
instead. If disabled, Type 1 entries will always be used.
UnifiedKernelImageFormat=, --unified-kernel-image-format=
Takes a filename without any path components to specify the format that unified kernel images
should be installed as. This may include both the regular specifiers (see Specifiers) and special
delayed specifiers, that are expanded during the installation of the files, which are described
below. The default format for this parameter is &e-&k with -&h being appended if roothash= or
usrhash= is found on the kernel command line and +&c if /etc/kernel/tries is found in the image.
The following specifiers may be used:
Specifier Value
──────────────────────────────────────────────────
&& & character
&e Entry Token
&k Kernel version
&h roothash= or usrhash= value of kernel
argument
&c Number of tries used for boot attempt
counting
UnifiedKernelImageProfiles=, --uki-profile=
Build additional UKI profiles. Takes a comma-separated list of paths to UKI profile config files.
This option may be used multiple times in which case each config gets built into a corresponding
UKI profile. Config files in the mkosi.uki-profiles/ directory are automatically picked up. All
configured UKI profiles are added as additional UKI profiles to each UKI built by mkosi.
See the documentation for the UKIProfile section for information on which settings can be
configured in UKI profile config files.
Initrds=, --initrd
Use user-provided initrd(s). Takes a comma-separated list of paths to initrd files. This option
may be used multiple times in which case the initrd lists are combined. If no initrds are
specified and a bootable image is requested, mkosi will look for initrds in a subdirectory
io.mkosi.initrd of the artifact directory (see $ARTIFACTDIR in the section ENVIRONMENT VARIABLES),
if none are found there mkosi will automatically build a default initrd.
InitrdPackages=, --initrd-package=
Extra packages to install into the default initrd. Takes a comma separated list of package
specifications. This option may be used multiple times in which case the specified package lists
are combined.
InitrdVolatilePackages=, --initrd-volatile-package=
Similar to VolatilePackages=, except it applies to the default initrd.
Devicetree=, --devicetree=
When set, specifies a Devicetree blob to be used by the booting system, instead of the one
provided by firmware. mkosi will search for the specified file relative to common paths where
Linux distributions install Devicetree files. It should typically have the format
<vendor>/<board>.dtb.
MicrocodeHost=, --microcode-host=
When set to true only include microcode for the host’s CPU in the image.
KernelCommandLine=, --kernel-command-line=
Use the specified kernel command line when building images.
If the root or usr partition are created with verity enabled, roothash= or usrhash= respectively
are automatically added to the kernel command line and root= or mount.usr= should not be added.
Otherwise, if the value of this setting contains the literals root=PARTUUID or mount.usr=PARTUUID,
these are replaced with the partition UUID of the root or usr partition respectively. For
example, root=PARTUUID would be replaced with root=PARTUUID=58c7d0b2-d224-4834-a16f-e036322e88f7
where 58c7d0b2-d224-4834-a16f-e036322e88f7 is the partition UUID of the root partition.
KernelModulesInclude=, --kernel-modules-include=
Takes a list of regex patterns that specify kernel modules to include in the image. Patterns
should be relative to /usr/lib/modules/<kver>/<subdir> paths. mkosi checks for a match anywhere
in the module path (e.g. i915 will match against drivers/gpu/drm/i915.ko). All modules that match
any of the specified patterns are included in the image. All module and firmware dependencies of
the matched modules are included in the image as well.
If the special value default is used, the default kernel modules defined in the mkosi-initrd
configuration are included as well.
If the special value host is used, the currently loaded modules on the host system are included as
well.
This setting takes priority over KernelModulesExclude= and only makes sense when used in
combination with it because all kernel modules are included in the image by default.
KernelModulesExclude=, --kernel-modules-exclude=
Takes a list of regex patterns that specify modules to exclude from the image. Behaves the same
as KernelModulesInclude= except that all modules that match any of the specified patterns are
excluded from the image.
KernelModulesInitrd=, --kernel-modules-initrd=
Boolean value, enabled (true) by default. If enabled, when building a bootable image, mkosi will
generate an extra initrd for each unified kernel image it assembles. This initrd contains only
modules for the specific kernel version, and will be appended to the prebuilt initrd. This allows
generating kernel independent initrds which are augmented with the necessary modules when the UKI
is assembled.
KernelModulesInitrdInclude=, --kernel-modules-initrd-include=
Like KernelModulesInclude=, but applies to the kernel modules included in the kernel modules
initrd.
KernelModulesInitrdExclude=, --kernel-modules-initrd-exclude=
Like KernelModulesExclude=, but applies to the kernel modules included in the kernel modules
initrd.
Locale=, --locale=, LocaleMessages=, --locale-messages=, Keymap=, --keymap=, Timezone=, --timezone=,
Hostname=, --hostname=, RootShell=, --root-shell=
The settings Locale=, --locale=, LocaleMessages=, --locale-messages=, Keymap=, --keymap=,
Timezone=, --timezone=, Hostname=, --hostname=, RootShell=, --root-shell= correspond to the
identically named systemd-firstboot options. See systemd-firstboot(1) for more information.
Additionally, where applicable, the corresponding systemd credentials for these settings are
written to /usr/lib/credstore, so that they apply even if only /usr is shipped in the image.
RootPassword=, --root-password=,
Set the system root password. If this option is not used, but a mkosi.rootpw file is found in the
local directory, the password is automatically read from it or if the file is executable it is run
as a script and stdout is read instead (see the Scripts section below). If the password starts
with hashed:, it is treated as an already hashed root password. The root password is also stored
in /usr/lib/credstore under the appropriate systemd credential so that it applies even if only
/usr is shipped in the image. To create an unlocked account without any password use hashed:
without a hash.
Autologin=, --autologin
Enable autologin for the root user on /dev/pts/0 (nspawn), /dev/tty1 and /dev/hvc0.
MakeInitrd=, --make-initrd
Add /etc/initrd-release and /init to the image so that it can be used as an initramfs.
Ssh=, --ssh
If specified, an sshd socket unit and matching service are installed in the final image that
expose SSH over VSock. When building with this option and running the image using mkosi vm, the
mkosi ssh command can be used to connect to the container/VM via SSH. Note that you still have to
make sure openssh is installed in the image to make this option behave correctly. Run mkosi
genkey to automatically generate an X.509 certificate and private key to be used by mkosi to
enable SSH access to any virtual machines via mkosi ssh. To access images booted using mkosi
boot, use machinectl.
SELinuxRelabel=, --selinux-relabel=
Specifies whether to relabel files to match the image’s SELinux policy. Takes a boolean value or
auto. Defaults to auto. If disabled, files will not relabeled. If enabled, an SELinux policy
has to be installed in the image and setfiles has to be available to relabel files. If any errors
occur during setfiles, the build will fail. If set to auto, files will be relabeled if an SELinux
policy is installed in the image and if setfiles is available. Any errors occurred during
setfiles will be ignored.
Note that when running unprivileged, setfiles will fail to set any labels that are not in the
host’s SELinux policy. To ensure setfiles succeeds without errors, make sure to run mkosi as root
or build from a host system with the same SELinux policy as the image you’re building.
MachineId=, --machine-id=
Takes a UUID or the special value random. Sets the machine ID of the image to the specified UUID.
If set to random, a random UUID will be written to /etc/machine-id. If not specified explicitly
and the file mkosi.machine-id exists in the local directory, the UUID to use is read from it.
Otherwise, uninitialized will be written to /etc/machine-id.
[Validation] Section
SecureBoot=, --secure-boot
Sign systemd-boot (if it is not signed yet) and any generated unified kernel images for UEFI
SecureBoot.
SecureBootAutoEnroll=, --secure-boot-auto-enroll=
Set up automatic enrollment of the secure boot keys in virtual machines as documented in
systemd-boot(7) if SecureBoot= is used. Note that systemd-boot will only do automatic secure boot
key enrollment in virtual machines starting from systemd v253. To do auto enrollment on systemd
v252 or on bare metal machines, write a systemd-boot configuration file to /efi/loader/loader.conf
using an extra tree with secure-boot-enroll force or secure-boot-enroll manual in it. Auto
enrollment is not supported on systemd versions older than v252. Defaults to yes.
SecureBootKey=, --secure-boot-key=
Path to the PEM file containing the secret key for signing the UEFI kernel image if SecureBoot= is
used and PCR signatures when SignExpectedPcr= is also used. When SecureBootKeySource= is
specified, the input type depends on the source.
SecureBootCertificate=, --secure-boot-certificate=
Path to the X.509 file containing the certificate for the signed UEFI kernel image, if SecureBoot=
is used.
SecureBootSignTool=, --secure-boot-sign-tool
Tool to use to sign secure boot PE binaries. Takes one of systemd-sbsign, sbsign or auto.
Defaults to auto. If set to auto, either systemd-sbsign or sbsign are used if available, with
systemd-sbsign being preferred.
Verity=, --verity=
Whether to enforce or disable signed verity for extension images. Takes a boolean value or auto.
If enabled, a verity key and certificate must be present and the build will fail if we don’t
detect any verity partitions in the disk image produced by systemd-repart. If disabled, verity
partitions will be excluded from the extension images produced by systemd-repart. If set to auto
and a verity key and certificate are present, mkosi will pass them to systemd-repart and expects
the generated disk image to contain verity partitions, but the build won’t fail if no verity
partitions are found in the disk image produced by systemd-repart.
Note that explicitly disabling signed verity is not yet implemented for the disk output and only
works for extension images at the moment.
VerityKey=, --verity-key=
Path to the PEM file containing the secret key for signing the verity signature, if a verity
signature partition is added with systemd-repart. When VerityKeySource= is specified, the input
type depends on the source.
VerityCertificate=, --verity-certificate=
Path to the X.509 file containing the certificate for signing the verity signature, if a verity
signature partition is added with systemd-repart.
SignExpectedPcr=, --sign-expected-pcr
Measure the components of the unified kernel image (UKI) using systemd-measure and embed the PCR
signature into the unified kernel image. This option takes a boolean value or the special value
auto, which is the default, which is equal to a true value if the systemd-measure binary is in
PATH. Depends on SecureBoot= being enabled and key from SecureBootKey=.
SignExpectedPcrKey=, --sign-expected-pcr-key=
Path to the PEM file containing the secret key for signing the expected PCR signatures. When
SignExpectedPcrKeySource= is specified, the input type depends on the source.
SignExpectedPcrCertificate=, --sign-expected-pcr-certificate=
Path to the X.509 file containing the certificate for signing the expected PCR signatures.
SecureBootKeySource=, --secure-boot-key-source=, VerityKeySource=, --verity-key-source=,
SignExpectedPcrKeySource=, --sign-expected-key-source=
The source of the corresponding private key, to support OpenSSL engines and providers,
e.g. --secure-boot-key-source=engine:pkcs11 or --secure-boot-key-source=provider:pkcs11.
SecureBootCertificateSource=, --secure-boot-certificate-source=, VerityCertificateSource=,
--verity-certificate-source=, SignExpectedPcrCertificateSource=, --sign-expected-certificate-source=
The source of the corresponding certificate, to support OpenSSL providers,
e.g. --secure-boot-certificate-source=provider:pkcs11. Note that engines are not supported.
Passphrase=, --passphrase
Specify the path to a file containing the passphrase to use for LUKS encryption. It should
contain the passphrase literally, and not end in a newline character (i.e. in the same format as
cryptsetup and /etc/crypttab expect the passphrase files). The file must have an access mode of
0600 or less.
Checksum=, --checksum
Generate a <output>.SHA256SUMS file of all generated artifacts after the build is complete.
Sign=, --sign
Sign the generated SHA256SUMS using gpg after completion.
OpenPGPTool=, --openpgp-tool
OpenPGP implementation to use for signing. gpg is the default. Selecting a value different than
the default will use the given Stateless OpenPGP (SOP) tool for signing the SHA256SUMS file.
Exemplary choices are sqop and rsop, but any implementation from
https://www.openpgp.org/about/sop/ that can be installed locally will work.
Key=, --key=
Select the gpg key to use for signing SHA256SUMS. This key must be already present in the gpg
keyring.
[Build] Section
ToolsTree=, --tools-tree=
If specified, programs executed by mkosi to build and boot an image are looked up inside the given
tree instead of in the host system. Use this option to make image builds more reproducible by
always using the same versions of programs to build the final image instead of whatever version is
installed on the host system. If this option is not used, but the mkosi.tools/ directory is found
in the local directory it is automatically used for this purpose with the root directory as
target.
Note that binaries found in any of the paths configured with ExtraSearchPaths= will be executed
with /usr/ from the tools tree instead of from the host. If the host distribution or release does
not match the tools tree distribution or release respectively, this might result in failures when
trying to execute binaries from any of the extra search paths.
If set to default, mkosi will automatically add an extra tools tree image and use it as the tools
tree.
The following table shows for which distributions default tools tree packages are defined and
which packages are included in those default tools trees:
Fedora CentOS Debian Kali Ubuntu Arch openSUSE
────────────────────────────────────────────────────────────────────────────────────────────
acl ✓ ✓ ✓ ✓ ✓ ✓ ✓
apt ✓ ✓ ✓ ✓ ✓ ✓
archlinux-keyring ✓ ✓ ✓ ✓ ✓ ✓
attr ✓ ✓ ✓ ✓ ✓ ✓ ✓
bash ✓ ✓ ✓ ✓ ✓ ✓ ✓
btrfs-progs ✓ ✓ ✓ ✓ ✓ ✓ ✓
ca-certificates ✓ ✓ ✓ ✓ ✓ ✓ ✓
coreutils ✓ ✓ ✓ ✓ ✓ ✓ ✓
cpio ✓ ✓ ✓ ✓ ✓ ✓ ✓
createrepo_c ✓ ✓ ✓ ✓ ✓ ✓ ✓
curl ✓ ✓ ✓ ✓ ✓ ✓ ✓
debian-keyring ✓ ✓ ✓ ✓ ✓ ✓
diffutils ✓ ✓ ✓ ✓ ✓ ✓ ✓
distribution-gpg-keys ✓ ✓ ✓ ✓ ✓ ✓
dnf ✓ ✓ ✓ ✓ ✓ ✓ ✓
dosfstools ✓ ✓ ✓ ✓ ✓ ✓ ✓
e2fsprogs ✓ ✓ ✓ ✓ ✓ ✓ ✓
edk2-ovmf ✓ ✓ ✓ ✓ ✓ ✓ ✓
erofs-utils ✓ ✓ ✓ ✓ ✓ ✓ ✓
findutils ✓ ✓ ✓ ✓ ✓ ✓ ✓
git ✓ ✓ ✓ ✓ ✓ ✓ ✓
grep ✓ ✓ ✓ ✓ ✓ ✓ ✓
grub-tools ✓ ✓ ✓ ✓ ✓ ✓
jq ✓ ✓ ✓ ✓ ✓ ✓ ✓
kali-archive-keyring ✓
kmod ✓ ✓ ✓ ✓ ✓ ✓ ✓
less ✓ ✓ ✓ ✓ ✓ ✓ ✓
mtools ✓ ✓ ✓ ✓ ✓ ✓ ✓
nano ✓ ✓ ✓ ✓ ✓ ✓ ✓
opensc ✓ ✓ ✓ ✓ ✓ ✓ ✓
openssh ✓ ✓ ✓ ✓ ✓ ✓ ✓
openssl ✓ ✓ ✓ ✓ ✓ ✓ ✓
pkcs11-provider ✓ ✓ ✓ ✓ ✓ ✓ ✓
perf ✓ ✓ ✓ ✓ ✓ ✓
sed ✓ ✓ ✓ ✓ ✓ ✓ ✓
pacman ✓ ✓ ✓ ✓ ✓ ✓
policycoreutils ✓ ✓ ✓ ✓ ✓ ✓
qemu ✓ ✓ ✓ ✓ ✓ ✓ ✓
sbsigntools ✓ ✓ ✓ ✓ ✓ ✓ ✓
socat ✓ ✓ ✓ ✓ ✓ ✓ ✓
squashfs-tools ✓ ✓ ✓ ✓ ✓ ✓ ✓
strace ✓ ✓ ✓ ✓ ✓ ✓ ✓
swtpm ✓ ✓ ✓ ✓ ✓ ✓ ✓
systemd ✓ ✓ ✓ ✓ ✓ ✓ ✓
ukify ✓ ✓ ✓ ✓ ✓ ✓ ✓
tar ✓ ✓ ✓ ✓ ✓ ✓ ✓
ubuntu-keyring ✓ ✓ ✓ ✓ ✓ ✓
util-linux ✓ ✓ ✓ ✓ ✓ ✓ ✓
virtiofsd ✓ ✓ ✓ ✓ ✓ ✓ ✓
virt-firmware ✓ ✓ ✓ ✓ ✓ ✓ ✓
xfsprogs ✓ ✓ ✓ ✓ ✓ ✓ ✓
xz ✓ ✓ ✓ ✓ ✓ ✓ ✓
zstd ✓ ✓ ✓ ✓ ✓ ✓ ✓
zypper ✓ ✓ ✓ ✓ ✓
ToolsTreeDistribution=, --tools-tree-distribution=
Set the distribution to use for the default tools tree. Defaults to the host distribution except
for Ubuntu, which defaults to Debian, and RHEL, CentOS, Alma and Rocky, which default to Fedora,
or custom if the distribution of the host is not a supported distribution.
ToolsTreeRelease=, --tools-tree-release=
Set the distribution release to use for the default tools tree. By default, the hardcoded default
release in mkosi for the distribution is used.
ToolsTreeMirror=, --tools-tree-mirror=
Set the mirror to use for the default tools tree. By default, the default mirror for the tools
tree distribution is used.
ToolsTreeRepositories=, --tools-tree-repository
Same as Repositories= but for the default tools tree.
ToolsTreeSandboxTrees=, --tools-tree-sandbox-tree
Same as SandboxTrees= but for the default tools tree.
ToolsTreePackages=, --tools-tree-package=
Extra packages to install into the default tools tree. Takes a comma separated list of package
specifications. This option may be used multiple times in which case the specified package lists
are combined.
ToolsTreePackageDirectories=, --tools-tree-package-directory=
Same as PackageDirectories=, but for the default tools tree.
ToolsTreeCertificates=, --tools-tree-certificates=
Specify whether to use certificates and keys from the tools tree. Enabled by default. If
enabled, /etc/pki, /etc/ssl, /etc/ca-certificates, and /var/lib/ca-certificates from the tools
tree are used. Otherwise, these directories are picked up from the host.
ExtraSearchPaths=, --extra-search-path=
List of colon-separated paths to look for tools in, before using the regular $PATH search path.
Incremental=, --incremental=, -i
Takes either strict or a boolean value as its argument. Enables incremental build mode. In this
mode, a copy of the OS image is created immediately after all OS packages are installed and the
prepare scripts have executed but before the mkosi.build scripts are invoked (or anything that
happens after it). On subsequent invocations of mkosi with the -i switch this cached image may be
used to skip the OS package installation, thus drastically speeding up repetitive build times.
Note that while there is some rudimentary cache invalidation, it is definitely not perfect. In
order to force a rebuild of the cached image, combine -i with -ff to ensure the cached image is
first removed and then re-created.
If set to strict, the build fails if previously built cached image does not exist.
CacheOnly=, --cache-only=
Takes one of auto, metadata, always or never. Defaults to auto. If always, the package manager
is instructed not to contact the network. This provides a minimal level of reproducibility, as
long as the package cache is already fully populated. If set to metadata, the package manager can
still download packages, but we won’t sync the repository metadata. If set to auto, the
repository metadata is synced unless we have a cached image (see Incremental=) and packages can be
downloaded during the build. If set to never, repository metadata is always synced and packages
can be downloaded during the build.
SandboxTrees=, --sandbox-tree=
Takes a comma-separated list of colon-separated path pairs. The first path of each pair refers to
a directory to copy into the mkosi sandbox before executing a tool. If the mkosi.sandbox/
directory is found in the local directory it is used for this purpose with the root directory as
target (also see the Files section below).
mkosi will look for the package manager configuration and related files in the configured sandbox
trees. Unless specified otherwise, it will use the configuration files from their canonical
locations in /usr or /etc in the sandbox trees. For example, it will look for /etc/dnf/dnf.conf
in the sandbox trees if dnf is used to install packages.
WorkspaceDirectory=, --workspace-directory=
Path to a directory where to store data required temporarily while building the image. This
directory should have enough space to store the full OS image, though in most modes the actually
used disk space is smaller. If not specified, a subdirectory of $XDG_CACHE_HOME (if set),
$HOME/.cache (if set) or /var/tmp is used.
The data in this directory is removed automatically after each build. It’s safe to manually
remove the contents of this directory should an mkosi invocation be aborted abnormally (for
example, due to reboot/power failure).
CacheDirectory=, --cache-directory=
Takes a path to a directory to use as the incremental cache directory for the incremental images
produced when the Incremental= option is enabled. If this option is not used, but a mkosi.cache/
directory is found in the local directory it is automatically used for this purpose.
PackageCacheDirectory=, --package-cache-dir
Takes a path to a directory to use as the package cache directory for the distribution package
manager used. If unset, but a mkosi.pkgcache/ directory is found in the local directory it is
automatically used for this purpose, otherwise a suitable directory in the user’s home directory
or system is used.
BuildDirectory=, --build-directory=
Takes a path to a directory to use as the build directory for build systems that support
out-of-tree builds (such as Meson). The directory used this way is shared between repeated
builds, and allows the build system to reuse artifacts (such as object files, executable, ...)
generated on previous invocations. The build scripts can find the path to this directory in the
$BUILDDIR environment variable. This directory is mounted into the image’s root directory when
mkosi-chroot is invoked during execution of the build scripts. If this option is not specified,
but a directory mkosi.builddir/ exists in the local directory it is automatically used for this
purpose (also see the Files section below).
UseSubvolumes=, --use-subvolumes=
Takes a boolean or auto. Enables or disables use of btrfs subvolumes for directory tree outputs.
If enabled, mkosi will create the root directory as a btrfs subvolume and use btrfs subvolume
snapshots where possible to copy base or cached trees which is much faster than doing a recursive
copy. If explicitly enabled and btrfs is not installed or subvolumes cannot be created, an error
is raised. If auto, missing btrfs or failures to create subvolumes are ignored.
RepartOffline=, --repart-offline=
Specifies whether to build disk images using loopback devices. Enabled by default. When enabled,
systemd-repart will not use loopback devices to build disk images. When disabled, systemd-repart
will always use loopback devices to build disk images.
Note that when using RepartOffline=nomkosi cannot run unprivileged and the image build has to be
done as the root user outside of any containers and with loopback devices available on the host
system.
There are currently two known scenarios where RepartOffline=no has to be used. The first is when
using Subvolumes= in a repart partition definition file, as subvolumes cannot be created without
using loopback devices. The second is when creating a system with SELinux and an XFS root
partition. Because mkfs.xfs does not support populating an XFS filesystem with extended
attributes, loopback devices have to be used to ensure the SELinux extended attributes end up in
the generated XFS filesystem.
History=, --history=
Takes a boolean. If enabled, mkosi will write information about the latest build to the
.mkosi-private subdirectory in the directory from which it was invoked. This information is then
used to restore the config of the latest build when running any verb that needs a build without
specifying --force.
To give an example of why this is useful, if you run mkosi -O my-custom-output-dir -f followed by
mkosi vm, mkosi will fail saying the image hasn’t been built yet. If you run mkosi -O
my-custom-output-dir --history=yes -f followed by mkosi vm, it will boot the image built in the
previous step as expected.
BuildSources=, --build-sources=
Takes a comma-separated list of colon-separated path pairs. The first path of each pair refers to
a directory to mount from the host. The second path of each pair refers to the directory where
the source directory should be mounted when running scripts. Every target path is prefixed with
/work/src and all build sources are sorted lexicographically by their target before mounting, so
that top level paths are mounted first. If not configured explicitly, the current working
directory is mounted to /work/src.
BuildSourcesEphemeral=, --build-sources-ephemeral=
Takes a boolean or the special value buildcache. Disabled by default. Configures whether changes
to source directories, the working directory and configured using BuildSources=, are persisted.
If enabled, all source directories will be reset to their original state every time after running
all scripts of a specific type (except sync scripts).
💥💣💥 If set to buildcache the overlay is not discarded when running build scripts, but saved to
the build directory, configured via BuildDirectory=, and will be reused on subsequent runs. The
overlay is still discarded for all other scripts. This option can be used to implement more
advanced caching of builds, but can lead to unexpected states of the source directory. When using
this option, a build directory must be configured. 💥💣💥
Environment=, --environment=
Adds variables to the environment that package managers and the prepare/build/postinstall/finalize
scripts are executed with. Takes a space-separated list of variable assignments or just variable
names. In the latter case, the values of those variables will be passed through from the
environment in which mkosi was invoked. This option may be specified more than once, in which
case all listed variables will be set. If the same variable is set twice, the later setting
overrides the earlier one.
EnvironmentFiles=, --env-file=
Takes a comma-separated list of paths to files that contain environment variable definitions to be
added to the scripting environment. Uses mkosi.env if it is found in the local directory. The
variables are first read from mkosi.env if it exists, then from the given list of files and then
from the Environment= settings.
WithTests=, --without-tests, -T
If set to false (or when the command-line option is used), the $WITH_TESTS environment variable is
set to 0 when the mkosi.build scripts are invoked. This is supposed to be used by the build
scripts to bypass any unit or integration tests that are normally run during the source build
process. Note that this option has no effect unless the mkosi.build build scripts honor it.
WithNetwork=, --with-network=
When true, enables network connectivity while the build scripts mkosi.build are invoked. By
default, the build scripts run with networking turned off. The $WITH_NETWORK environment variable
is passed to the mkosi.build build scripts indicating whether the build is done with or without
network.
ProxyUrl=, --proxy-url=
Configure a proxy to be used for all outgoing network connections. Various tools that mkosi
invokes and for which the proxy can be configured are configured to use this proxy. mkosi also
sets various well-known environment variables to specify the proxy to use for any programs it
invokes that may need internet access.
ProxyExclude=, --proxy-exclude=
Configure hostnames for which requests should not go through the proxy. Takes a comma-separated
list of hostnames.
ProxyPeerCertificate=, --proxy-peer-certificate=
Configure a file containing certificates used to verify the proxy. Defaults to the system-wide
certificate store.
Currently, setting a proxy peer certificate is only supported when dnf or dnf5 is used to build
the image.
ProxyClientCertificate=, --proxy-client-certificate=
Configure a file containing the certificate used to authenticate the client with the proxy.
Currently, setting a proxy client certificate is only supported when dnf or dnf5 is used to build
the image.
ProxyClientKey=, --proxy-client-key=
Configure a file containing the private key used to authenticate the client with the proxy.
Defaults to the proxy client certificate if one is provided.
Currently, setting a proxy client key is only supported when dnf or dnf5 is used to build the
image.
[Runtime] Section (previously known as the [Host] section)
NSpawnSettings=, --settings=
Specifies a .nspawn settings file for systemd-nspawn to use in the boot and shell verbs, and to
place next to the generated image file. This is useful to configure the systemd-nspawn
environment when the image is run. If this setting is not used but an mkosi.nspawn file found in
the local directory it is automatically used for this purpose.
VirtualMachineMonitor=, --vmm=
Configures the virtual machine monitor to use. Takes one of qemu or vmspawn. Defaults to qemu.
When set to qemu, the image is booted with qemu. Most output formats can be booted in qemu. Any
arguments specified after the verb are appended to the qemu invocation and are interpreted as
extra qemu command line arguments.
When set to vmspawn, systemd-vmspawn is used to boot up the image, vmspawn only supports disk and
directory type images. Any arguments specified after the verb are appended to the systemd-vmspawn
invocation and are interpreted as extra vmspawn options and extra kernel command line arguments.
Console=, --console=
Configures how to set up the console of the VM. Takes one of interactive, read-only, native, or
gui. Defaults to interactive. interactive provides an interactive terminal interface to the VM.
read-only is similar, but is strictly read-only, i.e. does not accept any input from the user.
native also provides a TTY-based interface, but uses qemu’s native implementation (which means the
qemu monitor is available). gui shows the qemu graphical UI.
CPUs=, --cpus=
Configures the number of CPU cores to assign to the guest when booting a virtual machine.
Defaults to 2.
When set to 0, the number of CPUs available to the mkosi process will be used.
RAM=, --ram=
Configures the amount of RAM assigned to the guest when booting a virtual machine. Defaults to
2G.
KVM=, --kvm=
Configures whether KVM acceleration should be used when booting a virtual machine. Takes a
boolean value or auto. Defaults to auto.
Vsock=, --vsock=
Configures whether to provision a vsock when booting a virtual machine. Takes a boolean value or
auto. Defaults to auto.
VsockConnectionId=, vsock-cid=
Configures the vsock connection ID to use when booting a virtual machine. Takes a number in the
interval [3, 0xFFFFFFFF) or hash or auto. Defaults to auto. When set to hash, the connection ID
will be derived from the full path to the image. When set to auto, mkosi will try to find a free
connection ID automatically. Otherwise, the provided number will be used as is.
TPM=, --tpm=
Configure whether to use a virtual TPM when booting a virtual machine. Takes a boolean value or
auto. Defaults to auto.
CDROM=, --cdrom=
Configures whether to attach the image as a CD-ROM device when booting a virtual machine. Takes a
boolean. Defaults to no.
Removable=, --removable=
Configures whether to attach the image as a removable device when booting a virtual machine.
Takes a boolean. Defaults to no.
Firmware=, --firmware=
Configures the virtual machine firmware to use. Takes one of uefi, uefi-secure-boot, bios, linux,
or auto. Defaults to auto. When set to uefi, the OVMF firmware without secure boot support is
used. When set to uefi-secure-boot, the OVMF firmware with secure boot support is used. When set
to bios, the default SeaBIOS firmware is used. When set to linux, direct kernel boot is used.
See the Linux= option for more details on which kernel image is used with direct kernel boot.
When set to auto, uefi-secure-boot is used if possible and linux otherwise.
FirmwareVariables=, --firmware-variables=
Configures the path to the the virtual machine firmware variables file to use. Currently, this
option is only taken into account when the uefi or uefi-secure-boot firmware is used. If not
specified, mkosi will search for the default variables file and use that instead.
When set to microsoft, a firmware variables file with the Microsoft secure boot certificates
already enrolled will be used.
When set to microsoft-mok, a firmware variables file with the Microsoft secure boot certificates
already enrolled will be extended with a MokList variable containing the secure boot certificate
from SecureBootCertificate=. This is intended to be used together with shim binaries signed by
the distribution and locally signed EFI binaries.
When set to custom, the secure boot certificate from SecureBootCertificate= will be enrolled into
the default firmware variables file.
virt-fw-vars from the virt-firmware project can be used to customize OVMF variable files.
Linux=, --linux=
Set the kernel image to use for qemu direct kernel boot. If not specified, mkosi will use the
kernel provided via the command line (-kernel option) or latest the kernel that was installed into
the image (or fail if no kernel was installed into the image).
Note that when the cpio output format is used, direct kernel boot is used regardless of the
configured firmware. Depending on the configured firmware, qemu might boot the kernel itself or
using the configured firmware.
Drives=, --drive=
Add a drive. Takes a colon-delimited string of format
<id>:<size>[:<directory>[:<options>[:<file-id>]]]. id specifies the ID assigned to the drive.
This can be used as the drive= property in various qemu devices. size specifies the size of the
drive. This takes a size in bytes. Additionally, the suffixes K, M and G can be used to specify
a size in kilobytes, megabytes and gigabytes respectively. directory optionally specifies the
directory in which to create the file backing the drive. options optionally specifies extra
comma-delimited properties which are passed verbatim to qemu’s -drive option. file-id specifies
the ID of the file backing the drive. Drives with the same file ID will share the backing file.
The directory and size of the file will be determined from the first drive with a given file ID.
Example usage:
[Runtime]
Drives=btrfs:10G
ext4:20G
QemuArgs=-device nvme,serial=btrfs,drive=btrfs
-device nvme,serial=ext4,drive=ext4
QemuArgs=
Space-delimited list of additional arguments to pass when invoking qemu.
Ephemeral=, --ephemeral
When used with the shell, boot, or vm verbs, this option runs the specified verb on a temporary
snapshot of the output image that is removed immediately when the container terminates. Taking
the temporary snapshot is more efficient on file systems that support reflinks natively (btrfs or
xfs) than on more traditional file systems that do not (ext4).
Credentials=, --credential=
Set credentials to be passed to systemd-nspawn or the virtual machine respectively when mkosi
shell/boot or mkosi vm are used. This option takes a space separated list of values which can be
either key=value pairs or paths. If a path is provided, if it is a file, the credential name will
be the name of the file. If the file is executable, the credential value will be the output of
executing the file. Otherwise, the credential value will be the contents of the file. If the
path is a directory, the same logic applies to each file in the directory.
Note that values will only be treated as paths if they do not contain the delimiter (=).
KernelCommandLineExtra=, --kernel-command-line-extra=
Set extra kernel command line entries that are appended to the kernel command line at runtime when
booting the image. When booting in a container, these are passed as extra arguments to systemd.
When booting in a VM, these are appended to the kernel command line via the SMBIOS
io.systemd.stub.kernel-cmdline-extra OEM string. This will only be picked up by systemd-boot and
systemd-stub versions newer than or equal to v254.
RuntimeTrees=, --runtime-tree=
Takes a colon-separated pair of paths. The first path refers to a directory to mount into any
machine (container or VM) started by mkosi. The second path refers to the target directory inside
the machine. If the second path is not provided, the directory is mounted at /root/src in the
machine. If the second path is relative, it is interpreted relative to /root/src in the machine.
For each mounted directory, the uid and gid of the user running mkosi are mapped to the root user
in the machine. This means that all the files and directories will appear as if they’re owned by
root in the machine, and all new files and directories created by root in the machine in these
directories will be owned by the user running mkosi on the host.
Note that when using mkosi vm with this feature systemd v254 or newer has to be installed in the
image.
RuntimeSize=, --runtime-size=
If specified, disk images are grown to the specified size when they’re booted with mkosi boot or
mkosi vm. Takes a size in bytes. Additionally, the suffixes K, M and G can be used to specify a
size in kilobytes, megabytes and gigabytes respectively.
RuntimeScratch=, --runtime-scratch=
Takes a boolean value or auto. Specifies whether to mount extra scratch space to /var/tmp. If
enabled, practically unlimited scratch space is made available under /var/tmp when booting the
image with mkosi vm, mkosi boot or mkosi shell.
Note that using this feature with mkosi vm requires systemd v254 or newer in the guest.
RuntimeNetwork=, --runtime-network=
Takes one of user, interface or none. Defaults to user. Specifies the networking to set up when
booting the image. user sets up usermode networking. interface sets up a virtual network
connection between the host and the image. This translates to a veth interface for mkosi shell
and mkosi boot and a tap interface for mkosi vm and mkosi vmspawn.
Note that when using interface, mkosi does not automatically configure the host interface. It is
expected that a recent version of systemd-networkd is running on the host which will automatically
configure the host interface of the link.
RuntimeBuildSources=, --runtime-build-sources=
Mount the build sources configured with BuildSources= and the build directory (if one is
configured) to the same locations in /work that they were mounted to when running the build script
when using mkosi boot or mkosi vm.
RuntimeHome=, --runtime-home=
Mount the current home directory from which mkosi is running to /root when using mkosi boot or
mkosi vm.
UnitProperties=, --unit-property=
Configure systemd unit properties to add to the systemd scopes allocated when using mkosi boot or
mkosi vm. These are passed directly to the --property options of systemd-nspawn and systemd-run
respectively.
SshKey=, --ssh-key=
Path to the X.509 private key in PEM format to use to connect to a virtual machine started with
mkosi vm and built with the Ssh= option enabled via the mkosi ssh command. If not configured and
mkosi.key exists in the working directory, it will automatically be used for this purpose. Run
mkosi genkey to automatically generate a key in mkosi.key.
SshCertificate=, --ssh-certificate=
Path to the X.509 certificate in PEM format to provision as the SSH public key in virtual machines
started with mkosi vm. If not configured and mkosi.crt exists in the working directory, it will
automatically be used for this purpose. Run mkosi genkey to automatically generate a certificate
in mkosi.crt.
Machine=, --machine=
Specify the machine name to use when booting the image. Can also be used to refer to a specific
image when SSH-ing into an image (e.g. mkosi --image=myimage ssh).
Note that Ephemeral= has to be enabled to start multiple instances of the same image.
Register=, --register=
Takes a boolean value or auto. Specifies whether to register the vm/container with
systemd-machined. If enabled, mkosi will fail if it can’t register the vm/container with
systemd-machined. If disabled, mkosi will not register the vm/container with systemd-machined.
If auto, mkosi will register the vm/container with systemd-machined if it is available. Defaults
to auto.
ForwardJournal=, --forward-journal=
Specify the path to which journal logs from containers and virtual machines should be forwarded.
If the path has the .journal extension, it is interpreted as a file to which the journal should be
written. Otherwise, the path is interpreted as a directory to which the journal should be
written.
Note that systemd v256 or newer is required in the virtual machine for log forwarding to work.
Note that if a path with the .journal extension is given, the journal size is limited to 4G.
Configure an output directory instead of file if your workload produces more than 4G worth of
journal data.
SysupdateDirectory=, --sysupdate-directory=
Path to a directory containing systemd-sysupdate transfer definition files that are used by mkosi
sysupdate. If mkosi.sysupdate/ exists in the local directory, it will be used for this purpose as
well.
Note that mkosi sysupdate invokes systemd-sysupdate with --transfer-source= set to the mkosi
output directory. To make use of this in a transfer definition file, set PathRelativeTo=explicit
to have the Path= setting for the transfer source be interpreted relative to the mkosi output
directory. Generally, configuring PathRelativeTo=explicit and Path=/ for the transfer source is
sufficient for the match pattern to be interpreted relative to the mkosi output directory.
[Match] Section
Profiles=
Matches against the configured profiles.
Distribution=
Matches against the configured distribution.
Release=
Matches against the configured distribution release. If this condition is used and no
distribution has been explicitly configured yet, the host distribution and release are used.
Architecture=
Matches against the configured architecture. If this condition is used and no architecture has
been explicitly configured yet, the host architecture is used.
Repositories=
Matches against repositories enabled with the Repositories= setting. Takes a single repository
name.
PathExists=
This condition is satisfied if the given path exists. Relative paths are interpreted relative to
the parent directory of the config file that the condition is read from.
ImageId=
Matches against the configured image ID, supporting globs. If this condition is used and no image
ID has been explicitly configured yet, this condition fails.
ImageVersion=
Matches against the configured image version. Image versions can be prepended by the operators
==, !=, >=, <=, <, > for rich version comparisons according to the UAPI group version format
specification. If no operator is prepended, the equality operator is assumed by default. If this
condition is used and no image version has been explicitly configured yet, this condition fails.
Bootable=
Matches against the configured value for the Bootable= feature. Takes a boolean value or auto.
Format=
Matches against the configured value for the Format= option. Takes an output format (see the
Format= option).
SystemdVersion=
Matches against the systemd version on the host (as reported by systemctl --version). Values can
be prepended by the operators ==, !=, >=, <=, <, > for rich version comparisons according to the
UAPI group version format specification. If no operator is prepended, the equality operator is
assumed by default.
BuildSources=
Takes a build source target path (see BuildSources=). This match is satisfied if any of the
configured build sources uses this target path. For example, if we have a mkosi.conf file
containing:
[Build]
BuildSources=../abc/qed:kernel
and a drop-in containing:
[Match]
BuildSources=kernel
The drop-in will be included.
Any absolute paths passed to this setting are interpreted relative to the current working
directory.
HostArchitecture=
Matches against the host’s native architecture. See the Architecture= setting for a list of
possible values.
ToolsTreeDistribution=
Matches against the configured tools tree distribution.
ToolsTreeRelease=
Matches against the configured tools tree release.
Environment=
Matches against a specific key/value pair configured with Environment=. If no value is provided,
check if the given key is in the environment regardless of which value it has.
This table shows which matchers support globs, rich comparisons and the default value that is matched
against if no value has been configured at the time the config file is read:
Matcher Globs Rich Default
Comparisons
────────────────────────────────────────────────────────────────────────────────────────────
Profiles= no no match fails
Distribution= no no match host distribution
Release= no no match host release
Architecture= no no match host architecture
PathExists= no no n/a
ImageId= yes no match fails
ImageVersion= no yes match fails
Bootable= no no match auto feature
Format= no no match default format
SystemdVersion= no yes n/a
BuildSources= no no match fails
HostArchitecture= no no n/a
ToolsTreeDistribution= no no match the fallback tools tree distribution
(see ToolsTreeDistribution= in [Build])
ToolsTreeRelease= no no match default tools tree release
Environment= no no n/a
[Include]
Include=, --include=, -I
Include extra configuration from the given file or directory. The extra configuration is included
immediately after parsing the setting, except when used on the command line, in which case the
extra configuration is included after parsing all command line arguments.
Note that each path containing extra configuration is only parsed once, even if included more than
once with Include=.
The builtin configs for the mkosi default initrd, default tools tree and default virtual machine
image can be included by including the literal value mkosi-initrd, mkosi-tools or mkosi-vm
respectively.
Note: Include names starting with either of the literals mkosi- or contrib- are reserved for use
by mkosi itself.
[Config] Section
Profiles=, --profile=
Select the given profiles. A profile is a configuration file or directory in the mkosi.profiles/
directory. The configuration files and directories of each profile are included after parsing the
mkosi.conf.d/*.conf drop in configuration.
Dependencies=, --dependency=
The images that this image depends on specified as a comma-separated list. All images configured
in this option will be built before this image.
When this setting is specified for the “main” image, it specifies which subimages should be built.
See the Building multiple images section for more information.
MinimumVersion=, --minimum-version=
The minimum mkosi version required to build this configuration. If specified multiple times, the
highest specified version is used.
ConfigureScripts=, --configure-script=
Takes a comma-separated list of paths to executables that are used as the configure scripts for
this image. See the Scripts section for more information.
PassEnvironment=, --pass-environment=
Takes a list of environment variable names separated by spaces. When building multiple images,
pass the listed environment variables to each individual subimage as if they were “universal”
settings. See the Building multiple images section for more information.
[UKIProfile] Section
The UKIProfile section can be used in UKI profile config files which are passed to the
UnifiedKernelImageProfiles= setting. The following settings can be specified in the UKIProfile section:
Profile=
The contents of the .profile section of the UKI profile. Takes a list of key/value pairs
separated by =. The ID= key must be specified. See the UKI https://uapi-
group.org/specifications/specs/unified_kernel_image/#multi-profile-ukis specification for a full
list of possible keys.
Cmdline=
Extra kernel command line options for the UKI profile. Takes a space delimited list of extra
kernel command line arguments. Note that the final .cmdline section will the combination of the
base .cmdline section and the extra kernel command line arguments specified with this setting.
Specifiers
The current value of various settings can be accessed when parsing configuration files by using
specifiers. To write a literal % character in a configuration file without treating it as a specifier,
use %%. The following specifiers are understood:
Setting Specifier
─────────────────────────────
Distribution= %d
Release= %r
Architecture= %a
Format= %t
Output= %o
OutputDirectory= %O
ImageId= %i
ImageVersion= %v
There are also specifiers that are independent of settings:
Specifier Value
──────────────────────────────────────────────────
%C Parent directory of current config
file
%P Current working directory
%D Directory that mkosi was invoked in
%I Name of the current subimage in
mkosi.images
Finally, there are specifiers that are derived from a setting:
Specifier Value
──────────────────────────────────────────────────
%F The default filesystem of the
configured distribution
Note that the current working directory changes as mkosi parses its configuration. Specifically, each
time mkosi parses a directory containing a mkosi.conf file, mkosi changes its working directory to that
directory.
Note that the directory that mkosi was invoked in is influenced by the --directory= command line
argument.
The following table shows example values for the directory specifiers listed above:
$D/mkosi.conf $D/mkosi.conf.d/abc/abc.conf $D/mkosi.conf.d/abc/mkosi.conf
──────────────────────────────────────────────────────────────────────────────────────
%C $D $D/mkosi.conf.d $D/mkosi.conf.d/abc
%P $D $D $D/mkosi.conf.d/abc
%D $D $D $D
Supported distributions
Images may be created containing installations of the following distributions:
• Fedora Linux
• Debian
• Kali Linux
• Ubuntu
• Arch Linux
• openSUSE
• Mageia
• CentOS
• RHEL
• RHEL UBI
• OpenMandriva
• Rocky Linux
• Alma Linux
• Azure Linux
• None (Requires the user to provide a pre-built rootfs)
In theory, any distribution may be used on the host for building images containing any other
distribution, as long as the necessary tools are available. Specifically, any distribution that packages
apt may be used to build Debian, Kali or Ubuntu images. Any distribution that packages dnf may be used
to build images for any of the RPM-based distributions. Any distro that packages pacman may be used to
build Arch Linux images. Any distribution that packages zypper may be used to build openSUSE images.
Other distributions and build automation tools for embedded Linux systems such as Buildroot, OpenEmbedded
and Yocto Project may be used by selecting the custom distribution, and populating the rootfs via a
combination of base trees, skeleton trees, and prepare scripts.
Currently, Fedora Linux packages all relevant tools as of Fedora 28.
Note that when not using a custom mirror, RHEL images can only be built from a host system with a RHEL
subscription (established using e.g. subscription-manager).
Execution Flow
Execution flow for mkosi build. Default values/calls are shown in parentheses. When building with
--incremental mkosi creates a cache of the distribution installation if not already existing and replaces
the distribution installation in consecutive runs with data from the cached one.
1. Parse CLI options
2. Parse configuration files
3. Run configure scripts (mkosi.configure)
4. If we’re not running as root, unshare the user namespace and map the subuid range configured in
/etc/subuid and /etc/subgid into it.
5. Unshare the mount namespace
6. Remount the following directories read-only if they exist:
• /usr
• /etc
• /opt
• /srv
• /boot
• /efi
• /media
• /mnt
Then, for each image, we execute the following steps:
1. Copy sandbox trees into the workspace
2. Sync the package manager repository metadata
3. Run sync scripts (mkosi.sync)
4. Copy base trees (--base-tree=) into the image
5. Reuse a cached image if one is available
6. Copy a snapshot of the package manager repository metadata into the image
7. Copy skeleton trees (mkosi.skeleton) into image
8. Install distribution and packages into image
9. Run prepare scripts on image with the final argument (mkosi.prepare)
10. Install build packages in overlay if any build scripts are configured
11. Run prepare scripts on overlay with the build argument if any build scripts are configured
(mkosi.prepare)
12. Cache the image if configured (--incremental)
13. Run build scripts on image + overlay if any build scripts are configured (mkosi.build)
14. Finalize the build if the output format none is configured
15. Copy the build scripts outputs into the image
16. Copy the extra trees into the image (mkosi.extra)
17. Run post-install scripts (mkosi.postinst)
18. Write config files required for Ssh=, Autologin= and MakeInitrd=
19. Install systemd-boot and configure secure boot if configured (--secure-boot)
20. Run systemd-sysusers
21. Run systemd-tmpfiles
22. Run systemctl preset-all
23. Run depmod
24. Run systemd-firstboot
25. Run systemd-hwdb
26. Remove packages and files (RemovePackages=, RemoveFiles=)
27. Run SELinux relabel is a SELinux policy is installed
28. Run finalize scripts (mkosi.finalize)
29. Generate unified kernel image if configured to do so
30. Generate final output format
31. Run post-output scripts (mkosi.postoutput)
Scripts
To allow for image customization that cannot be implemented using mkosi’s builtin features, mkosi
supports running scripts at various points during the image build process that can customize the image as
needed. Scripts are executed on the host system as root (either real root or root within the user
namespace that mkosi created when running unprivileged) with a customized environment to simplify
modifying the image. For each script, the configured build sources (BuildSources=) are mounted into the
current working directory before running the script in the current working directory. $SRCDIR is set to
point to the current working directory. The following scripts are supported:
• If mkosi.configure (ConfigureScripts=) exists, it is executed before building the image. This script
may be used to dynamically modify the configuration. It receives the configuration serialized as JSON
on stdin and should output the modified configuration serialized as JSON on stdout. Note that this
script only runs when building or booting the image (build, vm, boot and shell verbs). If a default
tools tree is configured, it will be built before running the configure scripts and the configure
scripts will run with the tools tree available. This also means that the modifications made by
configure scripts will not be visible in the summary output.
• If mkosi.sync (SyncScripts=) exists, it is executed before the image is built. This script may be used
to update various sources that are used to build the image. One use case is to run git pull on various
source repositories before building the image. Specifically, the BuildSourcesEphemeral= setting does
not apply to sync scripts, which means sync scripts can be used to update build sources even if
BuildSourcesEphemeral= is enabled.
• If mkosi.prepare (PrepareScripts=) exists, it is first called with the final argument, right after the
software packages are installed. It is called a second time with the build command line parameter,
right after the build packages are installed and the build overlay mounted on top of the image’s root
directory . This script has network access and may be used to install packages from other sources than
the distro’s package manager (e.g. pip, npm, ...), after all software packages are installed but before
the image is cached (if incremental mode is enabled). In contrast to a general purpose installation,
it is safe to install packages to the system (pip install, npm install -g) instead of in $SRCDIR itself
because the build image is only used for a single project and can easily be thrown away and rebuilt so
there’s no risk of conflicting dependencies and no risk of polluting the host system.
• If mkosi.build (BuildScripts=) exists, it is executed with the build overlay mounted on top of the
image’s root directory. When running the build script, $DESTDIR points to a directory where the script
should place any files generated it would like to end up in the image. Note that make-, automake-, and
meson-based build systems generally honor $DESTDIR, thus making it very natural to build source trees
from the build script. After running the build script, the contents of $DESTDIR are copied into the
image.
• If mkosi.postinst (PostInstallationScripts=) exists, it is executed after the (optional) build tree and
extra trees have been installed. This script may be used to alter the images without any restrictions,
after all software packages and built sources have been installed.
• If mkosi.finalize (FinalizeScripts=) exists, it is executed as the last step of preparing an image.
• If mkosi.postoutput (PostOutputScripts=) exists, it is executed right after all the output files have
been generated, before they are finally moved into the output directory. This can be used to generate
additional or alternative outputs, e.g. SHA256FILES or SBOM manifests.
• If mkosi.clean (CleanScripts=) exists, it is executed right after the outputs of a previous build have
been cleaned up. A clean script can clean up any outputs that mkosi does not know about (e.g.
artifacts from SplitArtifacts=partitions or RPMs built in a build script). Note that this script does
not use the tools tree even if one is configured.
• If mkosi.version exists and is executable, it is run during configuration parsing and populates
ImageVersion= with the output on stdout. This can be used for external version tracking, e.g. with git
describe or date '+%Y-%m-%d'. Note that this script is executed on the host system without any
sandboxing.
• If mkosi.rootpw exists and is executable, it is run during configuration parsing and populates
RootPassword= with the output on stdout. This can be used to randomly generate a password and can be
remembered by outputting it to stderr or by reading $MKOSI_CONFIG in another script
(e.g. mkosi.postoutput). Note that this script is executed on the host system without any sandboxing.
If a script uses the .chroot extension, mkosi will chroot into the image using mkosi-chroot (see below)
before executing the script. For example, if mkosi.postinst.chroot exists, mkosi will chroot into the
image and execute it as the post-installation script.
Instead of a single file script, mkosi will also read all files in lexicographical order from
appropriately named .d directories, e.g. all files in a mkosi.build.d would be used as build scripts.
This is supported by
• mkosi.sync.d,
• mkosi.prepare.d,
• mkosi.build.d,
• mkosi.postinst.d,
• mkosi.finalize.d,
• mkosi.postoutput.d, and
• mkosi.clean.d.
This can be combined with the .chroot extension, e.g. mkosi.build.d/01-foo.sh would be run without
chrooting into the image and mkosi.build.d/02-bar.sh.chroot would be run after chrooting into the image
first.
Scripts executed by mkosi receive the following environment variables:
• $ARCHITECTURE contains the architecture from the Architecture= setting. If Architecture= is not set,
it will contain the native architecture of the host machine. See the documentation of Architecture=
for possible values for this variable.
• $QEMU_ARCHITECTURE contains the architecture from $ARCHITECTURE in the format used by qemu. Useful for
finding the qemu binary ( qemu-system-$QEMU_ARCHITECTURE).
• $DISTRIBUTION contains the distribution from the Distribution= setting.
• $RELEASE contains the release from the Release= setting.
• $DISTRIBUTION_ARCHITECTURE contains the architecture from $ARCHITECTURE in the format used by the
configured distribution.
• $PROFILES contains the profiles from the Profiles= setting as a comma-delimited string.
• $CACHED= is set to 1 if a cached image is available, 0 otherwise.
• $CHROOT_SCRIPT contains the path to the running script relative to the image root directory. The
primary usecase for this variable is in combination with the mkosi-chroot script. See the description
of mkosi-chroot below for more information.
• $SRCDIR contains the path to the directory mkosi was invoked from, with any configured build sources
mounted on top. $CHROOT_SRCDIR contains the value that $SRCDIR will have after invoking mkosi-chroot.
• $BUILDDIR is only defined if mkosi.builddir exists and points to the build directory to use. This is
useful for all build systems that support out-of-tree builds to reuse already built artifacts from
previous runs. $CHROOT_BUILDDIR contains the value that $BUILDDIR will have after invoking
mkosi-chroot.
• $DESTDIR is a directory into which any installed software generated by a build script may be placed.
This variable is only set when executing a build script. $CHROOT_DESTDIR contains the value that
$DESTDIR will have after invoking mkosi-chroot.
• $OUTPUTDIR points to the staging directory used to store build artifacts generated during the build.
$CHROOT_OUTPUTDIR contains the value that $OUTPUTDIR will have after invoking mkosi-chroot.
• $PACKAGEDIR points to the directory containing the local package repository. Build scripts can add
more packages to the local repository by writing the packages to $PACKAGEDIR.
• $ARTIFACTDIR points to the directory that is used to pass around build artifacts generated during the
build and make them available for use by mkosi. This is similar to PACKAGEDIR, but is meant for
artifacts that may not be packages understood by the package manager, e.g. initrds created by other
initrd generators than mkosi. Build scripts can add more artifacts to the directory by placing them in
$ARTIFACTDIR. Files in this directory are only available for the current build and are not copied out
like the contents of $OUTPUTDIR.
mkosi will also use certain subdirectories of an artifacts directory to automatically use their
contents at certain steps. Currently the following two subdirectories in the artifact directory are
used by mkosi:
• io.mkosi.microcode: All files in this directory are used as microcode files, i.e. they are prepended
to the initrds in lexicographical order.
• io.mkosi.initrd: All files in this directory are used as initrds and joined in lexicographical order.
It is recommended, that users of $ARTIFACTDIR put things for their own use in a similar namespaced
directory, e.g. local.my.namespace.
• $BUILDROOT is the root directory of the image being built, optionally with the build overlay mounted on
top depending on the script that’s being executed.
• $WITH_DOCS is either 0 or 1 depending on whether a build without or with installed documentation was
requested (WithDocs=yes). A build script should suppress installation of any package documentation to
$DESTDIR in case $WITH_DOCS is set to 0.
• $WITH_TESTS is either 0 or 1 depending on whether a build without or with running the test suite was
requested (WithTests=no). A build script should avoid running any unit or integration tests in case
$WITH_TESTS is 0.
• $WITH_NETWORK is either 0 or 1 depending on whether a build without or with networking is being
executed (WithNetwork=no). A build script should avoid any network communication in case $WITH_NETWORK
is 0.
• $SOURCE_DATE_EPOCH is defined if requested (SourceDateEpoch=TIMESTAMP,
Environment=SOURCE_DATE_EPOCH=TIMESTAMP or the host environment variable $SOURCE_DATE_EPOCH). This is
useful to make builds reproducible. See SOURCE_DATE_EPOCH for more information.
• $MKOSI_UID and $MKOSI_GID respectively are the uid, gid of the user that invoked mkosi.
• $MKOSI_CONFIG is a file containing a json summary of the settings of the current image. This file can
be parsed inside scripts to gain access to all settings for the current image.
• $IMAGE_ID contains the identifier from the ImageId= or --image-id= setting.
• $IMAGE_VERSION contains the version from the ImageVersion= or --image-version= setting.
Consult this table for which script receives which environment variables:
Variable configure sync prepare build postinst finalize postoutput clean
────────────────────────────────────────────────────────────────────────────────────────────────────────────
ARCHITECTURE ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
QEMU_ARCHITECTURE ✓
DISTRIBUTION ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
DISTRIBUTION_ARCHITECTURE ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
RELEASE ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
PROFILES ✓ ✓ ✓ ✓ ✓ ✓ ✓
CACHED ✓
CHROOT_SCRIPT ✓ ✓ ✓ ✓
SRCDIR ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
CHROOT_SRCDIR ✓ ✓ ✓ ✓
BUILDDIR ✓ ✓ ✓
CHROOT_BUILDDIR ✓
DESTDIR ✓
CHROOT_DESTDIR ✓
OUTPUTDIR ✓ ✓ ✓ ✓
CHROOT_OUTPUTDIR ✓ ✓
BUILDROOT ✓ ✓ ✓ ✓
PACKAGEDIR ✓ ✓ ✓ ✓
ARTIFACTDIR ✓ ✓ ✓ ✓
WITH_DOCS ✓ ✓
WITH_TESTS ✓ ✓
WITH_NETWORK ✓ ✓ ✓ ✓
SOURCE_DATE_EPOCH ✓ ✓ ✓ ✓ ✓
MKOSI_UID ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
MKOSI_GID ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
MKOSI_CONFIG ✓ ✓ ✓ ✓ ✓ ✓ ✓
IMAGE_ID ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
IMAGE_VERSION ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
Additionally, when a script is executed, a few scripts are made available via $PATH to simplify common
usecases.
• mkosi-chroot: This script will chroot into the image and execute the given command. On top of
chrooting into the image, it will also mount various files and directories ($SRCDIR, $DESTDIR,
$BUILDDIR, $OUTPUTDIR, $CHROOT_SCRIPT) into the image and modify the corresponding environment
variables to point to the locations inside the image. It will also mount APIVFS filesystems (/proc,
/dev, ...) to make sure scripts and tools executed inside the chroot work properly. It also
propagates /etc/resolv.conf from the host into the chroot if requested so that DNS resolution works
inside the chroot. After the mkosi-chroot command exits, various mount points are cleaned up.
For example, to invoke ls inside of the image, use the following:
mkosi-chroot ls ...
To execute the entire script inside the image, add a .chroot suffix to the name (mkosi.build.chroot
instead of mkosi.build, etc.).
• For all of the supported package managers (dnf, rpm, apt, dpkg, pacman, zypper), scripts of the same
name are put into $PATH that make sure these commands operate on the image’s root directory with the
configuration supplied by the user instead of on the host system. This means that from a script, you
can do e.g. dnf install vim to install vim into the image.
Additionally, mkosi-install, mkosi-reinstall, mkosi-upgrade and mkosi-remove will invoke the
corresponding operation of the package manager being used to built the image.
• git is automatically invoked with safe.directory=* to avoid permissions errors when running as the root
user in a user namespace.
• useradd and groupadd are automatically invoked with --root=$BUILDROOT when executed outside of the
image.
When scripts are executed, any directories that are still writable are also made read-only (/home, /var,
/root, ...) and only the minimal set of directories that need to be writable remain writable. This is
to ensure that scripts can’t mess with the host system when mkosi is running as root.
Note that when executing scripts, all source directories are made ephemeral which means all changes made
to source directories while running scripts are thrown away after the scripts finish executing. Use the
output, build or cache directories if you need to persist data between builds.
Files
To make it easy to build images for development versions of your projects, mkosi can read configuration
data from the local directory, under the assumption that it is invoked from a source tree. Specifically,
the following files are used if they exist in the local directory:
• The mkosi.skeleton/ directory or mkosi.skeleton.tar archive may be used to insert files into the image.
The files are copied before the distribution packages are installed into the image. This allows
creation of files that need to be provided early, for example to configure the package manager or set
systemd presets.
When using the directory, file ownership is not preserved: all files copied will be owned by root. To
preserve ownership, use a tar archive.
• The mkosi.extra/ directory or mkosi.extra.tar archive may be used to insert additional files into the
image, on top of what the distribution includes in its packages. They are similar to mkosi.skeleton/
and mkosi.skeleton.tar, but the files are copied into the directory tree of the image after the OS was
installed.
When using the directory, file ownership is not preserved: all files copied will be owned by root. To
preserve ownership, use a tar archive.
• The mkosi.sandbox/ directory or mkosi.sandbox.tar archive may be used to configure the package manager
without the files being inserted into the image. If the files should be included in the image
mkosi.skeleton/ and mkosi.skeleton.tar should be used instead.
When using the directory, file ownership is not preserved: all files copied will be owned by root. To
preserve ownership, use a tar archive.
• The mkosi.nspawn nspawn settings file will be copied into the same place as the output image file, if
it exists. This is useful since nspawn looks for settings files next to image files it boots, for
additional container runtime settings.
• The mkosi.cache/ directory, if it exists, is automatically used as package download cache, in order to
speed repeated runs of the tool.
• The mkosi.builddir/ directory, if it exists, is automatically used as out-of-tree build directory, if
the build commands in the mkosi.build scripts support it. Specifically, this directory will be mounted
into the build container, and the $BUILDDIR environment variable will be set to it when the build
scripts are invoked. A build script may then use this directory as build directory, for automake-style
or ninja-style out-of-tree builds. This speeds up builds considerably, in particular when mkosi is
used in incremental mode (-i): not only the image and build overlay, but also the build tree is reused
between subsequent invocations. Note that if this directory does not exist the $BUILDDIR environment
variable is not set, and it is up to the build scripts to decide whether to do an in-tree or an
out-of-tree build, and which build directory to use.
• The mkosi.rootpw file can be used to provide the password for the root user of the image. If the
password is prefixed with hashed: it is treated as an already hashed root password. The password may
optionally be followed by a newline character which is implicitly removed. The file must have an
access mode of 0600 or less. If this file does not exist, the distribution’s default root password is
set (which usually means access to the root user is blocked).
• The mkosi.passphrase file provides the passphrase to use when LUKS encryption is selected. It should
contain the passphrase literally, and not end in a newline character (i.e. in the same format as
cryptsetup and /etc/crypttab expect the passphrase files). The file must have an access mode of 0600
or less.
• The mkosi.crt and mkosi.key files contain an X.509 certificate and PEM private key to use when signing
is required (UEFI SecureBoot, verity, ...).
• The mkosi.output/ directory is used to store all build artifacts.
• The mkosi.credentials/ directory is used as a source of extra credentials similar to the Credentials=
option. For each file in the directory, the filename will be used as the credential name and the file
contents become the credential value, or, if the file is executable, mkosi will execute the file and
the command’s output to stdout will be used as the credential value. Output to stderr will be ignored.
Credentials configured with Credentials= take precedence over files in mkosi.credentials.
• The mkosi.repart/ directory is used as the source for systemd-repart partition definition files which
are passed to systemd-repart when building a disk image. If it does not exist and the
RepartDirectories= setting is not configured, mkosi will default to the following partition definition
files:
00-esp.conf (if we’re building a bootable image):
[Partition]
Type=esp
Format=vfat
CopyFiles=/boot:/
CopyFiles=/efi:/
SizeMinBytes=512M
SizeMaxBytes=512M
05-bios.conf (if we’re building a BIOS bootable image):
[Partition]
# UUID of the grub BIOS boot partition which grubs needs on GPT to
# embed itself into.
Type=21686148-6449-6e6f-744e-656564454649
SizeMinBytes=1M
SizeMaxBytes=1M
10-root.conf
[Partition]
Type=root
Format=<distribution-default-filesystem>
CopyFiles=/
Minimize=guess
Note that if either mkosi.repart/ is found or RepartDirectories= is used, we will not use any of the
default partition definitions.
All these files are optional.
Note that the location of all these files may also be configured during invocation via command line
switches, and as settings in mkosi.conf, in case the default settings are not acceptable for a project.
CACHING
mkosi supports three different caches for speeding up repetitive re-building of images. Specifically:
1. The package cache of the distribution package manager may be cached between builds. This is
configured with the --cache-directory= option or the mkosi.cache/ directory. This form of caching
relies on the distribution’s package manager, and caches distribution packages (RPM, deb, ...) after
they are downloaded, but before they are unpacked.
2. If the incremental build mode is enabled with --incremental, cached copies of the final image and
build overlay are made immediately before the build sources are copied in (for the build overlay) or
the artifacts generated by mkosi.build are copied in (in case of the final image). This form of
caching allows bypassing the time-consuming package unpacking step of the distribution package
managers, but is only effective if the list of packages to use remains stable, but the build sources
and its scripts change regularly. Note that this cache requires manual flushing: whenever the package
list is modified the cached images need to be explicitly removed before the next re-build, using the
-f switch.
3. Finally, between multiple builds the build artifact directory may be shared, using the mkosi.builddir/
directory. This directory allows build systems such as Meson to reuse already compiled sources from a
previous built, thus speeding up the build process of a mkosi.build build script.
The package cache and incremental mode are unconditionally useful. The final cache only apply to uses of
mkosi with a source tree and build script. When all three are enabled together turn-around times for
complete image builds are minimal, as only changed source files need to be recompiled.
Building multiple images
If the mkosi.images/ directory exists, mkosi will load individual subimage configurations from it and
build each of them. Image configurations can be either directories containing mkosi configuration files
or regular files with the .conf extension.
When image configurations are found in mkosi.images/, mkosi will build the images specified in the
Dependencies= setting of the main image and all of their dependencies (or all of them if no images were
explicitly configured using Dependencies= in the main image configuration). To add dependencies between
subimages, the Dependencies= setting can be used as well. Subimages are always built before the main
image.
When images are defined, mkosi will first read the main image configuration (configuration outside of the
mkosi.images/ directory), followed by the image specific configuration. Several “universal” settings
apply to the main image and all its subimages and cannot be configured separately in subimages. The
following settings are universal and cannot be configured in subimages:
• Architecture=
• BuildDirectory=
• BuildSources=
• BuildSourcesEphemeral=
• CacheDirectory=
• CacheOnly=
• Distribution=
• ExtraSearchPaths=
• Incremental=
• LocalMirror=
• Mirror=
• OutputDirectory=
• OutputMode=
• PackageCacheDirectory=
• PackageDirectories=
• Profiles=
• ProxyClientCertificate=
• ProxyClientKey=
• ProxyExclude=
• ProxyPeerCertificate=
• ProxyUrl=
• Release=
• RepartOffline=
• Repositories=
• RepositoryKeyCheck=
• SandboxTrees=
• SourceDateEpoch=
• ToolsTree=
• ToolsTreeCertificates=
• UseSubvolumes=
• SecureBootCertificate=
• SecureBootCertificateSource=
• SecureBootKey=
• SecureBootKeySource=
• VerityCertificate=
• VerityCertificateSource=
• VerityKey=
• VerityKeySource=
• SignExpectedPcrCertificate=
• SignExpectedPcrCertificateSource=
• SignExpectedPcrKey=
• SignExpectedPcrKeySource=
• VolatilePackageDirectories=
• WithNetwork=
• WithTests
• WorkspaceDirectory=
There are also settings which are passed down to subimages but can be overridden. For these settings,
values configured explicitly in the subimage will take priority over values configured on the CLI or in
the main image config. Currently the following settings are passed down to subimages but can be
overridden:
• ImageId=
• ImageVersion=
• SectorSize=
Images can refer to outputs of images they depend on. Specifically, for the following options, mkosi
will only check whether the inputs exist just before building the image:
• BaseTrees=
• ExtraTrees=
• Initrds=
To refer to outputs of a image’s dependencies, simply configure any of these options with a relative path
to the output to use in the output directory of the dependency. Or use the %O specifier to refer to the
output directory.
A good example on how to build multiple images can be found in the systemd repository.
ENVIRONMENT VARIABLES
• $MKOSI_LESS overrides options for less when it is invoked by mkosi to page output.
• $MKOSI_DNF can be used to override the executable used as dnf. This is particularly useful to select
between dnf and dnf5.
• $EPEL_MIRROR can be used to override the default mirror location used for the epel repositories when
Mirror= is used. By default mkosi looks for the epel repositories in the fedora subdirectory of the
parent directory of the mirror specified in Mirror=. For example if the mirror is set to
https://mirror.net/centos-stream mkosi will look for the epel repositories in
https://mirror.net/fedora/epel.
• SYSEXT_SCOPE and CONFEXT_SCOPE can be used to override the default value of the respective
extension-release file when building a sysext or confext. By default the value is set to initrd system
portable.
EXAMPLES
Create and run a raw GPT image with ext4, as image.raw:
# mkosi -p systemd --incremental boot
Create and run a bootable GPT image, as foobar.raw:
$ mkosi -d fedora -p kernel-core -p systemd -p systemd-boot -p udev -o foobar.raw
# mkosi --output foobar.raw boot
$ mkosi --output foobar.raw vm
Create and run a Fedora Linux image in a plain directory:
# mkosi --distribution fedora --format directory boot
Create a compressed image image.raw.xz with SSH installed and add a checksum file:
$ mkosi --distribution fedora --format disk --checksum --compress-output --package=openssh-clients
Inside the source directory of an automake-based project, configure mkosi so that simply invoking mkosi
without any parameters builds an OS image containing a built version of the project in its current state:
$ cat >mkosi.conf <<EOF
[Distribution]
Distribution=fedora
[Output]
Format=disk
[Content]
Packages=kernel,systemd,systemd-udev,openssh-clients,httpd
BuildPackages=make,gcc,libcurl-devel
EOF
$ cat >mkosi.build <<EOF
#!/bin/sh
if [ "$container" != "mkosi" ]; then
exec mkosi-chroot "$CHROOT_SCRIPT" "$@"
fi
cd $SRCDIR
./autogen.sh
./configure --prefix=/usr
make -j `nproc`
make install
EOF
$ chmod +x mkosi.build
# mkosi --incremental boot
# systemd-nspawn -bi image.raw
Different ways to boot with vm
The easiest way to boot a virtual machine is to build an image with the required components and let mkosi
call qemu with all the right options:
$ mkosi -d fedora \
--autologin \
-p systemd-udev,systemd-boot,kernel-core \
build
$ mkosi -d fedora vm
...
fedora login: root (automatic login)
[root@fedora ~]#
The default is to boot with a text console only. In this mode, messages from the boot loader, the
kernel, and systemd, and later the getty login prompt and shell all use the same terminal. It is
possible to switch between the qemu console and monitor by pressing Ctrl-a c. The qemu monitor may for
example be used to inject special keys or shut down the machine quickly. Alternatively the machine can
be shut down using Ctrl-a x.
To boot with a graphical window, add --console=gui:
$ mkosi -d fedora --console=gui qemu
A kernel may be booted directly with mkosi vm -kernel ... -initrd ... -append '...'. This is a bit
faster because no boot loader is used, and it is also easier to experiment with different kernels and
kernel commandlines. Note that despite the name, qemu’s -append option replaces the default kernel
commandline embedded in the kernel and any previous -append specifications.
The UKI is also copied into the output directory and may be booted directly:
$ mkosi vm -kernel mkosi.output/fedora~38/image.efi
When booting using an external kernel, we don’t need the kernel in the image, but we would still want the
kernel modules to be installed.
It is also possible to do a direct kernel boot into a boot loader, taking advantage of the fact that
systemd-boot(7) is a valid UEFI binary:
$ mkosi vm -kernel /usr/lib/systemd/boot/efi/systemd-bootx64.efi
In this scenario, the kernel is loaded from the ESP in the image by systemd-boot.
REQUIREMENTS
mkosi is packaged for various distributions: Debian, Kali, Ubuntu, Arch Linux, Fedora Linux,
OpenMandriva, Gentoo. Note that it has been a while since the last release and the packages shipped by
distributions are very out of date. We currently recommend running mkosi from git until a new release
happens.
mkosi requires a Linux kernel that provides mount_setattr() which was introduces in 5.12.
mkosi currently requires systemd 254 to build bootable disk images.
When not using distribution packages make sure to install the necessary dependencies. For example, on
Fedora Linux you need:
# dnf install btrfs-progs apt dosfstools mtools edk2-ovmf e2fsprogs squashfs-tools gnupg python3 tar xfsprogs xz zypper sbsigntools
On Debian/Kali/Ubuntu it might be necessary to install the ubuntu-keyring, ubuntu-archive-keyring,
kali-archive-keyring and/or debian-archive-keyring packages explicitly, in addition to apt, depending on
what kind of distribution images you want to build.
Note that the minimum required Python version is 3.9.
mkosi needs unrestricted abilities to create and act within namespaces. Some distros restrict creation
of, or capabilities within, user namespaces, which breaks mkosi.
For information about Ubuntu, that implements such restrictions using AppArmor, see
https://ubuntu.com/blog/ubuntu-23-10-restricted-unprivileged-user-namespaces. For other systems, try
researching the kernel.unprivileged_userns_clone or user.max.user_namespace sysctls.
For Ubuntu systems, you can remove the restrictions for mkosi by adapting this snippet to point to your
mkosi binary, copying it to /etc/apparmor.d/path.to.mkosi, and then running systemctl reload apparmor:
abi <abi/4.0>,
include <tunables/global>
/path/to/mkosi flags=(default_allow) {
userns,
}
Frequently Asked Questions (FAQ)
• Why does mkosi vm with KVM not work on Debian/Kali/Ubuntu?
While other distributions are OK with allowing access to /dev/kvm, on Debian/Kali/Ubuntu this is only
allowed for users in the kvm group. Because mkosi unshares a user namespace when running unprivileged,
even if the calling user was in the kvm group, when mkosi unshares the user namespace to run
unprivileged, it loses access to the kvm group and by the time we start qemu we don’t have access to
/dev/kvm anymore. As a workaround, you can change the permissions of the device nodes to 0666 which is
sufficient to make KVM work unprivileged. To persist these settings across reboots, copy
/usr/lib/tmpfiles.d/static-nodes-permissions.conf to /etc/tmpfiles.d/static-nodes-permissions.conf and
change the mode of /dev/kvm from 0660 to 0666.
• How do I add a regular user to an image?
You can use the following snippet in a post-installation script:
useradd --create-home --user-group $USER --password "$(openssl passwd -stdin -6 <$USER_PASSWORD_FILE)"
Note that from systemd v256 onwards, if enabled, systemd-homed-firstboot.service will prompt to create
a regular user on first boot if there are no regular users.
• Why do I see failures to chown files when building images?
When not running as root, your user is not able to change ownership of files to arbitrary owners.
Various distributions still ship files in their packages that are not owned by the root user. When not
running as root, mkosi maps the current user to root when invoking package managers, which means that
changing ownership to root will work but changing ownership to any other user or group will fail.
Note that chown calls are only suppressed when running package managers, but not when running scripts.
If this is required, e.g. for a build script, you can set the MKOSI_CHROOT_SUPPRESS_CHOWN variable to a
true value (1, yes, true) to suppress chown calls in mkosi-chroot and .chroot scripts.
If this behavior causes applications running in your image to misbehave, you can consider running mkosi
as root which avoids this problem. Alternatively, if running mkosi as root is not desired, you can use
unshare --map-auto --map-current-user --setuid 0 --setgid 0 to become root in a user namespace with
more than one user assuming the UID/GID mappings in /etc/subuid and /etc/subgid are configured
correctly. Note that running mkosi as root or with unshare means that all output files produced by
mkosi will not be owned by your current user anymore.
Note that for systemd services that need directories in /var owned by the service user and group, an
alternative to shipping these directories in packages or creating them via systemd-tmpfiles is to use
StateDirectory=, CacheDirectory= or LogsDirectory= in the service file which instructs systemd to
create the directory when it first starts the service.
Alternatively, the z or Z directives for systemd-tmpfiles can be used to chown various directories and
files to their owning user when the system first boots up.
• Why does portablectl inspect <image>/systemd-dissect <image> say my portable service isn’t one?
systemd-dissect andportablectl inspect check for PORTABLE_PREFIXES= in os-release and if the key is
missing, will fail to recognise a portable service as one, showing ✗ under Use as for in the case of
systemd-dissect or n/a under Portable Service for portablectl.
Since there is no good default to set for this key and the generated portable service images will still
attach properly, even when the key is not set, mkosi doesn’t set one.
You can set PORTABLE_PREFIXES= in the os-release file yourself in a postinst script.
REFERENCES
• Primary mkosi git repository on GitHub
• mkosi — A Tool for Generating OS Images introductory blog post by Lennart Poettering
• The mkosi OS generation tool story on LWN
SEE ALSO
systemd-nspawn(1), systemd-repart(8), dnf(8)
mkosi(1)