larprober logo, an ink bottle with three strokes rising from it larprober
01

A Linux distribution that installs itself

Leptocline

A live ISO that boots on BIOS and UEFI, installs itself with a graphical installer, and carries 82 security tools plus its own command line utilities.

Year
2026
Type
Linux distribution
Stack
Debian 13, live-build, Calamares, GitHub Actions
Status
Public, CI green

github.com/larprober/leptocline

The brief

Build a Linux distribution that is genuinely its own thing: it boots on real hardware, installs from a graphical installer, ships a curated tool set, and carries branding all the way through the boot menu, the desktop and the installer.

What shipped

  • A hybrid live ISO of about 2.9 GB that boots under both BIOS and UEFI.
  • 82 security tools, verified by unpacking the ISO squashfs rather than by trusting the build chroot.
  • Java 21 and Prism Launcher, unpacked into the image by a build hook.
  • Calamares as a graphical installer, with matching branding, plus a Turkish keyboard layout by default.
  • Two custom command line utilities and a system information tool built for the distribution.
  • Debian packaging that produces a base and a desktop metapackage, with dependencies generated from the package lists.
  • A GitHub Actions workflow that builds the packages and the full ISO on every push, in roughly 27 minutes per run.
The Leptocline build pipeline Configuration feeds a chroot, which is packed into a squashfs, wrapped into a hybrid ISO and uploaded as a release. Verification reads the squashfs rather than the chroot, and continuous integration runs the whole pipeline in about 27 minutes. Every push rebuilds the whole image about 27 minutes Config 8 suite vars Chroot packages, hooks Squashfs the filesystem ISO BIOS and UEFI Release uploaded verify here, not in the chroot the whole pipeline runs in a privileged Debian container, because the runner's own fork is missing the flags
A fast repack never runs the chroot hooks, so a broken hook can pass locally and fail only in a full build. That is the argument for continuous integration that builds the real 3 GB image rather than a shortened one.

The parts that were actually hard

live-build splits the suite across eight variables

The version in use keeps separate suite settings for the chroot, the binary image and the installer, each with a parent twin, and every one of them defaults to testing. Set only the obvious one and the build quietly hands back stock Debian with none of the intended packages. All eight are now named explicitly from a single variable.

Fast builds hide broken hooks

Chroot hooks only run during a full build, never during a repack. A malformed edit in the installer hook survived every local fast build and only surfaced once CI ran the whole thing. That is the argument for a CI job that builds the real image rather than a shortened one.

The runner image could not do the job

Ubuntu ships a fork of live-build that is missing flags this build depends on, so CI runs inside a privileged Debian container instead of the default runner. Same tool name, different tool.

Package existence is not package availability

Three builds died on packages that had been dropped from the distribution. The check that returns a record for an uninstallable package is the wrong check. The build now reads the candidate version from the policy instead, and fails early with a readable message.

Honest limits

The ISO has been verified in a virtual machine, not yet on bare metal. The signed package repository is written but unproven, because it needs a signing key and a hosting switch that have not been turned on yet. Both are stated in the repository rather than glossed over.

All case studies Next: tellsign

Need something like this?

Describe it in a paragraph. I will tell you whether it is a two day job or a two month one before you commit to anything.

Start a project

Reply within 24 hours on weekdays. Taking new projects.

Taking new projectsReply in 24 hours on weekdays Start a project