Self-hosted service
linuxkit/linuxkit avatar
linuxkit/linuxkit

LinuxKit: building minimal, immutable Linux images from container YAML

A toolkit for building secure, portable and lean operating systems for containers

8,653 stars1,024 forksGoApache-2.0

At a glance

What is it?
LinuxKit turns a YAML file listing a kernel, an init image, onboot containers and services into a bootable VM or cloud disk image. It suits people who need to bake an OS rather than configure one, and it is the wrong tool if you want a general-purpose distro you can log into and mutate.
Who is it for?
Adopt LinuxKit if you ship an appliance, an edge node or a Kubernetes host and want the OS to be a build artifact you can regenerate rather than a machine you patch in place. Do not adopt it if you expect a shell you can log into and upgrade package by package, or if you need a distribution with a package manager and a support contract.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 8 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem LinuxKit solves: an OS you build, not one you configure

Most Linux distributions are designed to be installed once and then changed: you add packages, edit configs, patch the kernel and let the machine drift. LinuxKit inverts that. The README describes it as "a toolkit for building custom minimal, immutable Linux distributions", with everything replaceable and customisable, completely stateless, and persistent storage attached only if you want it. The unit of work is a YAML file, and the output is an image.

The audience is narrow and fairly specific. The README lists clustered applications and container orchestration as the target, and says the design draws on the experience of building Docker Editions but was redesigned as a general-purpose toolkit. If you run Kubernetes on hardware you control, or you ship a device that boots straight into containers, the model fits. If you want a server you can SSH into and apt-get your way out of trouble, it does not. There is no package manager in the image by default, because the image is meant to be rebuilt, not repaired.

How the YAML maps to a bootable image

The README's yaml specification section is the clearest description of the mechanism, and it is short. Four keys carry the weight. `kernel` names a Docker image containing a kernel and a filesystem tarball, for example modules. `init` names the base init process image, which is unpacked as the base system and contains init, containerd, runc and a few tools. `onboot` is a list of system containers executed sequentially in order, expected to terminate quickly. `services` is the set of system services that normally run for the whole time the system is up. A fifth key, `files`, adds extra files to the image.

That ordering matters more than it looks. Because onboot entries run in sequence and are expected to exit, they are the place for one-shot setup: formatting a volume, loading a module, writing a config file before a service starts. Services are the long-lived processes. Both are containers, which is why the README says the toolkit is "built with containers, for running containers". The build step resolves those images and assembles them into the requested artifact format, which is why `--format raw-bios` and `--format iso-efi` change the output without changing the YAML.

Installing the linuxkit CLI and building the example image

The README gives three install routes. If you have Go, `go install` is the shortest path and puts the binary in your Go bin directory. The repository also supports a plain `make` build that writes the tool into `bin/`, and a Homebrew tap that the README summarises in two commands. Pick one; the rest of this section assumes the binary is on your PATH.

bash
go install github.com/linuxkit/linuxkit/src/cmd/linuxkit@latest

The Homebrew route is the macOS-friendly alternative, and the README notes it installs the HEAD revision rather than a tagged release.

bash
brew tap linuxkit/linuxkit
brew install --HEAD linuxkit

With the tool installed, the README's first real use is building the example configuration that ships in the repository root. Run it from a checkout, since it reads `linuxkit.yml` from the working directory.

bash
linuxkit build linuxkit.yml

To get something you can actually boot rather than a default artifact, the README shows selecting an output format explicitly. A raw BIOS disk image is the usual choice for a local hypervisor.

bash
linuxkit build --format raw-bios linuxkit.yml

Once the image exists, `linuxkit run <name>` or `linuxkit run <name>.<format>` executes it, picking a backend for your platform or letting you choose one such as VMware. `linuxkit run --help` lists the options. Note that the build requirements are real: the README lists GNU make, Docker and optionally qemu for a container-based source build, and go, make plus two lint tools for `make local`.

Platform coverage is broad, but the format list is not uniform

The README enumerates supported platforms in two groups. Local hypervisors cover Virtualization.Framework on macOS for x86_64 and arm64, HyperKit on macOS for x86_64, Hyper-V on Windows for x86_64, qemu across macOS, Linux and Windows for x86_64, arm64 and s390x, and VMware on macOS and Windows for x86_64. Cloud platforms cover AWS, Google Cloud, Azure, OpenStack and Scaleway, all listed as x86_64 only. Baremetal covers Equinix Metal for x86_64 and arm64, and Raspberry Pi Model 3b for arm64.

Read that table as a constraint rather than a feature list. s390x appears only under qemu. The cloud entries are all x86_64, so an arm64 cloud image is not documented here. Raspberry Pi support is pinned to one board, the Model 3b. If your target is not on the list, you are outside what the README claims, and the per-platform documents under `docs/` are the place to check before you invest in a YAML file. The repository also carries an `examples/` directory with platform-specific files such as `platform-aws.yml`, `platform-gcp.yml` and `platform-equinixmetal.arm64.yml`, which is a faster starting point than writing a platform stanza from scratch.

Where LinuxKit is the wrong choice

Immutability is a promise with a cost. The README states the system is completely stateless, with persistent storage attachable. That means anything you would normally fix with a shell on a running box has to become a change to the YAML and a rebuild. A one-line config tweak turns into a build, a push and a redeploy. For a fleet that is fine. For a single long-lived server that a human administers, it is friction with no payoff.

