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.
Prerequisites
Section titled “Prerequisites”Kubernetes cluster and kubectl
Section titled “Kubernetes cluster and kubectl”Start a local Kubernetes cluster and configure kubectl to use it before rendering. On Windows, enable Kubernetes in Docker Desktop. Run the commands from the same environment as the CLI. On Windows, use the same WSL distribution for intropy, kubectl, kustomize, and dapr, with Docker Desktop WSL 2 integration enabled. Keep the System workspace under ~/, not /mnt/c, so scaffolded temporary files can receive Unix permissions:
kubectl config current-contextkubectl get nodesContinue when the current context is the local cluster you intend to use and its node is Ready.
Standalone Kustomize
Section titled “Standalone Kustomize”Intropy runs the standalone kustomize executable. The Kustomize version bundled with kubectl is not used, so install kustomize separately and ensure it is on PATH. The Kustomize installation instructions include other platform options.
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bashsudo mv kustomize /usr/local/bin/kustomize versionContinue when kustomize version prints a version.
Dapr CLI and Kubernetes runtime
Section titled “Dapr CLI and Kubernetes runtime”Install the Dapr CLI in the same environment as the Intropy CLI. The CLI alone is not sufficient: install Dapr into the Kubernetes cluster as well. This adds the Dapr control plane and CRDs that the rendered Dapr Components require:
dapr init -kdapr status -kContinue when dapr status -k reports the Dapr control-plane services as running. Install the fixture services your System needs before applying the manifests, such as a RabbitMQ broker for pub/sub.
System namespace
Section titled “System namespace”Rendering does not create a namespace. By default, resources render into a namespace named after the System. Create it before applying the manifests. For the order-flow example:
kubectl create namespace order-flowFor a different System, replace order-flow with its name. To deploy into an existing namespace instead, pass --namespace to the render command.
Render and apply
Section titled “Render and apply”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.
Bindings: every port needs a fixture
Section titled “Bindings: every port needs a fixture”A fixture is the local stand-in for the external system behind a Port. Choose the fixture that matches the Port’s adapter, not the deployment target.
| Port adapter | Local fixture | Use when |
|---|---|---|
| File | file |
The Component reads from or writes to a folder inside its own pod (an emptyDir mounted into the Dapr sidecar). Nothing outside the pod can reach it. |
| File | nfs |
The Port is an NFS file share. The sidecar mounts the dev environment’s NFS export, and each Port is the directory /<port> on it. |
| SFTP | sftp |
The Port connects to an SFTP server. |
| HTTP | http |
The Port calls or receives from an HTTP endpoint. |
| Blob storage | blob |
The Port reads from or writes to object storage. |
The order-flow example uses file adapters for both ports. Select file for order-extractor-source and order-loader-destination; the local fixture maps each Port to a folder.
A topology port is a name; locally, each name must be told which fixture 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, nfs, 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: the bindings are an argument to the render.
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.
Full flag detail: intropy manifests render.