kukeon

module
v0.6.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 12, 2026 License: Apache-2.0

README ΒΆ

πŸŒͺ️ kukeon: Run a team of AI agents on your own Linux.

Test

Self-hosted runtime for AI coding agents on your own Linux host.

Kukeon runs Claude Code and other agent workloads as isolated containerd cells on a single Linux host you own β€” from a cloud VM down to a Raspberry Pi. Each agent gets an attachable terminal, logs, scoped secrets, and reproducible blueprints/configs, with the Git forge as the system of record. No SaaS sandbox, no Kubernetes cluster, every action inspectable.

Start with one agent cell; grow into per-project agent teams declared with kuketeam.yaml.

Quick Start

Get kukeon running on a single Linux host in minutes.

Prerequisites
  • Linux with cgroups v2
  • containerd running at /run/containerd/containerd.sock

Release binaries are published for amd64 and arm64.

Install
curl -fsSL https://kukeon.io/install.sh | bash

The installer detects your platform, verifies the prerequisites above (and prints a distro-aware hint on any miss), downloads the latest release, verifies its sha256 checksum, installs kuke + kukeond to /usr/local/bin, runs sudo kuke init to bring the daemon up, and (on systemd hosts) installs /etc/systemd/system/kukeond.service so kukeond comes back automatically after a host or containerd restart. On systemd-less hosts the unit step is skipped with a notice β€” bring kukeond up manually after each reboot with sudo kuke daemon start. Pass --check to run the prereq checks only without touching the system:

curl -fsSL https://kukeon.io/install.sh | bash -s -- --check

After install completes you should see the daemon's realm/space/stack hierarchy provisioned and kukeond listening on its unix socket:

