HIP-117: Cloud-in-a-Box — One Binary, Three Modes. Status Draft. Hanzo's own standard — read this before implementing against it.
This proposal defines the three deployment topologies of the ONE cloud binary (HIP-0106) — from a laptop to an HA cluster without changing the artifact:
cloud serve — single process, no Kubernetes: everysubsystem in-process, per-tenant SQLite, datastore as a subprocess or gracefully absent. The true cloud-in-a-box for laptop, edge, and single-node installs.
cloud cluster init — the binary fetches k3s (it does NOT embed it), bootstraps a Kubernetes cluster, installs the operator, and hands reconciliation to services.hanzo.ai CRs (HIP-0400). Single command from bare metal to HA.
helm install — bring your own Kubernetes: the charts at cloud/helm/cloud deploy the same image into an existing cluster.
The mode is topology, not identity: same bits, same config surface, same product behavior. What runs is decided by HIP-0116 (plugins / enabled subsystems); where it runs is decided here — and nowhere else.
An OSS AI cloud must install like a tool, not like a platform team. The competition for the first five minutes is docker run and curl | sh, not a 40-page Helm values reference. At the same time the production shape is an operator-reconciled Kubernetes estate (HIP-0400 CRs, HIP-0036 CI/CD). Historically these were different software: a "dev mode" binary and a "real" set of manifests that drifted apart.
HIP-0106 removed the reason for that split. The unified binary already runs every subsystem in one process against SQLite; Kubernetes adds scale-out and self-healing, not features. So the deployment story collapses to one artifact with three entry points, and the only real design question left is: does the binary embed the orchestrator?
The answer is no. Embedding k3s into cloud was considered and rejected:
own release cadence, CVE stream, and kernel-facing surface. Baking it into the app binary conflates two lifecycles that must upgrade independently.
state); a k3s payload roughly triples it for a code path most deployments never execute.
that fetches and bootstraps the orchestrator on demand — and it is the right separation: the app binary orchestrates the bootstrap; it is not the orchestrator.
cloud serve (single process, no Kubernetes)The binary IS the cloud:
fail-closed embeds). Disabled-by-default activation and 503 blast-radius isolation apply unchanged.
--data-dir. No external database exists in this mode — SQLite is the default, not the fallback.
exception per HIP-0106) runs as a locally supervised subprocess when present. When absent, analytics-dependent surfaces degrade fail-closed (503 on their prefixes) while everything else serves — the same isolation rule as any broken subsystem.
satisfied: there is exactly one replica.
in-memory shape: instant finality, zero configuration.
This mode is shipped: it is cloud.Serve — the same entry the SaaS runs — pointed at local storage. Edge and laptop installs are not a port; they are a smaller instance of production.
cloud cluster init (the binary bootstraps its own cluster)For bare metal / VM fleets with no existing Kubernetes:
verifies its checksum before executing anything. The pin lives in the cloud release, so cloud version N always bootstraps a known orchestrator version — reproducible clusters, no latest.
cluster join adds agents), write the kubeconfig.
hanzoai/operator and the services.hanzo.ai CRDs (HIP-0400 family).
ghcr.io/hanzoai/<service> images (built by HIP-0036 lanes), creates the datastore as a StatefulSet, and converges the estate. From here on, day-2 is GitOps against CRs — cluster init is a bootstrapper, not a parallel management plane.
HA and scale-out are properties of this mode: multiple nodes, replica counts on CRs, and the durable Quasar/ZapDB substrate shape from HIP-0116.
Airgapped variant: an optional cloud-fat build go:embeds the pinned k3s binary for networks that cannot fetch. It is a separate build target, never the default — the default binary never carries an orchestrator. This is the ONLY sanctioned embedding of k3s.
Status: decided; staged behind the SaaS-first cutover. The operator, CRDs, and images it composes all exist and run production today (HIP-0400, HIP-0036); cluster init sequences them from the binary.
helm install (bring your own Kubernetes)For teams that already operate Kubernetes:
helm install cloud ./helm/cloud # charts at hanzoai/cloud helm/cloud
The chart deploys the same ghcr.io/hanzoai/cloud image with the same config surface (--enable / CLOUD_* per HIP-0106) and pins replicas=1 while the embedded IAM is enabled (the session single-replica guard). BYO ingress-controller integration follows the estate topology of HIP-0112. Shipped: the chart exists in-tree at cloud/helm/cloud.
A mode is a command-line entry point, never a fork or a build flag (the cloud-fat airgap variant differs only by the embedded k3s payload, not by application code).
issuer, and data dir mean the same thing in every mode.
balance-floor gating (HIP-0106 realized state; HIP-0018) apply identically — a single-node install bills like the SaaS.
stand up the cluster, replicate the SQLite/ZapDB state (HIP-0107 / HIP-0302), repoint DNS. No schema rewrite, no "export".
modes run and the product surface it serves; realized state documents cloud.Serve, the embeds, and the measured binary)
the single-node vs HA state substrate)
cluster initinstalls and defers to)
images the operator pulls)
Mode 2/3 converge to)
concern)
installation