Core Deployment
Helm Charts
Everything needed to deploy the platform lives in deploy/. Each service has its own chart under
deploy/{service}/helm; the supporting infrastructure is either a chart in the same tree or a
third-party chart referenced from the helmfile.
| Path | Chart |
|---|---|
|
|
|
|
|
|
|
Elasticsearch and Kibana, deployed through the Elastic Cloud on Kubernetes operator. |
|
Neo4j, as a StatefulSet with a persistent volume. |
|
Apache ActiveMQ Artemis broker. Has its own |
|
OpenTelemetry collector configuration. |
|
|
|
KServe serving runtimes and a JVM-based model server. |
|
Unreal Engine rendering service. |
Cluster add-ons that are applied directly rather than through a chart of their own (GPU operator,
device plugins, local path provisioner) are in deploy/drivers/ and the deploy/values-*.yaml
files.
Engine Chart
deploy/engine/helm deploys the engine as a Deployment behind a Service and an nginx Ingress.
Values
| Value | Default | Description |
|---|---|---|
|
|
Pod count. With more than one replica the chart adds required pod anti-affinity by hostname, so replicas land on different nodes. |
|
|
Compose the host name: |
|
|
Primary and optional secondary ingress domain. The secondary domain gets its own Ingress with identical routing. |
|
registry image / |
Container image and tag. |
|
|
HTTP port. The Socket.IO port |
|
heap and direct memory limits |
JVM options. The default caps heap at 40% of the container memory (2 GiB of the 5 Gi limit) and direct memory at 1 GiB — see Memory Budget. |
|
OpenTelemetry agent and collector endpoints |
Applied when |
|
|
Enables the OpenTelemetry environment block and renders a Prometheus Operator |
|
|
Name of the secret (or CSI-projected volume key) holding |
|
|
Identity prefix and ref of the resource storage container. |
|
5 Gi memory |
Requests and limits. |
|
enabled |
Toggle the credential wiring for each provider. |
|
|
Renders an additional canary Ingress with an nginx traffic-split annotation and a |
|
|
Schedules the pods onto spot nodes — used by ephemeral environments. |
|
|
Certificate issuer, ingress class and image pull secret. |
Memory Budget
The container memory limit has to hold more than the Java heap. Under production load an engine replica uses:
| Part | Size | Notes |
|---|---|---|
Heap |
2 GiB |
|
Direct memory |
~0.7 GiB |
Netty’s pooled buffers. They grow during the first hours and then level off; the cap is
|
Non-heap |
~0.4 GiB |
Metaspace and code cache. |
Other native memory |
~0.75 GiB |
Thread stacks (400–500 threads), GC structures and malloc arenas. The JVM metrics do not show it; it is the container RSS minus the three parts above. |
That adds up to about 3.9 GiB, or 4.2 GiB with direct memory at its cap. With the former 4 Gi limit
and a 50% heap, replicas ran at the limit and the kernel OOM-killed them. When you change the heap
percentage, the direct memory cap or the limit, keep heap plus direct memory at least 1.5 GiB below
the limit. Development environments are the one exception: values-develop.yaml keeps a 4 Gi limit
with the default JVM options, so 1.6 GiB of heap plus 1 GiB of direct memory falls slightly short of
this margin, which their low load tolerates. The parts are exported as jvm_memory_committed_bytes,
jvm_buffer_memory_used_bytes{id="direct"} and, for the whole container,
container_memory_working_set_bytes.
Templates
| Template | Renders |
|---|---|
|
Deployment with a rolling update strategy, both container ports ( |
|
|
|
ClusterIP Service exposing port |
|
Ingress with TLS, WebSocket support, cookie affinity, disabled buffering and unlimited body size.
Routes |
|
The same routing for |
|
Prometheus Operator ServiceMonitor, when |
Prerequisites
The chart expects the following to exist in the target namespace:
-
a secret named after
app.localConfigName(defaultpromethist-engine) containingapplication-default.properties, and — when the corresponding toggle is on — the Google service account key and Firebase admin key. In Azure clusters this is projected from Key Vault by theazure-secret-providerSecretProviderClass(deploy/secret-provider.yaml); -
an
aws-credentialssecret whenaws.enabledis set; -
the image pull secret named by
imagePullSecrets; -
a reachable OpenTelemetry collector when
app.serviceMonitoris enabled; -
the external data stores the engine connects to (MongoDB, Elasticsearch, optionally Neo4j) and a Keycloak realm, configured through
application-default.properties.
Installing
helm -n $NAMESPACE upgrade --install promethist-engine deploy/engine/helm \
--set app.namespace=$NAMESPACE \
--set app.domain=promethist.dev \
--set app.image=registry.gitlab.com/promethistai/promethist/engine \
--set app.tag=$IMAGE_TAG
For a development environment add -f deploy/engine/helm/values-develop.yaml --set replicas=1.
The same invocation is what CI runs — see Core Deployment.
The chart is also packaged and published to the internal chart repository on every release.
Bridge Chart
deploy/bridge/helm deploys the bridge service (container port 9013) with a Deployment, Service
and Ingress. In addition to the service itself it renders one CronJob per entry in
e2eCron.jobs, which periodically call the bridge’s own run endpoints to execute scheduled
end-to-end conversation tests. The production value files (values-production-eu.yaml,
values-production-us.yaml) define those schedules per region; each job may carry a variable
group and a bearer token from e2eCron.authSecret.
See Bridge for what those runs actually do.
Relay Chart
deploy/relay/helm deploys the relay service (container port 9012) with a Deployment, Service
and Ingress. It is the simplest of the three service charts — no configuration files, no secrets
and the smallest resource footprint.
Platform Infrastructure with Helmfile
deploy/helmfile.yaml.gotmpl assembles the shared platform infrastructure — Keycloak,
PostgreSQL, MinIO, the Elastic stack and the telemetry stack (OpenTelemetry collector, Prometheus,
Grafana, Tempo, Loki, Promtail) — alongside the engine release.
Environments are defined at the top of the helmfile (production, preview, issue, develop,
local); each layers environments/defaults.yaml.gotmpl, its own
environments/{name}/values.yaml.gotmpl and environments/secrets.yaml.gotmpl. Per-release
values are templates under deploy/configs/.
cd deploy
helmfile apply --environment develop
Individual releases can be selected by label, which is the usual way to touch one component only:
helmfile apply --environment develop -l name=engine -l name=minio
Which components are installed is driven by the components.* toggles of the environment —
all, runtime, telemetry, analytics, keycloak, postgresql, minio. Values can be
overridden ad hoc with --state-values-file or --state-values-set.
The helmfile expects credentials for PostgreSQL, Keycloak, Azure storage, Grafana and MinIO in the
environment; deploy/README.md lists them together with the Keycloak client setup and the steps
for adding a new environment.
The engine can be deployed both through the helmfile and, as CI does, by a direct
helm upgrade --install of deploy/engine/helm. Both paths use the same chart, but they are
separate release histories — pick one per environment rather than mixing them.
|