Skip to content
Docs

Deploying Cluster Mode

deploy/helm/hyve is a single Helm chart deploying both components of Cluster Mode — the controller and the API — together.

Install

The chart isn’t published to a Helm repository — install it from a hyve checkout. The image is published to ghcr.io/cbridges1/hyve with every release.

Get the chart and apply the CRDs

Terminal window
git clone https://github.com/cbridges1/hyve.git && cd hyve
kubectl apply -f deploy/helm/hyve/crds/

Install the chart

Terminal window
helm upgrade --install hyve deploy/helm/hyve \
--namespace hyve-system --create-namespace \
--set image.repository=ghcr.io/cbridges1/hyve \
--set image.tag=<version> \
--set api.publicBaseURL=https://hyve.example.com \
--set api.multiTenant.enabled=true

hyve-api generates and stores its own session-signing key on first start — there’s no Secret to create.

Expose hyve-api

The chart creates a plain ClusterIP Service (hyve-api, port 80) and no Ingress. Expose it however your cluster already does — an Ingress, a LoadBalancer Service, a tunnel (e.g. Pangolin or Cloudflare), or kubectl port-forward for a quick look. Terminate TLS in front of it and set api.publicBaseURL to that HTTPS address. The same address serves the web console — and hyve-agent, which tunnels back over a WebSocket at /agent/tunnel, so whatever fronts hyve-api must allow WebSocket upgrades; no other port needs exposing.

Create the first superadmin

Accounts live in hyve-api’s own datastore, so this runs inside the API pod:

Terminal window
kubectl -n hyve-system exec deploy/hyve-api -- \
hyve cluster-config api create-user admin --role superadmin --namespace hyve-system

Pass --password for scripting; omit it to be prompted. Or skip this step entirely by setting api.bootstrapAdmin.username and api.bootstrapAdmin.passwordSecret.name (an existing Secret with a password key) at install time — or api.bootstrapAdmin.usernameKey instead of username to read the username from that same Secret.

Log in

Terminal window
hyve context login --api-url https://hyve.example.com

Key values

ValuePurpose
image.repository / image.tagThe hyve image — ghcr.io/cbridges1/hyve and a release tag
namespaceThe control-plane namespace both components run in (default hyve-system)
api.publicBaseURLThe HTTPS address callers reach hyve-api on — required for host-cluster and hyve-agent kubeconfigs
api.multiTenant.enabledLets one install serve many organizations (a ClusterRole instead of a namespaced Role). With api.db.driver: postgres, hyve-controller also reconciles every organization on the home cluster (it reads them from the same database, and restarts itself to pick up new ones)
controller.agent.controlPlaneURLhyve-api’s public HTTPS address (usually api.publicBaseURL) — where a newly installed hyve-agent bootstraps and tunnels to. Unset disables hyve-agent installs
api.db.driversqlite (default, one API replica, stored on a PVC) or postgres — required for more than one replica or for moving organizations onto reconciling clusters
api.requireReconcilingClusterRefuse to let any tenant organization live on the home cluster
api.bootstrapAdmin.username (or .usernameKey) / .passwordSecretCreate the first superadmin on startup, only while none exists — replaces the manual create-user step. Not an API endpoint; the password (and, with usernameKey, the username) is read from a mounted Secret
api.smtp.host / .port / .username / .fromAddress / .passwordSecretSeed outbound email (password resets) on first start; settings saved later in the console always win
api.service.type / api.service.nodePortClusterIP by default; NodePort only where node ports are reachable
api.accessRoles.clusterScopedSee the warning below — leave at its default

Running multiple tenants on one cluster

Multiple hyve installs (each its own controller + API pair) can safely share one cluster, isolated by namespace — every hyve.io CRD is namespaced, and (with clusterScoped: false, the default) each install’s roles are scoped to its own namespace only:

Terminal window
kubectl create namespace tenant-a
helm install hyve-tenant-a deploy/helm/hyve \
--namespace tenant-a \
--set namespace=tenant-a \
--set image.repository=ghcr.io/cbridges1/hyve --set image.tag=<version>

A second tenant is the identical pattern with a different namespace — no shared config beyond a common image. For most setups, one install serving several organizations (api.multiTenant.enabled=true) is simpler than one install per tenant.