Local cluster
manifests render --env local produces the same Kubernetes shape the GitOps path deploys (workloads, Dapr annotations, Dapr Components) as one YAML stream on stdout, for a cluster on your own machine:
intropy manifests render --env local | kubectl apply -f -Run it from the workspace that holds the System host (--system selects one in a multi-system workspace). Only YAML is written to stdout; progress, prompts, warnings, and errors go to stderr, and the complete render is buffered and validated before stdout is written, so a failed render cannot apply an incomplete prefix through the pipe.
The command does not inspect the cluster. Having Dapr installed, and the fixture services running (a RabbitMQ broker for pub/sub, for example), is your cluster setup’s responsibility.
Bindings: every port needs a fixture
Section titled “Bindings: every port needs a fixture”A topology port is a name; locally, each name must be told which adapter to resolve to. Without that, the render refuses:
error: local bindings are required for ports: order-extractor-source, order-loader-destinationpass one '--binding <port>=<fixture>' for each; available fixtures: sftp, http, file, blobPass one --binding <port>=<fixture> per port for a reproducible, non-interactive render:
intropy manifests render --env local \ --binding order-extractor-source=file \ --binding order-loader-destination=file | kubectl apply -f -In an interactive terminal a selector asks for any missing choice instead; the selection applies to that render only and is never persisted. There is no saved binding state: in real environments the bindings live in the GitOps repository, and locally they are an argument.
What gets emitted
Section titled “What gets emitted”For the order-flow example (one extractor, one loader, both bound to file), the stream contains the workloads the deployment model implies and the Dapr Components that wire them:
-
A Deployment for the loader, with Dapr sidecar annotations (
dapr.io/enabled,dapr.io/app-id: order-loader,dapr.io/app-port: "8080") and an OTLP exporter endpoint in its environment. -
A CronJob for the extractor (extractors wake, pull, publish, and exit) with
concurrencyPolicy: Forbidand its own Dapr annotations. -
A Dapr Component per port, scoped to the component that uses it. The
filefixture becomesbindings.localstoragewith arootPathunder/data/:apiVersion: dapr.io/v1alpha1kind: Componentmetadata:labels:intropy.io/port: order-extractor-sourcename: order-extractor-sourcenamespace: order-flowscopes:- order-extractorspec:metadata:- name: rootPathvalue: /data/order-extractor-sourcetype: bindings.localstorageversion: v1 -
A pub/sub Component shared by publisher and subscriber, pointing at the local fixture broker.
Everything lands in a namespace named after the System (order-flow here); --namespace changes it. Images default to the local convention (local/<component>:dev); override one with --image <component>=<name:tag>, or retag every component with --image :<tag>.
When to use this, and when not to
Section titled “When to use this, and when not to”This is not the inner loop. For building and debugging a System, the host’s Aspire run is faster and needs no cluster: F5, mocked platform services, drop folders standing in for ports, the dashboard for traces (see Systems and topology).
Render to a local cluster when the deployed shape is the thing under test: that the workload kinds and sidecar annotations are what you expect, that port Components are scoped correctly, that the System behaves on real Kubernetes with a real broker. From there, the same model, rendered from the same topology by the same templates, is onboarded into the GitOps repository and moved through environments with releases and promotion.
Full flag detail: intropy manifests render.