Claylinux is a set of tools to build Linux bootable images using docker. It can produce raw disk images (.img
),
CDROM/ISO images (.iso
), pure EFI binaries (.efi
), ...
This project is currently a WORK IN PROGRESS, some breaking changes may happen at any time.
The Linux OS building process is the following:
- start from a base docker image which contains both the Linux OS filesystem and a Linux kernel. For example, you can
use the
claylinux/alpine-lts
image which correspond to a Alpine Linux OS with alinux-lts
kernel. - add software & configuration files to the image using a Dockerfile.
- use the
claylinux/builder
image to generate a bootable image from the docker image you just built.
Here is an example of Dockerfile which builds a custom Alpine Linux image with nginx
installed:
# Initialize the OS
FROM claylinux/alpine-lts:latest AS system
RUN apk add --no-cache nginx && rc-update add nginx default
# =========================================================
# Generate the OS image
FROM claylinux/builder:latest AS build
RUN --mount=from=system,target=/system build-image --format raw
# =========================================================
# Extract the files from the /out directory into a new image
FROM scratch AS output
COPY --from=build /out /
Build the OS image with this command:
docker buildx build --output=out .
A claylinux.img
file is generated into the out/
directory, which is a bootable disk image. You can burn this image
on a USB key or a hard drive using for example dd on Linux, or
Rufus on Microsoft Windows. Then you can boot a machine on this media and use the Linux OS
you built.
Since the OS image is built using docker, the /etc/hosts
file is already used by docker to provide the networking to
the build container, so it can't be used as the /etc/hosts
file of the target OS. And it's the same for the
/etc/resolv.conf
file. So, if you want to change the /etc/hosts
or /etc/resolv.conf
file in your target OS,
please edit the /etc/hosts.target
or /etc/resolv.conf.target
file, which will be used as /etc/hosts
or
/etc/resolv.conf
in the target OS.
There are a couple of things to know when using the claylinux tool (and some traps that you can fall into) which are detailed here:
- The whole operating system will be loaded into RAM and will run from there. So you should keep your image size minimal and avoid cluttering your OS filesystem, as it will eat up RAM.
- Due to point 1, no firmwares are added by default into the base images since they take much space. So, depending on
the target machine you'll boot your OS on, you'll have to add some firmwares manually into your image. For Alpine Linux,
the firmwares are found into the
linux-firmware-*
packages. You can easily identify which firmwares are missing by looking for the firmware load errors in thedmesg
output. Note that no additional firmware is needed for virtual machine OSes using thevirt
kernels. - If you need to add big files into your system, you'd better put them on a persistent filesystem that will be
mounted in
/etc/fstab
instead of putting them into the OS image. - Also, due to point 1, every change you make on the root filesystem will be lost after a reboot. If you need to
persist some changes, add some mount points to persistent disks in
/etc/fstab
and use them. - The kernel will start your operating system using a minimal
init
script. We don't use the Linux distribution's initramfs mechanisms (such as mkinitfs, mkinitramfs, dracut, ...) as they generally require the root filesystem to be located on a separated partition/disk. Instead, we bundle everything in a single.efi
file. - But thanks to 4 and 1, there's only one single
.efi
file to sign for Secure Boot, which contains both the kernel, the initramfs and the OS userland filesystem, and which can't be falsified. So it's pretty secure.
To build the claylinux images, use:
docker buildx bake
And run some sanity tests with:
docker buildx bake test
Finally, you can build a test OS image & launch it in a qemu emulator using the following command:
docker compose run --rm emulator
Or, if you have kvm enabled on your docker host:
docker compose run --rm emulator-accel