Skip to main content
Deploy the 4minds platform to your own Kubernetes cluster with a single helm install. The umbrella chart carries every service and datastore, and its own hooks do all in-cluster orchestration (OpenBao init/unseal, DB migrations, Kafka topics) — no external installer binary is required. You configure the deployment through one values file: copy the values template at the bottom of this page to my-values.yaml and fill in your hostname, inference endpoints, and options.
The prerequisite commands below use Amazon EKS as the worked example (eksctl, EBS CSI, IRSA). On another Kubernetes distribution, substitute the equivalent steps — a default StorageClass, a CSI driver, an ingress controller, and (for KMS auto-unseal) a cloud KMS key + workload identity.

What you’ll do

  1. Prerequisites (Steps 1–7) — prepare the cluster and platform plumbing the chart does not create (cluster/OIDC, storage, ingress, namespace, TLS, image pull, and — only for production KMS unseal — a KMS key + IAM role).
  2. Configure — copy the template to my-values.yaml and fill it in.
  3. Install — one helm install with your values.
  4. Verify — confirm pods are Running and the UI answers.
Sections after that cover upgrades, uninstall, and troubleshooting.

Before you start

Required CLI tools: aws, kubectl, helm (v3.8+, OCI support), eksctl (for the EKS example steps), and openssl (only if you want a self-signed test cert). Make sure your aws CLI is authenticated to the account that owns the cluster. Set these environment variables — every command below references them:
Then confirm none are empty:
Copy-paste tip. If a multi-line command (with a trailing \) breaks in your shell, paste it as a single line instead.

Prerequisites

Step 1 — EKS cluster with OIDC

What this does: creates (or reuses) the Kubernetes cluster. --with-oidc is the only hard requirement — IRSA (used for KMS auto-unseal and the EBS driver) needs it. Skip the create cluster command if you already have a cluster; use your own version / instance type / node count.
If the cluster already exists, just make sure the OIDC provider is associated:
Sizing (guidance, not a requirement). The full platform runs many services plus stateful datastores. A reasonable starting point for the application tier is 3 × m5.2xlarge (8 vCPU / 32 GiB each); scale to your workload. Inference is separate. This chart does NOT run models — it points at OpenAI-compatible endpoints you set in my-values.yaml (llm.*, mlai.embedding, symi-gateway.config, wren-ai). Those can be a managed service or GPU nodes in this same cluster (add a g5/p4 node group and point the endpoints at the in-cluster services).

Step 2 — Default StorageClass + EBS CSI driver

What this does: gives stateful services (PostgreSQL, Redis, Kafka, MinIO, Qdrant, OpenBao, mlai) a default StorageClass backed by a working CSI driver. OpenBao persists its vault data on a 2Gi PVC, so this is required even for seal.mode: lab — without persistence, a pod restart re-initializes the vault and drops the seeded secrets.

Step 3 — ingress-nginx controller

What this does: installs the NGINX ingress controller. The chart creates an Ingress of class nginx; the controller itself is a prerequisite.

Step 4 — Namespace

What this does: creates the namespace everything installs into.

Step 5 — TLS secret for your hostname

What this does: provides the certificate the Ingress uses to terminate TLS. The Ingress reads the secret named by frontend-backend.ingress.tlsSecretName (default frontend-tls). The host and TLS entry derive from global.hostname automatically, so you only create the secret here. Option A — you already have a cert (ACM-issued, Let’s Encrypt, etc.):
Option B — self-signed (testing/PoC only; browsers will warn):
Using a different secret name? Set frontend-backend.ingress.tlsSecretName in my-values.yaml to match.

Step 6 — Image pull (usually nothing to do)

What this does: lets the cluster pull the images. On AWS Marketplace the images live in the Marketplace ECR and your EKS node IAM role pulls them automatically (attach AmazonEC2ContainerRegistryReadOnly to the node role if it isn’t already). In that case leave global.imagePullSecrets: []. Only if you mirror the images into your own private registry do you create a pull secret and list its name under global.imagePullSecrets.

Step 7 — OpenBao KMS auto-unseal (production only)

What this does: sets up AWS KMS + an IRSA role so OpenBao auto-unseals without in-cluster keys. Skip this entire step if you use seal.mode: lab (Shamir keys stored in-cluster — fine for test/PoC).
Then set these in my-values.yaml. The chart binds roleArn onto the OpenBao ServiceAccount as eks.amazonaws.com/role-arn automatically (no manual annotation, survives helm upgrade):
Azure / GCP: set provider: azure (tenantId/vaultName/keyName) or provider: gcp (projectId/locationId/keyRing/cryptoKey) and bind the pod identity via openbao.serviceAccount.annotations (Workload Identity).

Prerequisites summary


Configure

What this does: creates your deployment’s values file. Copy the template and fill in the required fields — hostname, email, LLM/embedding endpoints, symi, wren-ai, seal mode, and any SSO/integrations you use. Everything else has a sensible default.

(Optional) External S3 instead of the bundled MinIO

By default object storage is the in-cluster MinIO and you set nothing. To use AWS S3 (or any S3-compatible endpoint) instead, add to my-values.yaml:
Leave storage.endpoint / secrets.s3* empty to keep the bundled MinIO. If you also set OAuth client secrets, put the S3 keys under the same secrets: block — a second secrets: key silently overrides the first (YAML has no merge). For Azure Blob, set storage.useAzure: "true" and secrets.azureStorageAccountKey in that same block.

Install

What this does: deploys the platform with your values. The chart’s hooks then run automatically (OpenBao init+unseal, backend-secret seeding, Kafka topics, the mlai schema migration) — no manual steps.
AWS Marketplace subscribers. After subscribing, the AWS console gives you a helm pull (from the Marketplace ECR) + helm install snippet. That snippet installs with defaults only — you MUST append your config, or the platform comes up unconfigured (no hostname, no inference endpoints). Keep the AWS --set flag AND add -f my-values.yaml:

Verify

What this does: confirms the platform is up and serving.
Then open https://$HOSTNAME_FQDN and sign up (email + password works out of the box; SSO only if you configured a provider).

Upgrades

Hooks are idempotent (OpenBao “already initialized”, mlai migration re-verify). Auto-generated secrets (PG/Redis/MinIO/Fernet/Tier/SYMI) are preserved across upgrades via helm.sh/resource-policy: keep.

Uninstall

⚠️ Deleting PVCs destroys all data (Postgres, Qdrant, MinIO, etc.).

Troubleshooting

Values template

Copy the template below to my-values.yaml, fill in the required fields (hostname, email, inference endpoints), and pass it to helm install with -f.
my-values.yaml