Skip to content

Production deployment overview

Elitea’s Kubernetes path is one Helm chart, elitea, for everything: the platform, NATS JetStream with its stream bootstrap, the vector store and, where a cluster needs it, the sandbox-runtime installer. ArgoCD syncs it as one Application through an app-of-apps root. This page is the map; Deploy from scratch walks a complete first install, Install with Helm is the shorter reference, and Deploy on GKE with Argo CD is the GitOps install on Google Cloud.

flowchart TB
    Browser["Browser"] --> Edge["Ingress / Gateway API: one / route"]
    Edge --> Main["elitea-main"]
    Main -->|"relays /app, /docs"| Web["elitea-web (SPA)"]

    Main --> Gateway["LLM gateway"]
    Main --> Scheduler["elitea-scheduler"]
    Main --> SubappHost["subapp-host: DeepWiki / Inventory"]
    Main -. mTLS control/output/content .-> Worker["agent worker (Rust)"]

    Gateway --> Worker
    Gateway --> NATS[("NATS JetStream")]
    Scheduler --> NATS

    Main --> DB[("PostgreSQL")]
    Worker --> DB
    Gateway --> DB
    SubappHost --> DB

    Main --> NATS
    Main -. mTLS .-> NATS
    Worker -. "mTLS (command bus)" .-> NATS

    Main --> Object[("Object storage")]
    SubappHost --> Object

Every arrow into the worker and the NATS command bus is mutually authenticated (mTLS; the command bus is NATS JetStream, elitea-main publishing as its own identity and the workers pulling from their own account) — that plane’s material is described in Install with Helm and deploy/runtime/README.md. DeepWiki and Inventory are two instances of the same subapp-host pattern: a Go host process reaching a Rust engine sidecar over a Unix socket inside one pod.

What the chart creates, and what you bring

Section titled “What the chart creates, and what you bring”

The chart is one release — elitea-main and its migration Job, elitea-web, the scheduler, the LLM gateway, the agent worker, the OTel collector, the database-preparation Job, the DeepWiki and Inventory provider services with their own migration Jobs, and the vector store: elitea-vector (vector.enabled) with Qdrant (qdrant.enabled, the upstream qdrant chart bundled like NATS), which indexing and the native DeepWiki and Inventory engines need. The runtime plane, the worker, the vector store, DeepWiki and Inventory are all on by default, one switch each (<feature>.enabled: false leaves one out). NATS JetStream and its bootstrap Job are in the same release (nats.enabled, on by default), ordered ahead of the workloads; the sandbox-runtime installer (sandboxRuntime.enabled) is off unless a k3s or EKS cluster needs gVisor on its nodes.

PostgreSQL

No chart provisions it. Point postgresql.existingSecret at a Secret holding the DSN; the database may start empty (the migration Job bootstraps the schema itself), but an administrator DSN is still needed for CREATE DATABASE. Plain PostgreSQL is enough: no extension, because every vector is in Qdrant.

cert-manager and secrets

cert-manager must be installed: the bundled NATS CA, every NATS identity and the in-cluster mTLS hops are its Certificates. Secrets come from you, or from your secret manager through the chart’s externalSecrets block (External Secrets Operator).

Object storage

An S3-compatible endpoint for artifacts and DeepWiki/Inventory output. The bucket must exist before the first sync (or set objectInit.enabled: true for a self-hosted S3-compatible store you administer directly); a missing bucket lets the deployment look green and then crash-loop on the next boot step.

Ingress

No Ingress or HTTPRoute renders until main.ingress.enabled is on. Then it is one / rule with elitea-main as the sole backend, and that is the whole edge: elitea-main relays /app and /docs to elitea-web. Your ingress controller or Gateway, DNS and public certificate are yours; on GKE, main.ingress.gke adds what the Google load balancer needs.

OIDC/SAML identity provider, TLS

The chart consumes an authentication configuration document or OIDC_ISSUER_URL; it issues no certificates of its own beyond the in-cluster mTLS hops (cert-manager issuers, brought by you).

The runtime plane (agent execution) opens six isolated connection pools per elitea-main replica — 36 connections beyond the primary pool — and they may not share capacity. values-standalone.yaml sizes for this explicitly: at postgresql.maxConnections: 200 and main.autoscaling.maxReplicas: 4, four replicas cost roughly 4 × 42 = 168 connections, inside the 175 left after reservedConnections: 25 (interactive psql, backup tooling, the migration and dbInit Jobs). The chart’s own guard (elitea-main.validateConnectionBudget) refuses to render a topology that would exceed the stated ceiling, rather than letting it surface later as FATAL: sorry, too many clients already on whichever component connects next.

Every chart (elitea, and the standalone elitea-sandbox-runtime) and every first-party image is built, cosign-signed (keyless) and pushed to ghcr.io/elitea-ng by the release job in .github/workflows/publish.yml, after the images they reference are already pushed and signed.

Terminal window
helm install elitea oci://ghcr.io/elitea-ng/charts/elitea --version <tag>

Both charts are also listed on Artifact Hub. The listing shows the values reference and every version, with pre-releases marked. It also shows a security report on the images that version ships. The listing reads the same OCI charts; it is not a second copy.

  1. Charts have no `latest` tag

    An OCI chart reference resolves by SemVer, so --version <tag> is required in practice — there is no floating tag to fall back on.

  2. `image.tag` is stamped at package time

    The in-repo chart defaults to "latest"; the published chart’s image.tag is rewritten to the release version so it never installs a stale cached layer.

  3. Verify the signature

    Terminal window
    cosign verify ghcr.io/elitea-ng/charts/elitea:<tag> \
    --certificate-identity-regexp '^https://github.com/elitea-ng/elitea-platform/' \
    --certificate-oidc-issuer https://token.actions.githubusercontent.com

    Image manifests verify the same way, against ghcr.io/elitea-ng/<component>:<tag>. Every image and chart also carries signed SLSA build provenance, and every image a CycloneDX SBOM. Verify release artifacts shows how to check them, and how to enforce them at admission.

Continue to Install with Helm for the step-by-step install, or GitOps with ArgoCD if you are deploying through the app-of-apps.