Realm: default (namespace: default.kukeon.io)
System realm: kuke-system (namespace: kuke-system.kukeon.io)
Run path: /opt/kukeon
...
kukeond is ready (unix:///run/kukeon/kukeond.sock)

If you would rather drive each step yourself β€” installing onto an air-gapped host, or pinning a non-default release tag β€” see the manual install steps.

Daily use without sudo

kuke init provisions a system kukeon group and sets the kukeond socket to mode 0660 root:kukeon. Add yourself to the group so daemon-routed commands (kuke get, kuke create, kuke apply, kuke delete, kuke log, kuke attach) don't need sudo:

sudo usermod -aG kukeon $USER
# Log out and back in (or run `newgrp kukeon`) so the group takes effect, then:
kuke get realms

Operations that bypass the daemon still need root: kuke init, kuke daemon reset, kuke image load (in-process by design β€” every kuke image * subcommand runs in-process), kuke purge / kuke uninstall with --no-daemon, and any command run with KUKEON_NO_DAEMON=true or an explicit --run-path.

Your first cell: Claude Code

Build the example Claude Code image and run it as a cell β€” no Docker required. kuke build writes the image straight into the realm's containerd namespace:

sudo kuke build -t claude-code:latest docs/examples/claude-code/
sudo kuke run -f docs/examples/claude-code/cell.yaml
# detach with ^]^] β€” the cell keeps running
kuke run claude-code   # reattach any time

kuke run -f is create-or-attach, keyed by the manifest's metadata.name: the first invocation creates the cell and attaches your terminal; running it again β€” or kuke run <name> β€” reattaches to a Ready cell as a no-op, and starts a Stopped cell before attaching. You land at a claude> prompt inside the cell; run claude to enter the Claude Code REPL (bring your own auth β€” the example image bakes in no API keys).

β†’ See docs/site/guides/run-claude-code.md for the full walkthrough, or docs/site/tutorials/hello-world.md for a plain-container first cell.

Autocomplete
cat >> ~/.bashrc <<EOF
source <(kuke autocomplete bash)
EOF

kuke autocomplete zsh and kuke autocomplete fish are also supported.

Completions are dynamic: every tab dispatches through kuke __complete, so newly added blueprints, configs, realms, and cells are picked up on the next tab without re-sourcing the script.

What you can do today

Kukeon is useful right now as a single-host runtime for AI coding agents:

  • Run Claude Code in an isolated cell β€” the canonical first workflow, from zero to a live prompt. β†’ See docs/site/guides/run-claude-code.md.
  • Run one-shot agent jobs from a CellBlueprint β€” parametrized prompts driven with kuke run --from-blueprint.
  • Define repeatable agent environments with CellBlueprint + CellConfig.
  • Compose a per-project agent roster with kuke team init from a committed kuketeam.yaml β€” the next-level path once one cell isn't enough. β†’ See docs/site/cli/kuke-team-init.md.
  • Operate a lightweight single-host agent runtime without Kubernetes.

It is also a good fit beyond agents: if you have outgrown docker compose but don't want to stand up a Kubernetes cluster, kukeon gives a single Linux host an explicit Realm β†’ Space β†’ Stack β†’ Cell β†’ Container hierarchy β€” one CNI network per space, one cgroup subtree per layer, no distributed control plane. Homelab and VPS users, and systems engineers who prefer containerd over Docker, are first-class audiences.

Why kukeon

Your agents, your machines, your rules. SaaS agent sandboxes (E2B, Daytona, Modal) force your agents to run on their cloud. Kukeon runs them on yours β€” a cloud VM, a homelab, a single Linux box with containerd. No vendor lock-in, no data leaving your infrastructure, no credit card.

  • Sovereign β€” every byte of agent state lives on hosts you own
  • Declarative β€” Session + Interactive + onEnd.persist as first-class YAML
  • Isolated β€” realm/space/cell backed by real Linux primitives (containerd namespaces, CNI networks, cgroups)
  • Self-hosted β€” no cluster, no etcd, no scheduler, no SaaS
  • Transparent β€” inspect what the daemon did with ctr, ip link, ls /sys/fs/cgroup
  • Coexists with Docker β€” kukeon drives the system containerd under its own *.kukeon.io namespaces; an existing Docker install on the same host is untouched. β†’ See the FAQ.

What it is not (yet)

Setting expectations before you install:

  • Not a Kubernetes replacement for multi-node clusters or cross-region orchestration.
  • Not a SaaS sandbox β€” execution stays on infrastructure you own.
  • Not yet a fully autonomous software company β€” the human merge gate is a deliberate stage-0, not a missing feature (see vision.md).
  • Not its own audit-trail database β€” every action is a Git object in your forge.
  • Not a layer that hides low-level primitives behind opaque abstractions.
  • Pre-v1 β€” manifests, CLI verbs, and daemon semantics can still change between minor releases.

Core Concepts

Kukeon defines a clear hierarchical model:

flowchart LR
    Realm --> Space --> Stack --> Cell --> Container
  • Realm: High-level environment mapped to a containerd namespace
  • Space: CNI network and cgroup subtree that define isolation
  • Stack: Logical grouping of related cells
  • Cell: A pod-like group. One root container owns the network namespace
  • Container: An OCI container running inside the cell

Each layer is a real Linux primitive, not an invented abstraction. This structure avoids Docker's ambiguity and Kubernetes-level complexity.

β†’ See docs/site/concepts/overview.md for the full concept guide, docs/site/architecture/overview.md for how kuke, kukeond, containerd, and CNI fit together, and docs/site/cli/commands.md for the complete CLI reference.

Documentation

Complete documentation is available at https://kukeon.io, including concepts, architecture, CLI reference, manifest reference, guides, and tutorials.

Philosophy

«καὢ ὁ ΞΊΟ…ΞΊΞ΅α½ΌΞ½ διίσταται μὴ κινούμΡνος» "The barley-drink separates if it isn't stirred"

Fragment DK 22B125 Heraclitus, circa 500 BC

Heraclitus used the kykeon, a simple barley drink, as an analogy for the logos, the hidden principle of order in the cosmos. The drink becomes itself only when its ingredients are mixed and kept in motion. Without movement, it separates and loses its identity.

Kukeon applies the same metaphor to computing:

  • containers, networks, and cgroups are the ingredients
  • kukeond is the stirring motion that brings them together
  • the running system is the order that emerges through interaction

Kukeon brings coherence and structure to low-level Linux primitives that normally remain scattered and disconnected. It unifies them into a living, dynamic system.

Uninstall

kuke uninstall removes everything kukeon put on the host β€” every realm and its workloads, the *.kukeon.io containerd namespaces, /opt/kukeon, /run/kukeon, and the kukeon system user and group. Only the kuke/kukeond binary is left behind:

sudo kuke uninstall

β†’ See docs/site/cli/kuke-uninstall.md for details, and docs/site/architecture/storage-layout.md for everything kukeon writes on a host.

Roadmap

Kukeon is under active development, with a focus on correctness, clear abstractions, and stable primitives before adding integrations.

β†’ The backlog is the roadmap: see GitHub Issues β€” filter by label:planning for umbrellas and priority:A / priority:B for the active queue.

Contribute

Kukeon is open to thoughtful contributions. The focus is on a simple and reliable foundation for structured container environments, not on building a giant platform. Ideas, discussions, and clean code are welcome, especially when they improve clarity, correctness, or safety without adding unnecessary complexity.

β†’ See docs/site/guides/local-dev.md for the local development loop (make dev-init, building kuke/kukeond from source, iterating on the daemon).

License

Apache License 2.0

Β© 2025 Emiliano Spinella (eminwux)

Directories ΒΆ

Path Synopsis
cmd
kuke/attach
Package attach implements the `kuke attach` thin sbsh client subcommand.
Package attach implements the `kuke attach` thin sbsh client subcommand.
kuke/build
Package build hosts the `kuke build` CLI shim.
Package build hosts the `kuke build` CLI shim.
kuke/create/blueprint
Package blueprint implements `kuke create blueprint <name>` (issue #816, child of the #814 epic:create umbrella).
Package blueprint implements `kuke create blueprint <name>` (issue #816, child of the #814 epic:create umbrella).
kuke/create/config
Package config implements `kuke create config <name> --from-blueprint <bp>` (issue #817, child of the #814 epic:create umbrella).
Package config implements `kuke create config <name> --from-blueprint <bp>` (issue #817, child of the #814 epic:create umbrella).
kuke/create/registrycredential
Package registrycredential implements `kuke create registry-credential` β€” an imperative path to attach pull credentials to an existing realm's spec.registryCredentials without round-tripping through a hand-edited YAML manifest.
Package registrycredential implements `kuke create registry-credential` β€” an imperative path to attach pull credentials to an existing realm's spec.registryCredentials without round-tripping through a hand-edited YAML manifest.
kuke/daemon
Package daemon hosts the `kuke daemon` subcommand group, which exposes daemon-lifecycle verbs (start, stop, kill, and later restart/reset).
Package daemon hosts the `kuke daemon` subcommand group, which exposes daemon-lifecycle verbs (start, stop, kill, and later restart/reset).
kuke/daemon/kill
Package kill implements `kuke daemon kill`, the immediate-SIGKILL escape hatch for the kukeond cell.
Package kill implements `kuke daemon kill`, the immediate-SIGKILL escape hatch for the kukeond cell.
kuke/daemon/logs
Package logs implements `kuke daemon logs`, a shortcut that prints the kukeond container's stdout/stderr stream.
Package logs implements `kuke daemon logs`, a shortcut that prints the kukeond container's stdout/stderr stream.
kuke/daemon/recreate
Package recreate implements `kuke daemon recreate`, a composed verb that tears down the kukeond cell and re-provisions it using the same cell-creation path `kuke init` exercises.
Package recreate implements `kuke daemon recreate`, a composed verb that tears down the kukeond cell and re-provisions it using the same cell-creation path `kuke init` exercises.
kuke/daemon/reset
Package reset implements `kuke daemon reset`, the lightweight dev-loop teardown for the kukeond cell.
Package reset implements `kuke daemon reset`, the lightweight dev-loop teardown for the kukeond cell.
kuke/daemon/restart
Package restart implements `kuke daemon restart`, which is the composed stop-then-start lifecycle verb for the kukeond cell.
Package restart implements `kuke daemon restart`, which is the composed stop-then-start lifecycle verb for the kukeond cell.
kuke/daemon/start
Package start implements `kuke daemon start`, which brings up the existing kukeond cell on a host that has already been initialized.
Package start implements `kuke daemon start`, which brings up the existing kukeond cell on a host that has already been initialized.
kuke/daemon/stop
Package stop implements `kuke daemon stop`, which gracefully shuts down the kukeond cell.
Package stop implements `kuke daemon stop`, which gracefully shuts down the kukeond cell.
kuke/doctor
Package doctor hosts `kuke doctor`, a parent command for host-level pre-flight checks invoked before `kuke init` to surface environmental problems that would otherwise be diagnosed only via cryptic mid-bootstrap failures (e.g., missing cgroup-v2 controller delegation).
Package doctor hosts `kuke doctor`, a parent command for host-level pre-flight checks invoked before `kuke init` to surface environmental problems that would otherwise be diagnosed only via cryptic mid-bootstrap failures (e.g., missing cgroup-v2 controller delegation).
kuke/doctor/cgroups
Package cgroups implements `kuke doctor cgroups`: a pre-flight that classifies the host root cgroup's controller availability against the set kukeon's cell-creation path will require, with actionable output for the contributor running `make dev-init`.
Package cgroups implements `kuke doctor cgroups`: a pre-flight that classifies the host root cgroup's controller availability against the set kukeon's cell-creation path will require, with actionable output for the contributor running `make dev-init`.
kuke/get/image
Package image hosts the `kuke get image` subcommand: cross-realm-by-default image listing under the `kuke get <kind>` family.
Package image hosts the `kuke get image` subcommand: cross-realm-by-default image listing under the `kuke get <kind>` family.
kuke/get/testutil
Package testutil provides test helpers shared across the kuke get subcommand test suites.
Package testutil provides test helpers shared across the kuke get subcommand test suites.
kuke/image
Package image hosts the `kuke image` parent command and its subcommands: `load` (#200), `delete` (#212), and `prune` (#1036).
Package image hosts the `kuke image` parent command and its subcommands: `load` (#200), `delete` (#212), and `prune` (#1036).
kuke/internal/lifecycle
Package lifecycle holds the scaffolding shared by the `kuke daemon` lifecycle verbs (start, stop, kill, restart, reset, logs).
Package lifecycle holds the scaffolding shared by the `kuke daemon` lifecycle verbs (start, stop, kill, restart, reset, logs).
kuke/log
Package log implements the `kuke log` subcommand.
Package log implements the `kuke log` subcommand.
kuke/run
Package run implements the `kuke run` verb.
Package run implements the `kuke run` verb.
kuke/status
Package status implements `kuke status`, the consolidated health report that absorbs the original gaps doc's three separate proposals β€” `kuke doctor` (host pre-flight is now `kuke doctor cgroups`), `kuke ping` (daemon liveness), and `kuke selftest` (parity + state consistency) β€” into one post-init smoke command.
Package status implements `kuke status`, the consolidated health report that absorbs the original gaps doc's three separate proposals β€” `kuke doctor` (host pre-flight is now `kuke doctor cgroups`), `kuke ping` (daemon liveness), and `kuke selftest` (parity + state consistency) β€” into one post-init smoke command.
kuke/team
Package team hosts the `kuke team` parent command and its subcommands.
Package team hosts the `kuke team` parent command and its subcommands.
kukeond
Package kukeond is the cobra entry point for the kukeond daemon binary.
Package kukeond is the cobra entry point for the kukeond daemon binary.
kukepause command
kukepause is the minimal PID 1 for every kukeon cell's root (pause) container, replacing the previous `sleep infinity` from busybox (issue #931).
kukepause is the minimal PID 1 for every kukeon cell's root (pause) container, replacing the previous `sleep infinity` from busybox (issue #931).
kuketty command
kuketty is the kukeon-owned terminal wrapper that runs inside an attachable container in place of sbsh.
kuketty is the kukeon-owned terminal wrapper that runs inside an attachable container in place of sbsh.
hack
attach-smoke command
attach-smoke drives an interactive subprocess attached to a freshly allocated pseudoterminal, then sends sbsh's Ctrl+] Ctrl+] detach sequence and waits for the child to exit.
attach-smoke drives an interactive subprocess attached to a freshly allocated pseudoterminal, then sends sbsh's Ctrl+] Ctrl+] detach sequence and waits for the child to exit.
internal
cellblueprint
Package cellblueprint resolves daemon-stored CellBlueprint templates into CellDocs for `kuke run -b`.
Package cellblueprint resolves daemon-stored CellBlueprint templates into CellDocs for `kuke run -b`.
cellconfig
Package cellconfig holds the identity primitives for a daemon-stored CellConfig (kind: CellConfig, issue #624, phase 4b-i of #423): the back-reference label a materialized cell carries, the deterministic stable-name derivation, and the slot-fill validation that checks a Config's repo/secret fills against the referenced blueprint's declared structural slots.
Package cellconfig holds the identity primitives for a daemon-stored CellConfig (kind: CellConfig, issue #624, phase 4b-i of #423): the back-reference label a materialized cell carries, the deterministic stable-name derivation, and the slot-fill validation that checks a Config's repo/secret fills against the referenced blueprint's declared structural slots.
cgroupcheck
Package cgroupcheck implements the host-cgroup pre-flight that catches missing or undelegated cgroup-v2 controllers before kukeon's bootstrap path tries (and fails) to enable them.
Package cgroupcheck implements the host-cgroup pre-flight that catches missing or undelegated cgroup-v2 controllers before kukeon's bootstrap path tries (and fails) to enable them.
client/local
Package local provides an in-process kukeonv1.Client backed by a controller.Exec.
Package local provides an in-process kukeonv1.Client backed by a controller.Exec.
clientconfig
Package clientconfig loads a kuke ClientConfiguration document from disk.
Package clientconfig loads a kuke ClientConfiguration document from disk.
cni
ctr
daemon
Package daemon implements the kukeond process: it owns a controller.Exec, exposes the kukeonv1 API over a unix socket using net/rpc + jsonrpc, and manages its own lifecycle (listener, PID file, graceful shutdown).
Package daemon implements the kukeond process: it owns a controller.Exec, exposes the kukeonv1 API over a unix socket using net/rpc + jsonrpc, and manages its own lifecycle (listener, PID file, graceful shutdown).
firewall
Package firewall manages host-level iptables state owned by kukeon β€” the FORWARD admission chain that admits traffic to/from kukeon bridges.
Package firewall manages host-level iptables state owned by kukeon β€” the FORWARD admission chain that admits traffic to/from kukeon bridges.
instance
Package instance records the host-instance ServerConfiguration values (containerd namespace suffix and cgroup root) that a given runPath was bootstrapped under, so the daemon can refuse to start when reconfigured to a different layout.
Package instance records the host-instance ServerConfiguration values (containerd namespace suffix and cgroup root) that a given runPath was bootstrapped under, so the daemon can refuse to start when reconfigured to a different layout.
kuketeams
Package kuketeams parses and validates the team-distribution documents (kuketeams.io/v1: ProjectTeam, TeamsConfig, Role, Harness, ImageCatalog; issue #793, epic #792).
Package kuketeams parses and validates the team-distribution documents (kuketeams.io/v1: ProjectTeam, TeamsConfig, Role, Harness, ImageCatalog; issue #793, epic #792).
kuketty/setupstatus
Package setupstatus is the wire contract for the GetSetupStatus RPC verb (issue #642, phase 1b).
Package setupstatus is the wire contract for the GetSetupStatus RPC verb (issue #642, phase 1b).
netpolicy
Package netpolicy renders space-level egress policies into iptables rules and applies them on the host firewall.
Package netpolicy renders space-level egress policies into iptables rules and applies them on the host firewall.
serverconfig
Package serverconfig loads a kukeond ServerConfiguration document from disk.
Package serverconfig loads a kukeond ServerConfiguration document from disk.
sysuser
Package sysuser provisions the kukeon system user/group and applies kukeon-managed file ownership during `kuke init`.
Package sysuser provisions the kukeon system user/group and applies kukeon-managed file ownership during `kuke init`.
teambuild
Package teambuild orchestrates the local `kuke team init --build` path: it walks the FROM directives of the catalog entries a project selected, derives the transitive base-before-leaves build order (the bases base/base-user/ base-root are intermediates that live in the agents source tree, not in images.yaml), and invokes the standalone kukebuild binary once per image into the target realm's containerd namespace.
Package teambuild orchestrates the local `kuke team init --build` path: it walks the FROM directives of the catalog entries a project selected, derives the transitive base-before-leaves build order (the bases base/base-user/ base-root are intermediates that live in the agents source tree, not in images.yaml), and invokes the standalone kukebuild binary once per image into the target realm's containerd namespace.
teamhost
Package teamhost owns the host-side, on-disk lifecycle of the team-distribution config maintained by `kuke team init` (epic #792, step 1 #796): the operator-global facts file (~/.kuke/kuketeams.yaml) and the per-project drop-in directory (~/.kuke/kuketeam.d/<project>.yaml).
Package teamhost owns the host-side, on-disk lifecycle of the team-distribution config maintained by `kuke team init` (epic #792, step 1 #796): the operator-global facts file (~/.kuke/kuketeams.yaml) and the per-project drop-in directory (~/.kuke/kuketeam.d/<project>.yaml).
teamrender
Package teamrender renders a project's ProjectTeam roster into a set of CellBlueprint and CellConfig documents β€” one (CellBlueprint, CellConfig) pair per `(role Γ— harness)` (epic #792, step 3 #1042).
Package teamrender renders a project's ProjectTeam roster into a set of CellBlueprint and CellConfig documents β€” one (CellBlueprint, CellConfig) pair per `(role Γ— harness)` (epic #792, step 3 #1042).
teamsecrets
Package teamsecrets composes a team's secret material from two `secrets.env` layers β€” a shared host-wide default at `~/.kuke/teams/secrets.env` and a per-team override at `<teamDir>/secrets.env` β€” and renders the merged non-empty entries as `kind: Secret` documents the daemon-side apply pipeline (#1029) consumes alongside the project's CellBlueprints and CellConfigs.
Package teamsecrets composes a team's secret material from two `secrets.env` layers β€” a shared host-wide default at `~/.kuke/teams/secrets.env` and a per-team override at `<teamDir>/secrets.env` β€” and renders the merged non-empty entries as `kind: Secret` documents the daemon-side apply pipeline (#1029) consumes alongside the project's CellBlueprints and CellConfigs.
teamsource
Package teamsource resolves a kuketeams.io/v1 ProjectTeam's structured `source` reference to a local clone of the agents repo and loads the Role, Harness, and ImageCatalog documents the project's roster references (epic #792).
Package teamsource resolves a kuketeams.io/v1 ProjectTeam's structured `source` reference to a local clone of the agents repo and loads the Role, Harness, and ImageCatalog documents the project's roster references (epic #792).
util/diskpressure
Package diskpressure samples filesystem usage for the volume backing a given path and rate-limits the warnings kukeond emits when a data volume crosses a high-water mark.
Package diskpressure samples filesystem usage for the volume backing a given path and rate-limits the warnings kukeond emits when a data volume crosses a high-water mark.
pkg
api/kukeonv1
Package kukeonv1 is the public client SDK for the kukeon daemon.
Package kukeonv1 is the public client SDK for the kukeon daemon.
api/model/kuketeams
Package kuketeams holds the Go types for the team-distribution contract (issue #793, epic #792).
Package kuketeams holds the Go types for the team-distribution contract (issue #793, epic #792).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL