Every 3B deployment — from the single-server quick start to a production Kubernetes cluster — runs the same set of components. This page describes what they are, how traffic reaches them, and the properties of the platform they run on.
Components
Component | Kind | Purpose |
| Deployment | The front door. Serves all inbound traffic and routes each request to the right service by hostname and path. Optionally terminates TLS. |
| Deployment | The application server: the UI bundle, the API, sign-in, and workflow editing. |
| Deployment | Schedules and coordinates workflow executions. |
| Deployment | Executes workflow steps. Runs untrusted automation code inside gVisor sandboxes via its |
| Deployment | Serves the addresses 3B shares externally — webhooks and public links. |
| Deployment | The real-time sync service (Zero). The UI holds a persistent websocket to it and receives data and updates as they happen, instead of polling the API. |
| StatefulSet | The database: spaces, workflows, users, and run history. Can be replaced with an external Postgres. |
| StatefulSet | File storage: attachments and the blob store. Can be replaced with S3 Supported Storage. |
| Job | A one-time database migration job that runs on every install and upgrade, before the application services start. |
How traffic flows
3B is reached through four external URL settings — UI, API, public, and Zero sync — served from two hostnames. All of them are served by nginx, which routes by hostname and path:
DNS → load balancer (TLS) → nginx → api / zero-sync / public
The app hostname carries the UI, API, and Zero sync (path-routed). The public hostname is separate. Because the chart ships its own nginx reverse proxy, no ingress controller is required — all you need in front of 3B is a load balancer (or, on a single server, DNS pointing straight at the host). See connectivity requirements for the URL, DNS, and port details.
Sandboxing
3B runs untrusted automation code inside gVisor sandboxes with per-job isolation. This is a defining property of the platform and drives its infrastructure requirements:
Nodes must be x86_64 (amd64) Linux. Arm and other architectures are not supported.
The
apiandworkerpods run withhostUsers: false, so the node must support user namespaces: containerd 2.x, a recent kernel, and theuser.max_user_namespacessysctl set to a non-zero value. Some hardened node images ship with this disabled; the deployment guides cover verifying and enabling it.
Postgres
All persistent application data — spaces, workflows, users, and run history — lives in PostgreSQL, and nearly every request touches it.
By default the chart runs Postgres in-cluster as the postgres StatefulSet, and the single-server install uses this bundled database. On Kubernetes we recommend a managed database (for example AWS RDS) where available, to simplify scaling, backups, and high availability: set postgres.enabled: false and create the credentials yourself as described in the Helm installation guide.
Either way, the database must run PostgreSQL 18 with logical replication enabled (wal_level=logical), which Zero sync requires.
Storage
Postgres and the blobstore each claim a persistent volume through the cluster’s default StorageClass. Both are sensitive to disk latency, so use SSD-backed storage.
Identity
A built-in identity provider is enabled by default, so a fresh install is immediately usable — open the UI and create the first account. SSO via SAML and OIDC is supported for connecting your own identity provider.
