mkosi - Build Legacy-Free OS Images
mkosi [options...] build
mkosi [options...] clean
mkosi [options...] summary
mkosi [options...] shell [command line...]
mkosi [options...] boot [command line...]
mkosi [options...] qemu
mkosi is a tool for easily building legacy-free OS images. It's a
fancy wrapper around dnf --installroot, debootstrap, pacstrap and
zypper that may generate disk images with a number of bells and
whistles.
The following output formats are supported:
- •
- Raw GPT disk image, with ext4 as root (gpt_ext4)
- •
- Raw GPT disk image, with xfs as root (gpt_xfs)
- •
- Raw GPT disk image, with btrfs as root (gpt_btrfs)
- •
- Raw GPT disk image, with squashfs as read-only root
(gpt_squashfs)
- •
- Plain squashfs image, without partition table, as read-only root
(plain_squashfs)
- •
- Plain directory, containing the OS tree (directory)
- •
- btrfs subvolume, with separate subvolumes for /var, /home,
/srv, /var/tmp (subvolume)
- •
- Tarball (tar)
When a GPT disk image is created, the following additional
options are available:
- •
- A swap partition may be added in
- •
- The image may be made bootable on EFI and BIOS systems
- •
- Separate partitions for /srv and /home may be added in
- •
- The root, /srv and /home partitions may optionally be encrypted with
LUKS.
- •
- A dm-verity partition may be added in that adds runtime integrity data for
the root partition
- •
- Optionally, create an SHA256SUMS checksum file for the result,
possibly even signed via gpg.
- •
- Optionally, place a specific .nspawn settings file along with
the result.
- •
- Optionally, build a local project's source tree in the image and
add the result to the generated image (see below).
- •
- Optionally, share RPM/DEB package cache between multiple
runs, in order to optimize build speeds.
- •
- Optionally, the resulting image may be compressed with XZ.
- •
- Optionally, the resulting image may be converted into a QCOW2 file
suitable for qemu storage.
- •
- Optionally, btrfs' read-only flag for the root subvolume may be set.
- •
- Optionally, btrfs' compression may be enabled for all created
subvolumes.
- •
- By default images are created without all files marked as documentation in
the packages, on distributions where the package manager supports this.
Use the --with-docs flag to build an image with docs added.
The following command line verbs are known:
- build
- This builds the image, based on the settings passed in on the command line
or read from a mkosi.default file, see below. This verb is the
default if no verb is explicitly specified. This command must be
executed as root.
- 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.
- summary
- Outputs a human-readable summary of all options used for building an
image. This will parse the command line and mkosi.default file as
it would do on build, but only output what it is configured for
and not actually build anything.`
- shell
- This builds the image if it is not build yet, and then invokes
systemd-nspawn to acquire an interactive shell prompt in it. If
this verb is used an optional command line may be specified which is
then invoked in place of the shell in the container. Combine
this with -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 boots the image up using
systemd-nspawn. If this verb is used an optional command line may
be specified which is passed as “kernel command line” to the
init system in the image.
- qemu
- Similar to boot but uses qemu to boot up the image,
i.e. instead of container virtualization VM virtualization is used.
This verb is only supported on images that contain a boot loader,
i.e. those built with --bootable (see below). This
command must be executed as root unless the image already exists and
-f is not specified.
- help
- This verb is equivalent to the --help switch documented below:
it shows a brief usage explanation.
The following command line parameters are understood. Note that
many of these parameters can also be set in the mkosi.default file, for
details see the table below.
- --distribution=, -d
- The distribution to install in the image. Takes one of the following
arguments: fedora, debian, ubuntu, arch, opensuse,
mageia, centos, clear. If not specified, defaults to the
distribution of the host.
- --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, CentOS, ..., e.g. 29), or a
distribution version name (in case of Debian, Ubuntu, ..., e.g.
artful). If neither this option, not --distribution= is
specified, defaults to the distribution version of the host.
If the distribution is specified, defaults to a recent version of
it.
- --mirror=, -m
- The mirror to use for downloading the distribution packages. Expects a
mirror URL as argument.
- --repositories=
- Additional package repositories to use during installation. Expects one or
more URLs as argument, separated by commas. This option may be used
multiple times, in which case the list of repositories to use is
combined.
- --architecture=
- The architecture to build the image for. Note that this currently only
works for architectures compatible with the host's architecture.
- --format=, -t
- The image format type to generate. One of directory (for generating OS
images inside a local directory), subvolume (similar, but as a
btrfs subvolume), tar (similar, but a tarball of the image is
generated), gpt_ext4 (a block device image with an ext4 file
system inside a GPT partition table), gpt_xfs (similar, but with an xfs
file system), gpt_btrfs (similar, but with an btrfs file
system), gpt_squashfs (similar, but with a squashfs file system),
plain_squashfs (a plain squashfs file system without a partition
table).
- --output=, -o
- Path for the output image file to generate. Takes a relative or absolute
path where the generated image will be placed. If neither this option nor
--output-dir= is used (see below), the image is generated under
the name image, but its name suffixed with an appropriate file suffix
(e.g. image.raw.xz in case gpt_ext4 is used in combination with
--xz).
- --output-dir=, -O
- Path to a directory where to place all generated artifacts
(i.e. the SHA256SUMS file and similar). If this is not
specified and a directory mkosi.output/ exists in the local directory
it is automatically used for this purpose. If this is not specified and
such a directory does not exist, all output artifacts are placed adjacent
to the output image file.
- --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 -f to delete all build
artifacts from a previous run before re-building the image. If incremental
builds are enabled (see below), 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 (see below), specifying this option
thrice will ensure the package cache is removed too, before the re-build
is initiated. For the clean operation -f 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.
- --bootable, -b
- Generate a bootable image. By default this will generate an image bootable
on UEFI systems. Use --boot-protocols= to select support for a
different boot protocol.
- --boot-protocols=
- Pick one or more boot protocols to support when generating a bootable
image, as enabled with --bootable above. Takes a comma-separated
list of uefi or bios. May be specified more than once in
which case the specified lists are merged. If uefi is
specified the sd-boot UEFI boot loader is used, if bios is
specified the GNU Grub boot loader is used.
- --kernel-command-line=
- Use the specified kernel command line for when building bootable
images.
- --secure-boot
- Sign the resulting kernel/initrd image for UEFI SecureBoot
- --secure-boot-key=
- Path to the PEM file containing the secret key for signing the UEFI kernel
image, if --secure-boot is used.
- --secure-boot-certificate=
- Path to the X.509 file containing the certificate for the signed UEFI
kernel image, if --secure-boot is used.
- --read-only
- Make root file system read-only. Only applies to gpt_ext4, gpt_xfs,
gpt-btrfs, subvolume output formats, and implied on gpt_squashfs
and plain_squashfs.
- --encrypt
- Encrypt all partitions in the file system or just the root file system.
Takes either all or data as argument. If all the root, /home
and /srv file systems will be encrypted using dm-crypt/LUKS
(with its default settings). If data the root file system will
be left unencrypted, but /home and /srv will be encrypted. The
passphrase to use is read from the mkosi.passphrase file in the
current working directory (see below). Note that the UEFI System
Partition (ESP) containing the boot loader and kernel to boot is
never encrypted since it needs to be accessible by the
firmware.
- --verity
- Add an “Verity” integrity partition to the image. If
enabled, the root partition is protected with dm-verity against
off-line modification, the verification data is placed in an
additional GPT partition. Implies --read-only.
- --compress=
- Compress the generated file systems. Only applies to gpt_btrfs,
subvolume, gpt_squashfs, plain_squashfs. Takes one of zlib,
lzo, zstd, lz4, xz or a boolean value as argument. If
the latter is used compression is enabled/disabled and the default
algorithm is used. In case of the squashfs output formats
compression is implied, however this option may be used to select the
algorithm.
- --mksquashfs=
- Set the path to the mksquashfs executable to use. This is useful
in case the parameters for the tool shall be augmented, as the tool
may be replaced by a script invoking it with the right parameters,
this way.
- --xz
- Compress the resulting image with xz. This only applies to
gpt_ext4, gpt_xfs, gpt_btrfs, gpt_squashfs and is
implied for tar. Note that when applied to the block device
image types this means the image cannot be started directly but needs to
be decompressed first. This also means that the shell, boot,
qemu verbs are not available when this option is used.
- --qcow2
- Encode the resulting image as QEMU QCOW2 image. This only applies to
gpt_ext4, gpt_xfs, gpt_btrfs, gpt_squashfs. QCOW2 images can
be read natively by qemu, but not by the Linux kernel.
This means the shell and boot verbs are not available
when this option is used, however qemu will work.
- --hostname=
- Set the image's hostname to the specified name.
- --no-chown
- By default, if mkosi is run inside a sudo environment all generated
artifacts have their UNIX user/group ownership changed to the user which
invoked sudo. With this option this may be turned off and all
generated files are owned by root.
- --incremental, -i
- Enable incremental build mode. This only applies if the two-phase
mkosi.build build script logic is used. In this mode, a
copy of the OS image is created immediately after all OS packages
are unpacked but before the mkosi.build script is invoked in the
development container. Similar a copy of the final image is created
immediately before the build artifacts from the mkosi.build script are
copied in. On subsequent invocations of mkosi with the -i
switch these cached images may be used to skip the OS package
unpacking, thus drastically speeding up repetitive build times.
Note that when this is used and a pair of cached incremental images
exists they are not automatically regenerated, even if options such
as --packages= are modified. In order to force rebuilding of
these cached images, combined -i with -ff, which ensures the cached
images are removed first, and then re-created.
- --package=, -p
- Install the specified distribution packages (i.e. RPM, DEB, ...) in
the image. Takes a comma separated list of packages. This option may be
used multiple times in which case the specified package list is combined.
Packaged specified this way will be installed both in the development and
the final image (see below). Use --build-package= (see below) to
specify packages that shall only be used for the image generated in
the build image, but that shall not appear in the final
image.
- --with-docs
- Include documentation in the image built. By default if the underlying
distribution package manager supports it documentation is not included in
the image built. The $WITH_DOCS environment variable passed to the
mkosi.build script indicates whether this option was used or not,
see below.
- --without-tests, -T
- If set the $WITH_TESTS environment variable is set to 0 when
the mkosi.build script is invoked. This is supposed to be used
by the build script 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 script honors
it.
- --cache=
- Takes a path to a directory to use as package cache for the distribution
package manager used. If this option is not used, but a mkosi.cache/
directory is found in the local directory it is automatically used
for this purpose (also see below). The directory configured
this way is mounted into both the development and the final image
while the package manager is running.
- --extra-tree=
- Takes a path to a directory to copy on top of the OS tree the package
manager generated. Use this to override any default configuration files
shipped with the distribution. If this option is not used, but the
mkosi.extra/ directory is found in the local directory it is
automatically used for this purpose (also see below).
Instead of a directory a tar file may be specified too. In this
case it is unpacked into the OS tree before the package manager is
invoked. 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 does retain full file ownership
and access mode metadata for committed files. If a tar file
mkosi.extra.tar is found in the local directory it automatically used
for this purpose.
- --skeleton-tree=
- Takes a path to a directory to copy into the OS tree before invoking the
package manager. Use this to insert files and directories into the OS tree
before the package manager installs any packages. If this option is not
used, but the mkosi.skeleton/ directory is found in the local
directory it is automatically used for this purpose (also see
below). As with the extra tree logic above, instead of a directory
a tar file may be used too, and mkosi.skeleton.tar is
automatically used.
- --build-script=
- Takes a path to an executable that is used as build script for this image.
If this option is used the build process will be two-phased instead of
single-phased (see below). The specified script is copied onto the
development image and executed inside an systemd-nspawn container
environment. If this option is not used, but the mkosi.build
file found in the local directory it is automatically used for this
purpose (also see below).
- --build-sources=
- Takes a path of a source tree to copy into the development image, if a
build script is used. This only applies if a build script is used, and
defaults to the local directory. Use --source-file-transfer= to
configure how the files are transferred from the host to the
container image.
- --build-dir=
- Takes a path of a directory to use as 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. This directory is mounted into the development image
when the build script is invoked. The build script can find the path to
this directory in the $BUILDDIR environment variable. 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
below).
- --build-package=
- Similar to --package=, but configures packages to install only
in the first phase of the build, into the development image. This
option should be used to list packages containing header files,
compilers, build systems, linkers and other build tools the
mkosi.build script requires to operate. Note that packages listed
here are only included in the image created during the first phase of the
build, and are absent in the final image. use --package= to list
packages that shall be included in both.
- --postinst-script=
- Takes a path to an executable that is invoked inside the final image right
after copying in the build artifacts generated in the first phase of the
build. This script is invoked inside a systemd-nspawn container
environment, and thus does not have access to host resources. If
this option is not used, but an executable mkosi.postinst is found in
the local directory, it is automatically used for this purpose (also see
below).
- --finalize-script=
- Takes a path to an executable that is invoked outside the final image
right after copying in the build artifacts generated in the first phase of
the build, and after having executed the mkosi.postinst script
(see above). This script is invoked directly in the host
environment, and hence has full access to the host's resources.
If this option is not used, but an executable mkosi.finalize is
found in the local directory, it is automatically used for this purpose
(also see below).
- --source-file-transfer=
- Configures how the source file tree (as configured with
--build-sources=) is transferred into the container image during
the first phase of the build. Takes one of copy-all (to copy
all files from the source tree), copy-git-cached (to copy only those
files git-ls-files --cached lists),
copy-git-others (to copy only those files
git-ls-files --others lists), mount to bind mount the source
tree directly. Defaults to copy-git-cached if a git source
tree is detected, otherwise copy-all.
- --with-network
- Enables network connectivity while the build script mkosi.build
is invoked. By default, the build script runs with networking
turned off. The $WITH_NETWORK environment variable is passed to
the mkosi.build build script indicating whether the build is done
with or without this option.
- --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 (also see below).
- --root-size=
- Takes a size in bytes for the root file system. The specified numeric
value may be suffixed with K, M, G to indicate kilo-, mega- and
gigabytes (all to the base of 1024). This applies to output
formats gpt_ext4, gpt_xfs, gpt_btrfs. Defaults to 1G,
except for gpt_xfs where it defaults to 1.3G.
- --esp-size=
- Similar, and configures the size of the UEFI System Partition (ESP). This
is only relevant if the --bootable option is used to generate a
bootable image. Defaults to 256M.
- --swap-size=
- Similar, and configures the size of a swap partition on the image. If
omitted no swap partition is created.
- --home-size=
- Similar, and configures the size of the /home partition. If
omitted no separate /home partition is created.
- --srv-size=
- Similar, and configures the size of the /srv partition. If
omitted no separate /srv partition is created.
- --checksum
- Generate a SHA256SUMS file of all generated artifacts after the
build is complete.
- --sign
- Sign the generated SHA256SUMS using gpg after completion.
- --key=
- Select the gpg key to use for signing SHA256SUMS. This key is
required to exist in the gpg keyring already.
- --bmap
- Generate a bmap file for usage with bmaptool from the generated
image file.
- --password=
- Set the password of the root user. By default the root
account is locked. If this option is not used but a file mkosi.rootpw
exists in the local directory the root password is automatically
read from it.
- --extra-search-paths=
- List of colon-separated paths to look for tools in, before using the
regular $PATH search path.
- --directory=, -C
- Takes a path to a directory. mkosi switches to this directory before
doing anything. Note that the various mkosi.* files are
searched for only after changing to this directory, hence using this
option is an effective way to build a project located in a specific
directory.
- --default=
- Loads additional settings from the specified settings file. Most command
line options may also be configured in a settings file. See the table
below to see which command line options match which settings file option.
If this option is not used, but a file mkosi.default is found in
the local directory it is automatically used for this purpose. If a
setting is configured both on the command line and in the settings
file, the command line generally wins, except for options taking
lists in which case both lists are combined.
- --all, -a
- Iterate through all files mkosi.* in the mkosi.files/ subdirectory,
and build each as if --default=mkosi.files/mkosi.... was invoked.
This is a quick way to build a large number of images in one go.
Any additional specified command line arguments override the
relevant options in all files processed this way.
- --all-directory=
- If specified, overrides the directory the --all logic described
above looks for settings files in. If unspecified, defaults to
mkosi.files/ in the current working directory (see above).
- --version
- Show package version.
- --help, -h
- Show brief usage information.
Most command line parameters may also be placed in an
mkosi.default settings file (or any other file --default= is
used on). The following table shows which command lines parameters
correspond with which settings file options.
Command Line Parameter |
mkosi.default section |
mkosi.default setting |
--distribution=, -d |
[Distribution] |
Distribution= |
--release=, -r |
[Distribution] |
Release= |
--repositories= |
[Distribution] |
Repositories= |
--mirror=, -m |
[Distribution] |
Mirror= |
--architecture= |
[Distribution] |
Architecture= |
--format=, -t |
[Output] |
Format= |
--output=, -o |
[Output] |
Output= |
--output-dir=, -O |
[Output] |
OutputDirectory= |
--force, -f |
[Output] |
Force= |
--bootable, -b |
[Output] |
Bootable= |
--boot-protocols= |
[Output] |
BootProtocols= |
--kernel-command-line= |
[Output] |
KernelCommandLine= |
--secure-boot |
[Output] |
SecureBoot= |
--secure-boot-key= |
[Output] |
SecureBootKey= |
--secure-boot-certificate= |
[Output] |
SecureBootCertificate= |
--read-only |
[Output] |
ReadOnly= |
--encrypt= |
[Output] |
Encrypt= |
--verity= |
[Output] |
Verity= |
--compress= |
[Output] |
Compress= |
--mksquashfs= |
[Output] |
Mksquashfs= |
--xz |
[Output] |
XZ= |
--qcow2 |
[Output] |
QCow2= |
--hostname= |
[Output] |
Hostname= |
--package= |
[Packages] |
Packages= |
--with-docs |
[Packages] |
WithDocs= |
--without-tests, -T |
[Packages] |
WithTests= |
--cache= |
[Packages] |
Cache= |
--extra-tree= |
[Packages] |
ExtraTrees= |
--skeleton-tree= |
[Packages] |
SkeletonTrees= |
--build-script= |
[Packages] |
BuildScript= |
--build-sources= |
[Packages] |
BuildSources= |
--source-file-transfer= |
[Packages] |
SourceFileTransfer= |
--build-directory= |
[Packages] |
BuildDirectory= |
--build-packages= |
[Packages] |
BuildPackages= |
--postinst-script= |
[Packages] |
PostInstallationScript= |
--finalize-script= |
[Packages] |
FinalizeScript= |
--with-network |
[Packages] |
WithNetwork= |
--settings= |
[Packages] |
NSpawnSettings= |
--root-size= |
[Partitions] |
RootSize= |
--esp-size= |
[Partitions] |
ESPSize= |
--swap-size= |
[Partitions] |
SwapSize= |
--home-size= |
[Partitions] |
HomeSize= |
--srv-size= |
[Partitions] |
SrvSize= |
--checksum |
[Validation] |
CheckSum= |
--sign |
[Validation] |
Sign= |
--key= |
[Validation] |
Key= |
--bmap |
[Validation] |
BMap= |
--password= |
[Validation] |
Password= |
--extra-search-paths= |
[Host] |
ExtraSearchPaths= |
Command line options that take no argument are not suffixed with a
= in their long version in the table above. In the mkosi.default file they
are modeled as boolean option that take either 1, yes, true for enabling,
and 0, no, false for disabling.
Images may be created containing installations of the following
OSes.
- •
- Fedora
- •
- Debian
- •
- Ubuntu
- •
- Arch Linux
- •
- openSUSE
- •
- Mageia
- •
- CentOS
- •
- Clear Linux
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 debootstrap may
be used to build Debian or Ubuntu
images. Any distribution that packages dnf may be used to
build Fedora or Mageia images. Any
distro that packages pacstrap may be used to build Arch
Linux images. Any distribution that packages zypper may
be used to build openSUSE images. Any
distribution that packages yum (or the newer replacement
dnf) may be used to build CentOS images.
Currently, Fedora packages all relevant tools as of Fedora
28.
Generated images are legacy-free. This means only
GPT disk labels (and no MBR disk labels) are supported, and
only systemd based images may be generated.
All generated GPT disk images may be booted in a local
container directly with:
-
systemd-nspawn -bi image.raw
Additionally, bootable GPT disk images (as created with the
--bootable flag) work when booted directly by EFI
and BIOS systems, for example in KVM
via:
-
qemu-kvm -m 512 -smp 2 -bios /usr/share/edk2/ovmf/OVMF_CODE.fd -drive format=raw,file=image.raw
EFI bootable GPT images are larger than plain
GPT images, as they additionally carry an EFI system partition
containing a boot loader, as well as a kernel, kernel modules, udev and
more.
All directory or btrfs subvolume images may be booted directly
with:
-
systemd-nspawn -bD image
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:
- •
- mkosi.default may be used to configure mkosi's image building
process. For example, you may configure the distribution to use
(fedora, ubuntu, debian, arch, opensuse, mageia) for
the image, or additional distribution packages to install.
Note that all options encoded in this configuration file may also be
set on the command line, and this file is hence little more than a
way to make sure simply typing mkosi without further parameters
in your source tree is enough to get the right image of your choice
set up. Additionally if a mkosi.default.d directory exists, each
file in it is loaded in the same manner adding/overriding the
values specified in mkosi.default. The file format is inspired
by Windows .ini files and supports multi-line assignments: any
line with initial whitespace is considered a continuation line of
the line before. Command-line arguments, as shown in the help
description, have to be included in a configuration block (e.g.
“[Packages]”) corresponding to the argument group
(e.g. “Packages”), and the argument gets converted as
follows: “–with-network” becomes
“WithNetwork=yes”. For further details see the table
above.
- •
- mkosi.extra/ or mkosi.extra.tar may be respectively a directory or
archive. If any exist all files contained in it are copied over the
directory tree of the image after the OS was installed. This may be
used to add in additional files to an image, on top of what the
distribution includes in its packages. When using a directory file
ownership is not preserved: all files copied will be owned by root. To
preserve ownership use a tar archive.
- •
- mkosi.skeleton/ or mkosi.skeleton.tar may be respectively a
directory or archive, and they work in the same way as
mkosi.extra/mkosi.skeleton.tar. However the files are copied before
anything else so to have a skeleton tree for the OS. This allows to change
the package manager and create files that need to be there before anything
is installed. When using a directory file ownership is not preserved: all
files copied will be owned by root. To preserve ownership use a tar
archive.
- •
- mkosi.build may be an executable script. If it exists the image
will be built twice: the first iteration will be the
development image, the second iteration will be the
final image. The development image
is used to build the project in the current working directory (the
source tree). For that the whole directory is copied
into the image, along with the mkosi.build build script. The
script is then invoked inside the image (via
systemd-nspawn), with $SRCDIR pointing to the
source tree. $DESTDIR points to a directory
where the script should place any files generated it would like to
end up in the final image. Note that
make/automake/meson based build systems
generally honor $DESTDIR, thus making it very natural to
build source trees from the build script. After the
development image was built and the build script ran
inside of it, it is removed again. After that the
final image is built, without any
source tree or build script copied in. However,
this time the contents of $DESTDIR are added into the
image.
When the source tree is copied into the build image, all
files are copied, except for mkosi.builddir/, mkosi.cache/ and
mkosi.output/. That said, .gitignore is respected if the
source tree is a git checkout. If multiple different images shall
be built from the same source tree it's essential to exclude their
output files from this copy operation, as otherwise a version of an
image built earlier might be included in a later build, which is
usually not intended. An alternative to excluding these built images
via .gitignore entries is making use of the mkosi.output/ directory
(see below), which is an easy way to exclude all build
artifacts.
- •
- mkosi.postinst may be an executable script. If it exists it is
invoked as the penultimate step of preparing an image, from within
the image context. It is once called for the
development image (if this is enabled, see above)
with the “build” command line parameter, right before
invoking the build script. It is called a second time for the
final image with the “final” command
line parameter, right before the image is considered complete.
This script may be used to alter the images without any
restrictions, after all software packages and built sources have
been installed. Note that this script is executed directly in the
image context with the final root directory in place, without
any $SRCDIR/$DESTDIR setup.
- •
- mkosi.finalize may be an executable script. If it exists it is
invoked as last step of preparing an image, from the host
system. It is once called for the development image
(if this is enabled, see above) with the “build”
command line parameter, as the last step before invoking the build
script, after the mkosi.postinst script is invoked.
It is called the second time with the “final” command
line parameter as the last step before the image is considered
complete. The environment variable $BUILDROOT points to the
root directory of the installation image. Additional verbs
may be added in the future, the script should be prepared for
that. This script may be used to alter the images without any
restrictions, after all software packages and built sources have
been installed. This script is more flexible than
mkosi.postinst in two regards: it has access to the host
file system so it's easier to copy in additional files or to modify
the image based on external configuration, and the script is run in
the host, so it can be used even without emulation even if the
image has a foreign architecture.
- •
- mkosi.mksquashfs-tool may be an executable script. If it exists
is is called instead of mksquashfs.
- •
- mkosi.nspawn may be an nspawn settings file. If this exists it
will be copied into the same place as the output image file.
This is useful since nspawn looks for settings files next to image
files it boots, for additional container runtime settings.
- •
- mkosi.cache/ may be a directory. If so, it is automatically used
as package download cache, in order to speed repeated runs of the
tool.
- •
- mkosi.builddir/ may be a directory. If so, it is automatically
used as out-of-tree build directory, if the build commands in the
mkosi.build script 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 script is invoked.
The 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 disk images 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 build script to decide whether to do in in-tree
or an out-of-tree build, and which build directory to use.
- •
- mkosi.rootpw may be a file containing the password for the root
user of the image to set. 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).
- •
- mkosi.passphrase may be a passphrase file 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.
If this file does not exist and encryption is requested the user is
queried instead.
- •
- mkosi.secure-boot.crt and mkosi.secure-boot.key may contain an
X.509 certificate and PEM private key to use when UEFI SecureBoot support
is enabled. All EFI binaries included in the image's ESP are signed with
this key, as a late step in the build process.
- •
- mkosi.output/ may be a directory. If it exists, and the image
output path is not configured (i.e. no --output= setting
specified), or configured to a filename (i.e. a path containing no
/ character) all build artifacts (that is: the image itself, the
root hash file in case Verity is used, the checksum and its
signature if that's enabled, and the nspawn settings file if there
is any) are placed in this directory. Note that this directory is
not used if the image output path contains at least one slash, and
has no effect in that case. This setting is particularly useful if
multiple different images shall be built from the same working
directory, as otherwise the build result of a preceding run might
be copied into a build image as part of the source tree (see
above).
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.default, in case the default settings are not acceptable for
a project.
If no build script mkosi.build (see above) is used the
build consists of a single phase only: the final image is generated
as the combination of mkosi.skeleton/ (see above), the unpacked
distribution packages and mkosi.extra/.
If a build script mkosi.build is used the build consists of
two phases: in the the first development phase an image that
includes necessary build tools (i.e. the combination of Packages=
and BuildPackages= is installed) is generated (i.e. the
combination of mkosi.skeleton/ and unpacked distribution
packages). Into this image the source tree is copied and
mkosi.build executed. The artifacts the mkosi.build generates are
saved. Then, the second final phase starts: an image that
excludes the build tools (i.e. only Packages= is installed,
BuildPackages= is not) is generated. This time the build artifacts
saved from the first phase are copied in, and mkosi.extra copied on top,
thus generating the final image.
The two-phased approach ensures that source tree is executed in a
clean and comprehensive environment, while at the same the final image
remains minimal and contains only those packages necessary at runtime, but
avoiding those necessary at build-time.
Note that only the package cache mkosi.cache/ (see below)
is shared between the two phases. The distribution package
manager is executed exactly once in each phase, always starting from
a directory tree that is populated with mkosi.skeleton but
nothing else.
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= 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 an mkosi.build script is used, by enabling incremental build
mode with --incremental (see above) a cached copy of the
development and final images can be made immediately before the build
sources are copied in (for the development image) 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 the mkosi.build build script.
The package cache (i.e. the first item above) is
unconditionally useful. The latter two caches 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: an OS
image rebuilt will be almost as quick to build the source tree
only.
The build script mkosi.build receives the following
environment variables:
- •
- $SRCDIR contains the path to the sources to build.
- •
- $DESTDIR is a directory into which any artifacts generated by
the build script shall be placed.
- •
- $BUILDDIR is only defined if mkosi.builddir 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.
- •
- $WITH_DOCS is either 0 or 1 depending on whether a build
without or with installed documentation was requested (see
--with-docs above). The build script should suppress installation of
any package documentation to $DESTDIR in case $WITH_DOCS is set to
0.
- •
- $WITH_TESTS is either 0or 1 depending on whether a build
without or with running the test suite was requested (see
--without-tests above). The build script should avoid running any unit
or integration tests in case $WITH_TESTS is 0.
- •
- $WITH_NETWORK is either 0or 1 depending on whether a
build without or with networking is being executed (see
--with-network above). The build script should avoid any network
communication in case $WITH_NETWORK is 0.
Create and run a raw GPT image with ext4, as
image.raw:
-
# mkosi
# systemd-nspawn -b -i image.raw
Create and run a bootable btrfs GPT image, as
foobar.raw:
-
# mkosi -t gpt_btrfs --bootable -o foobar.raw
# systemd-nspawn -b -i foobar.raw
# qemu-kvm -m 512 -smp 2 -bios /usr/share/edk2/ovmf/OVMF_CODE.fd -drive format=raw,file=foobar.raw
Create and run a Fedora image into a plain directory:
-
# mkosi -d fedora -t directory -o quux
# systemd-nspawn -b -D quux
Create a compressed image image.raw.xz and add a checksum
file, and install SSH into it:
-
# mkosi -d fedora -t gpt_squashfs --checksum --xz --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.default <<EOF
[Distribution]
Distribution=fedora
Release=24
[Output]
Format=gpt_btrfs
Bootable=yes
[Packages]
Packages=openssh-clients httpd
BuildPackages=make gcc libcurl-devel
EOF
# cat > mkosi.build <<EOF
#!/bin/sh
cd $SRCDIR
./autogen.sh
./configure --prefix=/usr
make -j `nproc`
make install
EOF
# chmod +x mkosi.build
# mkosi
# systemd-nspawn -bi image.raw
To create a Fedora image with hostname:
-
# mkosi -d fedora --hostname image
Also you could set hostname in configuration file:
-
# cat mkosi.default
...
[Output]
Hostname=image
...
mkosi is packaged for various distributions: Debian, Ubuntu, Arch
(in AUR), Fedora. It is usually easiest to use the distribution package.
The current version requires systemd 233 (or actually,
systemd-nspawn of it).
When not using distribution packages make sure to install the
necessary dependencies. For example, on Fedora you need:
-
dnf install arch-install-scripts btrfs-progs debootstrap dosfstools edk2-ovmf e2fsprogs squashfs-tools gnupg python3 tar veritysetup xfsprogs xz zypper sbsigntools
On Debian/Ubuntu it might be necessary to install the
ubuntu-keyring, ubuntu-archive-keyring and/or
debian-archive-keyring packages explicitly, in addition to
debootstrap, depending on what kind of distribution images you want
to build. debootstrap on Debian only pulls in the Debian keyring on
its own, and the version on Ubuntu only the one from Ubuntu.
Note that the minimum required Python version is 3.6.
- •
- Primary mkosi git repository on GitHub
(https://github.com/systemd/mkosi/)
- •
- mkosi — A Tool for Generating OS Images
(http://0pointer.net/blog/mkosi-a-tool-for-generating-os-images.html)
introductory blog post by Lennart Poettering
- •
- The mkosi OS generation tool (https://lwn.net/Articles/726655/) story on
LWN