The second limitation is the documentation's own honesty about reproducibility. The README lists "Designed to create reproducible builds" with a link to `docs/reproducible-builds.md` and the marker `[WIP]`. If your compliance story depends on bit-for-bit identical rebuilds, the project is telling you that work is not finished. Verify it yourself against your own YAML before you rely on it.

The third is the abandoned management path. The README mentions Infrakit as an example of external tooling, then notes it was renamed to deploykit and archived in 2019. The general claim that LinuxKit is designed to be managed by external tooling still stands, but the specific example the README gives is dead. Expect to wire up your own provisioning, and treat the `projects/` and `contrib/` directories as a mix of experiments rather than a supported control plane.

LinuxKit compared with Buildroot and Yocto

The obvious alternatives for building a custom Linux image are Buildroot and the Yocto Project, and the difference is the packaging model rather than the output. Buildroot and Yocto build a root filesystem from source recipes: you select packages, they cross-compile them, and you get an image. The dependency graph is source-level and the build is long. LinuxKit composes the root filesystem from OCI images. The kernel is a Docker image, init is a Docker image, onboot and services are Docker images. You are not compiling userspace; you are assembling images that were built elsewhere, which is why the README describes the toolkit as built with containers for running containers.

That has a practical consequence. If a component already exists as a container image, adding it to a LinuxKit image is a YAML entry. In Buildroot or Yocto, it is a recipe and a rebuild. The trade runs the other way for anything that is not containerised: a board-specific driver, a bootloader tweak, a library that only exists as source. LinuxKit gives you a kernel image and a filesystem tarball and expects you to supply them; the README points at `kernel/` for the example kernels and `pkg/init/` for the init image. The repository also links a separate `linuxkit/linux` tree with LinuxKit kernel branches, which is where kernel-level work happens. If your problem is deep userspace customisation, the source-based toolchains are the better fit. If your problem is assembling a known-good set of containers into a bootable disk, LinuxKit is the shorter path.

Licence, maintenance and what an upgrade costs you

LinuxKit is licensed under Apache-2.0, and the repository carries `LICENSE` and `NOTICE` files at the top level. Apache-2.0 is permissive and includes an explicit patent grant, which matters if you redistribute images built with the toolkit. The images you build are a separate question: their licences come from the kernel, init and service images your YAML references, not from LinuxKit itself. Read the `NOTICE` file and audit the image references in your YAML before you ship a product. This is a description of the licence text, not legal advice.

The repository is not archived, and the last push was on 2026-09-08. Recent releases are v1.8.0 on 2025-09-02, v1.8.1 on 2025-09-04 and v1.8.2 on 2025-09-16. The Makefile pins its build dependencies to specific commits rather than floating tags: `GO_COMPILE=linuxkit/go-compile:985a9db72a7e6941de5e1eb71c2b41b76bf0556f`, `RTF_COMMIT=1118e08445438dc37ec62b4c1e216918b3d804d2` and `MT_COMMIT=bfbd11963b8e0eb5f6e400afaebeaf39820b4e90`. That pinning makes builds more repeatable, but it also means the toolchain you build with is a fixed point you have to bump deliberately.

Upgrade cost has two parts. The CLI is a single Go binary, so replacing it is cheap. The images your YAML points at are not: a new kernel or init image changes the boot path, and the test suite is the only thing standing between you and a broken image. The README describes running it with `rtf` and `expect` installed, invoked from the `test` directory with `rtf -v run -x`, with results written to `_results`. Run that suite against your own YAML after any kernel or init bump, not just against the upstream defaults.

Editorial conclusion

Adopt LinuxKit if you ship an appliance, an edge node or a Kubernetes host and want the OS to be a build artifact you can regenerate rather than a machine you patch in place. Do not adopt it if you expect a shell you can log into and upgrade package by package, or if you need a distribution with a package manager and a support contract. Before committing, verify that your target platform appears in the supported list in the README, that the kernel and init images your YAML references actually exist in a registry you can reach, and that your team can carry a Go toolchain plus Docker for the build. The project's own documentation still marks reproducible builds as WIP, so treat bit-for-bit rebuilds as an open question rather than a guarantee.

Frequently asked questions

Where can I get a Linux operating system?

LinuxKit is not a Linux distribution you download and install. The README describes it as a toolkit for building custom minimal, immutable Linux distributions, and it tells you to build the linuxkit tool yourself with make, install it with go install, or use the Homebrew tap.

Is Linux a free operating system?

LinuxKit itself is licensed under Apache-2.0, with LICENSE and NOTICE files at the top level of the repository. The images you build carry their own licences, which come from the kernel, init and service images your YAML references rather than from LinuxKit.

What is Linux and how does it work?

LinuxKit is a narrower thing than Linux: it assembles a bootable image from a YAML file that names a kernel Docker image, an init image containing init, containerd and runc, onboot containers that run in sequence and exit, and services that run for the life of the system.

What are the common uses of Linux?

The README states LinuxKit is designed for building and running clustered applications, including container orchestration such as Docker or Kubernetes. It also lists support for booting on local hypervisors, cloud platforms and baremetal, including Equinix Metal and Raspberry Pi Model 3b.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. linuxkit/linuxkit on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/linuxkit-linuxkit.svg)](https://hysenlabs.com/projects/linuxkit-linuxkit)