Installing Moʻolelo
Moʻolelo runs on Kubernetes. The supported install method is Helm; an ArgoCD ApplicationSet is provided for GitOps-style continuous deployment.
This page covers a fresh install. For day-2 operations (scaling, troubleshooting, license rotation) see Observability, Scaling, and License key management.
Prerequisites
| Requirement | Notes |
|---|---|
| Kubernetes cluster | Version 1.28+, with at least 4 CPU and 16 GiB RAM available |
| Object storage | AWS S3, S3-compatible (MinIO, Ceph, Cloudflare R2), Google Cloud Storage, or Azure ADLS Gen2 — see Storage backends |
| Apache Pulsar | Version 3.x. Can be deployed into the same cluster or use an existing one |
| Project Nessie | Version 0.99+, configured to use the same object storage as Moʻolelo |
| Postgres | Version 14+, used for connector configuration |
| Helm | Version 3.13+ |
| (Optional) KEDA | For Pulsar-lag-based autoscaling of consumer services |
| (Optional) Linkerd | For mTLS between services via SPIFFE workload identity |
| License key | Get this from your Moʻolelo account team |
Step 1 — bring up the substrate
If you don't already have Pulsar, Nessie, and Postgres in your cluster, install them via their upstream charts:
helm repo add apache-pulsar https://pulsar.apache.org/charts
helm install pulsar apache-pulsar/pulsar --namespace moolelo-system --create-namespace
helm repo add nessie https://charts.projectnessie.org
helm install nessie nessie/nessie --namespace moolelo-system \
-f path/to/your-nessie-values.yaml
helm install postgres bitnami/postgresql --namespace moolelo-system \
--set auth.username=moolelo \
--set auth.database=mooleloConfigure Nessie to use your chosen object storage as its warehouse — see the Project Nessie object-storage docs for the exact key names per backend (S3, GCS, ADLS).
Step 2 — install Vespa
Moʻolelo doesn't ship a Helm chart for Vespa today; install Vespa via the upstream operator or container, deploy the Moʻolelo application package, and confirm health:
zip -j /tmp/app.zip \
deploy/vespa/services.xml \
deploy/vespa/hosts.xml \
deploy/vespa/schemas/chunk.sd \
deploy/vespa/schemas/entity.sd
curl -s -H "Content-Type: application/zip" \
--data-binary @/tmp/app.zip \
https://<your-vespa-config-host>:19071/application/v2/tenant/default/prepareandactivateThe application package ships in deploy/vespa/ in the Moʻolelo source tree — services.xml, hosts.xml, and the schema files for chunk and entity.
Step 3 — create the secrets
Moʻolelo expects two Kubernetes secrets:
# 1. Postgres DSN for the connector service
kubectl create secret generic connector-postgres-dsn \
--namespace moolelo-system \
--from-literal=dsn='postgres://moolelo:<password>@postgres:5432/moolelo?sslmode=require'
# 2. Webhook signing secrets (one per active provider)
kubectl create secret generic webhook-ingress-secrets \
--namespace moolelo-system \
--from-literal=github=<random-32-byte-string> \
--from-literal=confluence=<random-32-byte-string> \
--from-literal=sharepoint=<random-32-byte-string>For production, External Secrets Operator + HashiCorp Vault is the recommended pattern so secrets rotate without redeployment.
Step 4 — install the Moʻolelo services
The data-plane services install as a single Helm ApplicationSet via ArgoCD, or one chart at a time via Helm directly:
helm install connector deploy/helm/connector \
--namespace moolelo-system \
--set image.tag=v0.1.0
helm install webhook-ingress deploy/helm/webhook-ingress \
--namespace moolelo-system
helm install iceberg-sink deploy/helm/iceberg-sink \
--namespace moolelo-system \
--set warehouse=s3://your-bucket/moolelo-warehouse/ \
--set 'catalogProperties.secretRef.name=iceberg-catalog-credentials'
helm install entity-extractor-dispatcher deploy/helm/entity-extractor-dispatcher \
--namespace moolelo-system
helm install tokenizer-driver deploy/helm/tokenizer-driver \
--namespace moolelo-system
helm install vespa-projector deploy/helm/vespa-projector \
--namespace moolelo-system \
--set 'env.VESPA_PROJECTOR_VESPA_BASE_URL=http://moolelo-vespa.moolelo-system:8080'
# Query path
helm install query-coordinator deploy/helm/query-coordinator \
--namespace moolelo-system
helm install mcp-server deploy/helm/mcp-server \
--namespace moolelo-system
helm install webserver deploy/helm/webserver \
--namespace moolelo-system \
--set postgresSecret.name=connector-postgres-dsnThe query path comprises three services:
query-coordinator— the gRPC search service that runs hybrid retrieval, applies source-system permissions, detokenizes vault fields, and emits audit rows.mcp-server— the Model Context Protocol surface for LLM agents (see Querying via MCP). Callsquery-coordinatorover gRPC.webserver— the operator/admin HTTP API. Also callsquery-coordinatordirectly for the admin search preview. (mcp-serveris not in the path; the two surfaces are independent clients.)
Step 5 — pick an ML topology
The parser and embedder services have three deployment shapes — pick the one matching your infrastructure. See Choosing a deployment topology for the trade-offs.
# Topology A: in-cluster, no Ray (simplest)
helm install ml deploy/helm/ml-tier1-embedded --namespace moolelo-system
# Topology B: KubeRay + KServe (in-cluster with GPU pool)
helm install ml deploy/helm/ml-tier2-kuberay --namespace moolelo-ml --create-namespace
# Topology C: external (Ray on VMs, KServe in another cluster)
helm install ml deploy/helm/ml-tier3-external --namespace moolelo-system \
--set parser.url=https://parser.your-domain.com \
--set embedder.url=https://embedder.your-domain.comStep 6 — install your license key
kubectl create secret generic moolelo-license-key \
--namespace moolelo-system \
--from-file=license.key=/path/to/license.keyUpdate each service's deployment to mount the secret and set MOOLELO_LICENSE_PATH=/etc/moolelo/license.key. See License key management.
Step 7 — verify
Each Moʻolelo service exposes /healthz and /readyz. Once everything is Ready:
kubectl get pods -n moolelo-system
NAME READY STATUS RESTARTS AGE
connector-7d4b8c5f5-abc12 1/1 Running 0 2m
entity-extractor-dispatcher-7c9... 1/1 Running 0 2m
iceberg-sink-0 1/1 Running 0 2m
mcp-server-849c7d... 1/1 Running 0 2m
query-coordinator-6db5b... 1/1 Running 0 2m
tokenizer-driver-6f4... 1/1 Running 0 2m
vespa-projector-7c9b8... 1/1 Running 0 2m
webhook-ingress-5d4... 1/1 Running 0 2m
webserver-79c5b... 1/1 Running 0 2mYou're now ready to connect a source.
ArgoCD-managed deployments
Skip the per-chart helm install calls and apply the ApplicationSet:
kubectl apply -f deploy/argocd/applicationset.yaml
# Plus exactly one ML-topology Application:
kubectl apply -f deploy/argocd/ml-tier1-embedded.yamlArgoCD picks up changes from the chart values files in your fork of the repo. The recommended pattern is: fork this repository, edit deploy/values/base.yaml with your environment-specific values, and point your ArgoCD Application resources at your fork. Add deploy/values/with-vault.yaml and/or deploy/values/with-openfga.yaml to opt into the privacy substrate or the OpenFGA-backed ACL evaluator.
Air-gap installs
Every container image, Helm chart, and ML model used by Moʻolelo is mirror-able to your own registry. The install steps above are unchanged; you set image.repository to your mirror's hostname and pre-pull all model weights into the embedder image.
If your environment has zero outbound network, the deploy/airgap/mirror-pipeline.sh script in the repo mirrors all images, Helm charts, and ML model artifacts to a target Harbor instance. See deploy/airgap/README.md for the full procedure.

