OpenClaw EnterpriseDOCSGitHub

Compose development flow

Overview

./bin/occ dev up starts local OpenClaw Enterprise development from a checkout. The scripts/dev-up entry point selects the same profile. By default OCC and PostgreSQL run in Compose with Docker Compute. Operators can explicitly select Kubernetes Compute with either the Compose control plane or the local k3d-only profile. The Kubernetes profile can select the OpenShell Sandbox Driver for its fail-closed path; it prepares pinned OpenShell infrastructure and reconciles rendered workspace-chart resources before reporting readiness. Compose-backed profiles perform host preflight, select Docker Engine or Podman, prepare runtime images, start Compose, and wait for PostgreSQL migration, Installation bootstrap, API health, and worker readiness. The Kubernetes-only profile performs the equivalent readiness checks inside its owned cluster. Startup proves authenticated Installation access with a protected local bootstrap service key; it does not create an Agent or prove model execution.

For Docker Compute, the worker can reconcile Namespace infrastructure, but Agent deployment stops at harness authentication admission because Docker Compute rejects bindings. Kubernetes Agent execution continues through the selected Kubernetes Compute Driver and the authenticated Agent deployment procedure.

Entry Points

The Kubernetes profile additionally uses compose.kubernetes.yaml, internal/occdev, k3d, and kubectl. ./bin/occ dev down owns profile cleanup; scripts/dev-down dispatches to it. The local Kubernetes development guide owns the operator procedure and destructive cleanup boundary.

Flow

graph TD
  A["./bin/occ dev up"] --> Profile{"Compute profile"}
  Profile -->|Docker| B["Preflight host tools, resolve Podman machine connection,<br/>and inspect Compose config"]
  Profile -->|Kubernetes| KPre["Pin local engine endpoint<br/>and reject existing resources"]
  KPre --> KControl{"Control-plane profile"}
  KControl -->|Kubernetes| KOnly["Install PostgreSQL, OCE, and<br/>OpenShell in the owned cluster"]
  KOnly --> KWorkspace
  KControl -->|Compose| KConfig["Validate Compose and claim<br/>private state with snapshot"]
  KConfig --> KStart["Bootstrap OCC and create<br/>the owned k3d cluster"]
  KStart --> KReady["Import runtime and start<br/>API and Kubernetes worker"]
  KReady --> KSandbox{"Sandbox profile"}
  KSandbox -->|none| KProof
  KSandbox -->|OpenShell| KOpenShell["Install pinned Agent Sandbox, RuntimeClass,<br/>Gateway, and render workspace resources"]
  KOpenShell --> KWorkspace["Driver applies workspace resources and creates<br/>the default Namespace's owned Workspace"]
  KWorkspace --> KFailClosed["Default Namespace ready;<br/>Agent projection remains fail closed"]
  KFailClosed --> KProof
  KProof["Prove authenticated<br/>Installation access"]
  KProof --> KDown["./bin/occ dev down reuses<br/>recorded endpoint and project"]
  KStart -->|failure| KRollback["Roll back owned resources<br/>retain state if cleanup fails"]
  KReady -->|failure| KRollback
  KProof -->|failure| KRollback
  KDown --> KRemove["Stop reconcilers and delete<br/>owned cluster and volumes"]
  KRemove -->|success| KDone["Remove private state"]
  KRemove -->|failure| KRetain["Keep state for recovery"]
  B --> C["Select quickstart runtime image or validate custom images"]
  C --> D["Selected Compose starts PostgreSQL, migrate, bootstrap, API, and worker"]
  D --> E["Copy bootstrap service-key response to private local file"]
  E --> F["./bin/occ installation get proves authenticated access"]
  F --> G["Operator creates Namespace through authenticated API"]
  G --> H["Worker claims durable Namespace operation"]
  H --> I["Docker Driver ensures owned tenant network"]
  I --> J["Namespace becomes ready"]
  F --> K["Operator requests Agent deployment on Docker Compute"]
  K --> L["Admission rejects missing or unsupported harness binding"]
  J --> M["Authorized deletion removes owned Namespace resources"]
  D -->|operator cleanup| CDown["occ dev down keeps<br/>selected engine connection"]
  M --> CDown
  CDown --> CVolumes{"--volumes?"}
  CVolumes -->|No| CKeep["Remove Compose containers and network;<br/>retain named volumes"]
  CVolumes -->|Yes| CDelete["Remove Compose containers,<br/>network and named volumes"]

Execution Trace

1. Start and initialize the local stack

scripts/dev-up, apps/controller/src/server.mjs:start

Docker or Podman Compose startup owns engine selection, database initialization, local API admission and worker startup.

2. Prepare Namespace infrastructure and enforce Agent admission

apps/controller/src/drivers/compute/docker/index.ts:DockerComputeDriver

Namespace execution and Agent admission traces API authorization, durable work, tenant network ownership, unsupported Agent authentication and exact resource removal.

3. Clean up Docker or Podman Compose

internal/occdev/down.go:Down, internal/occdev/down.go:podmanComposeArgs

occ dev down uses the selected engine and forwarded Compose project and file options, including after partial startup. Podman retains the caller's selected connection. Its reported API socket supplies OCC_CONTAINER_ENGINE_SOCKET only to resolve the worker mount; a socket inside a macOS VM is not substituted for the host connection. An unavailable engine or invalid socket fails cleanup.

Compose removes its project containers and network. Named database, Configuration, and bootstrap volumes remain unless --volumes is explicit. Agent-owned containers and Namespace networks remain the responsibility of their platform deletion workflows; follow safe development shutdown.

4. Start and clean up Kubernetes development

internal/occdev/up.go:Up, internal/occdev/down.go:Down.

The Kubernetes startup and cleanup trace follows profile selection, the private Compose snapshot, k3d creation, runtime import, authenticated readiness, and cleanup through the recorded engine.

5. Prepare the optional OpenShell development profile

internal/occdev/openshell_k3d.go:upK3d, internal/occdev/openshell.go:prepareOpenShell, apps/controller/src/drivers/sandbox/openshell.ts:ensureNamespace

With OCC_DEVELOPMENT_CONTROL_PLANE=kubernetes, OpenShell uses the Kubernetes-only lifecycle before Compose rendering. It pins K3s and OpenShell inputs, installs PostgreSQL, OCE, and one central Gateway in oce-system, and publishes only an admitted API proxy on host loopback.

By default, the Kubernetes lifecycle starts PostgreSQL, migration, bootstrap, the API, and the worker in Compose. It installs the central Gateway in openshell-system and exposes its fixed NodePort only to the owned container network. In both modes, the worker creates the bootstrap Namespace through the regular Compute workflow. The Sandbox Driver applies rendered workspace resources and the operator label before creating the corresponding Gateway Workspace. Startup waits until the OCC Namespace becomes ready. See the OpenShell flow.

Debugging and Verification

Search documentation