Applying manifests¶
kuke apply is the declarative interface: write a YAML file describing the resources you want, and Kukeon reconciles the host to match. It's the preferred way to create or update anything that isn't a one-off CLI operation.
The basics¶
Accepts a single path, or - to read from stdin:
The manifest can contain one or more resource documents separated by ---:
apiVersion: v1beta1
kind: Space
metadata:
name: blog
spec:
realmId: main
---
apiVersion: v1beta1
kind: Stack
metadata:
name: wordpress
spec:
id: wordpress
realmId: main
spaceId: blog
---
apiVersion: v1beta1
kind: Cell
metadata:
name: wp
spec:
id: wp
realmId: main
spaceId: blog
stackId: wordpress
containers:
- id: nginx
image: docker.io/library/nginx:alpine
kuke apply creates resources in dependency order — parents (realm → space → stack) before children (cell → container), regardless of the order they appear in the file.
What apply does¶
Per resource, the outcome is one of:
created— the resource didn't exist; it was created.updated— the resource existed but its spec differs; it was reconciled. Printed diffs follow.unchanged— the desired state already matches; nothing to do.failed— reconciliation failed; the error is printed. Processing continues for other resources, and the command exits non-zero at the end.
Example output:
Output formats¶
With -o json or -o yaml, apply emits a structured report instead of the human-readable one.
Idempotence¶
apply is idempotent: running the same manifest twice is safe. The second run should report unchanged for every resource.
Nesting and ordering¶
Today, each resource is a separate document. There is no "apply an entire stack as one tree" mode — you write the stack, then the cells under it, either in the same multi-doc file or separately.
Cross-file apply:
sudo kuke apply -f realm.yaml
sudo kuke apply -f space.yaml
sudo kuke apply -f stack.yaml
sudo kuke apply -f cell.yaml
or multi-doc:
In-process escape hatch¶
kuke apply routes through kukeond by default. When the daemon is down or you need to debug locally, reach the in-process path via KUKEON_NO_DAEMON=true in the env or an explicit --run-path (which auto-promotes to in-process mode):
sudo KUKEON_NO_DAEMON=true kuke apply -f cell.yaml
# or
sudo kuke apply -f cell.yaml --run-path /opt/kukeon
The --no-daemon flag itself was retired from workload commands by #222; see Client and daemon for the broader story.
Parameterized cell profiles¶
kuke apply -f consumes a fixed manifest — the file you ship is the spec the daemon reconciles to, with no substitution layer in between. When you need the same cell shape with different values per invocation (image tag, command, mount paths), reach for a cell profile loaded with kuke run -p instead of editing the YAML each time.
A profile lives under $HOME/.kuke/profiles.d/<name>.yaml (or $KUKE_PROFILES_DIR) and declares its variable inputs alongside the cell spec:
apiVersion: v1beta1
kind: CellProfile
metadata:
name: shell
spec:
parameters:
- name: IMAGE
description: container image to run
default: alpine:latest
- name: CMD
description: command to exec
required: true
containers:
- id: shell
image: ${IMAGE}
command: ["/bin/sh", "-c", "${CMD}"]
kuke run -p materializes one cell with a unique name (<metadata.name>-<6hex> by default; override with --name) and resolves each ${KEY} reference in the body. Resolution order, highest first:
--param KEY=VALUEon the CLI (repeatable)- Values from
--param-file <path>(oneKEY=VALUEper line,#starts a comment) - The parameter's
defaultin the profile - The
kukeprocess env (os.LookupEnv) - Required + unset → error; non-required + unset → empty string
# Use defaults / env / required errors
kuke run -p shell --param CMD="echo hi"
# Override the image too
kuke run -p shell --param IMAGE=alpine:edge --param CMD="/bin/sh"
# Load a batch of values from a file, with a CLI override on top
kuke run -p shell --param-file ./shell.env --param IMAGE=alpine:edge
--param, --param-file, and --name are rejected when combined with -f (file mode is not a profile and has no parameter declarations). The substituted body is what reaches the daemon — there is no parameter layer in the manifest API itself.
See kuke run for the full flag surface.
See also¶
- Manifest Reference — the full schema of every resource
- CLI Reference → apply — every flag on
kuke apply - CLI Reference → run —
-f(file) and-p(profile) modes, including parameter handling - Tutorials → Hello-world cell — a worked example end-to-end