# IncusOS is a Debian based operating system with exactly one job

> IncusOS is an immutable OS image dedicated to running Incus, built from Debian 13 with mkosi and aimed at a fast, safe and reliable Incus server. The design puts the security assumptions in the boot path, with UEFI Secure Boot and TPM 2.0 carrying both boot security and disk encryption, and the image is published through a staging channel that a human promotes once it has been validated.

**lxc/incus-os** — Immutable Linux OS to run Incus

- Repository: https://github.com/lxc/incus-os
- Website: https://linuxcontainers.org/incus-os/
- Stars: 1,172 · Forks: 93
- Language: Go
- License: Apache-2.0
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/lxc-incus-os

## One workload, one image

IncusOS is described as an immutable OS image dedicated to running Incus, and that single sentence decides almost everything about the project. It is based on Debian 13 and built with mkosi, and it can be installed on modern amd64 and arm64 systems, so it covers both the common server architecture and the ARM boards that show up in edge and homelab hardware. The stated goal is a very fast, safe and reliable way to run an Incus server, and the word immutable is doing the work. The host is not a general purpose Linux installation that happens to have Incus on it, it is a closed image that the project builds and signs, and the operators of the containers inside it do not get to change it. The documentation covers both physical installation and running IncusOS on a variety of virtual machine platforms, which is what makes it usable for a test environment as well as a production server.

## Secure Boot and TPM carry the security story

The project states that it has a strong focus on security and actively relies on UEFI Secure Boot and TPM 2.0 for boot security and disk encryption. That is a specific architectural commitment rather than a slogan. Secure Boot means the firmware refuses to run a boot chain that is not signed by a key the firmware trusts, which is what makes an immutable image meaningful, since the guarantee is not only that the operating system does not change but that nobody else can change it either. The TPM adds the disk encryption half, and it is the component that turns a stolen machine from a data leak into a locked device, provided the sealing of the keys is done properly. The practical consequence for anyone evaluating this is a hardware requirement list, since both features need firmware support, and a support question, because older or unusual hardware may offer one without the other. The project's own getting started documentation is the place to check what it expects from a board.

## This repository builds the image, it does not run Incus

The development section makes the repository's role explicit: it includes all the sources used to build the production IncusOS images. The publication flow is a small pipeline with a human in it, and it is worth following because it explains the channel names you will meet. Pushing a new tag to the repository kicks off a full image build, that build is then downloaded and validated by the publishing server, and the image becomes available in the `testing` channel. It stays there until it is manually validated and promoted to the `stable` channel. So `testing` and `stable` are not development and production branches of a codebase, they are release channels for an operating system image, and the promotion step is a person deciding the image is good. The build logs for the most recent images are in the build workflow of the repository, and the resulting images are published to images.linuxcontainers.org/os/. The last push to the repository was on 2026-10-18.

## A daily test suite and a weekly certificate run

Testing an operating system image is a different problem from testing a library, and the workflow files show the two tiers the project uses. There is a daily test that exercises most of the API endpoints and runs tests that would be impractical, because too slow, to run on every pull request. That division is the interesting part, since the fast suite runs per change and the slow suite runs on a schedule, which is the only way to keep both. Alongside it there is a weekly certificate end to end test workflow, and the certificate in that name is the interesting word, since it points at the installed operating system validating the keys it will boot with, which is exactly the part that a unit test cannot cover. The upshot for a user is that the `stable` channel exists partly because of these runs, and the `testing` channel is where an image lands after the build is validated but before the longer tests have had time to say anything about it.

## The Go side is a daemon and five small tools

Most of the tree is image definition, but the `incus-osd/` directory holds Go code and the Makefile shows what is in it. The main program is the operating system daemon, built from `cmd/incus-osd`:

```bash
cd incus-osd && go build ./cmd/incus-osd
cd incus-osd && go build ./cmd/flasher-tool
cd incus-osd && go build ./cmd/generate-manifests
cd incus-osd && go build ./cmd/image-publisher
cd incus-osd && go build ./cmd/initrd-utils
```

The names describe the pipeline. The flasher tool writes the image to a device, which is the physical installation path. The manifest generator produces the manifests that describe the image contents, and the image publisher is the component that hands a built image to the publishing server for the validation and promotion flow described above. The initrd utilities are the piece that turns a kernel and an initrd into something the bootloader can run, and one of the Makefile targets packages them into a Debian package with debuild, so the initrd tooling is distributed the same way the rest of Debian is. The Makefile also derives the architecture from the machine it runs on and pulls the image identifier out of the mkosi configuration, so a build machine is the same architecture as the target by default.

## The mkosi tree is the image definition

The top level of the repository is a set of mkosi inputs, and the names map onto what mkosi does. `mkosi.conf` is the main configuration and holds the image identifier the Makefile reads. `mkosi.images/` holds the image definitions, `mkosi.packages/` holds the packages that go into the image, and `mkosi.extra/` holds extra content. There is a separate `mkosi.initrd.conf` for the initrd and a `mkosi.repart/` directory, which is for disk partition definitions, and `mkosi.sandbox/` for the sandbox setup, plus `mkosi.version` to pin the version. A `patches/` directory holds the changes applied on top of the upstream packages, and `app-build/` and `scripts/` hold the application build and the helper scripts. The `test/` directory and a `doc/` directory with a Sphinx setup, referenced by the SPHINXENV and SPHINXPIPPATH variables in the Makefile, complete the picture. The clean target shows how much of this is generated output, since it removes the cache, the certificate directory, the mkosi output directory, the tools and the built packages, and then runs the mkosi clean itself.

## Documentation, agent instructions and the licence

The remaining top level files describe how the project is run rather than what it contains. There is a `CONTRIBUTING.md` and a `CODE_OF_CONDUCT.md`, an `AGENTS.md` for coding agents working in the tree, and the full documentation lives on the project's own site rather than in the repository, with the getting started page and the contribution guidelines both hosted at linuxcontainers.org/incus-os/docs/main. The project is released under the Apache 2.0 licence, with the text in the `COPYING` file. There are no published GitHub releases, which is consistent with the way the project ships, since the artifacts are operating system images published to a channel rather than versioned archives attached to tags, and the tags in this repository are the trigger for a build rather than a downloadable release. The repository also carries a Makefile at the root, so the whole build is reproducible from a checkout, which is the main practical argument for reading the tree rather than just the images.

## Conclusion

IncusOS suits an operator who wants to run an Incus server on a dedicated machine and is willing to give up the ability to install packages on the host, because the immutability and the signed boot chain are the point. It is a poor fit for a general purpose machine, since the image exists to run Incus and the documentation points at physical installation or a virtual machine platform rather than a desktop. Before you plan an installation, check three things: that your hardware supports UEFI Secure Boot and TPM 2.0, because the security model leans on both, that you are comfortable with a two stage image release, where a tagged build lands in the testing channel and only a manually validated build is promoted to stable, and the state of the project, with the last push on 2026-10-18 and the images published at images.linuxcontainers.org/os/.

## FAQ

### What is IncusOS and what is it built on?

It is an immutable operating system image dedicated to running Incus, based on Debian 13 and built with mkosi. It installs on modern amd64 and arm64 systems and is intended to give a fast, safe and reliable way to run an Incus server.

### How are IncusOS images released?

Pushing a new tag to the repository triggers a full image build, which is downloaded and validated by the publishing server and then placed in the testing channel. The image stays there until it is manually validated and promoted to the stable channel, and the images themselves are published at images.linuxcontainers.org/os/.

### What hardware does IncusOS need for its security model?

The project relies on UEFI Secure Boot for boot security and on TPM 2.0 for boot security and disk encryption, so both have to be present and supported by the firmware for the guarantees to hold.

### What is incus-osd and what other tools are in the repository?

The incus-osd directory holds the Go code, and the Makefile builds the operating system daemon from cmd/incus-osd along with a flasher tool, a manifest generator, an image publisher and initrd utilities. The initrd utilities are additionally packaged into a Debian package with debuild.

### How is IncusOS tested?

A daily test exercises most of the API endpoints and runs tests that would be too slow for every pull request, and there is a weekly certificate end to end test workflow. The fast suite runs per change and the slow suite on a schedule.

## Sources

- [Issues](https://github.com/lxc/incus-os/issues)
- [License: Apache-2.0](https://github.com/lxc/incus-os/blob/main/LICENSE)
- [lxc/incus-os on GitHub](https://github.com/lxc/incus-os)
- [Project website](https://linuxcontainers.org/incus-os/)
- [README](https://github.com/lxc/incus-os/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/lxc-incus-os
