Keel Linux icon: the cross-section of a hull with three layers stacked on a keel

Keel Linux

Declarative, layered, IPv6-first system-container appliances, compatible with TurnKey Linux appliances.

A fork of TurnKey Linux 19 (Debian 13) that makes the LXC appliance behave like a cloud instance: described in one file, built from signed layers, reachable on its own address, and upgradable in place.

What changes

Four things an appliance should already do

TurnKey appliances are excellent on day zero and hard to keep on day two. Keel keeps the appliances and corrects the model around them.

  • 01

    Declared in one file

    An instance spec describes hostname, IPv6 networking, domain and certificate policy, services, users and secrets by reference. Applying it converges the appliance and is safe to re-run. The interactive console writes the same file.

  • 02

    Built from signed, content-addressed layers

    Core, stack and app are separate read-only layers, each with a sha256, listed in a plain-text manifest signed by the project key and tied to a git commit. Same commit and same manifest give the same bytes.

  • 03

    Reachable end to end over IPv6

    Every appliance gets a routable address of its own, such as 2001:db8:4b1::10, with an ACME certificate and host identity keys. No NAT traversal, no port mapping. IPv4 is optional and never assumed.

  • 04

    Maintainable across major versions

    Platform upgrades and application schema upgrades are kept apart. The second runs with a return point, the upstream tool, validation and rollback, so an appliance follows Debian releases instead of being reinstalled.

How it is built

Three layers on one spine

An appliance is a core layer, a stack layer and an app layer, assembled from a manifest. The layers are built by the same tools TurnKey uses today, one deterministic tarball each.

Layer diagram Three horizontal layers named app, stack and core are stacked on a vertical keel. A manifest to the right lists each layer with its sha256, the git commit and the signature, with a dashed line from each manifest entry to its layer. app 133 MB stack 80 MB core 326 MB manifest app sha256:9c1e... stack sha256:4d7b... core sha256:e3a0... commit 1a2b3c4d signed by project key
Each layer is a deterministic tarball with a sha256 and a plain-text manifest. An update downloads only what changed: a new WordPress release means the app layer, not the base.

Measured on the build host

Unmodified TurnKey 19.0 recipes, built as layers.

Core layer
326 MB
LAMP stack delta
80 MB
WordPress app delta
133 MB
WordPress rebuild on cached layers
69 s instead of 451 s
Standards

Rules every change follows

  • 90 percent test coverage minimum, 95 percent for project code

    Every change ships with tests. The forked repositories keep at least 90 percent coverage; code the project writes keeps 95 percent.

  • IPv6 in every example

    Commands, defaults and configuration examples use IPv6 addresses, such as [2001:db8:4b1::10]:22. IPv4 is optional and never assumed.

  • English

    Commits, code comments, documentation and pull requests are written in English.

  • History is never rewritten

    Forks keep the upstream history and the upstream remote. No squashing, no force pushes, cherry-picks with attribution.

  • System containers only

    Full init, journal, cron, SSH and filesystem-level backup. Tests run on LXC with native systemd against real databases. No other container model is involved.

Status

Early

The build host reproduces unmodified TurnKey 19.0 from the forked repositories. That is the baseline every later change is measured against, and it passed before anything else started.

The first bug fixes are on branches, and the first pieces of the library (the instance spec and layer verification) exist with full test coverage. Nothing is published for end users yet: no images, no packages, no layer repository.

What is next

  1. Declarative spec. inspect, apply and diff for a running appliance, with the console writing the same file.
  2. Layered builds. Hashed core, stack and app layers with signed manifests, and a pull that fetches only the layers that are missing.
  3. Transition from TurnKey 19.0. A keyring package and a transition package that switch an existing appliance to the project repositories and write its spec from what is installed.