Install with Helm
The chart deploys the API, the SPA, and (optionally) a bundled Postgres. It's a
public OCI package: oci://ghcr.io/edgentia-core/charts/edgentia.
Evaluating on a cluster? The Kubernetes quick-start bundles wrap this chart with ready-made values, a bundled Keycloak, and a device simulator (broker + synthetic data) so you can see edgentia working end-to-end fast — for Keycloak or Entra. This guide is the full chart reference for a production install.
Quick install
helm install edgentia oci://ghcr.io/edgentia-core/charts/edgentia --version 0.1.3 \
--namespace edgentia --create-namespace \
--set config.appBaseUrl=https://edgentia.acme.com \
--set security.encryptionKey="$(openssl rand -base64 32)" \
--set database.password="$(openssl rand -base64 24)" \
--set auth.mode=entra \
--set auth.entra.tenantId=<tenant-guid> \
--set auth.entra.clientId=<client-guid>For Keycloak instead of Entra:
--set auth.mode=keycloak \
--set auth.keycloak.authority=https://kc.acme.com/realms/edgentia \
--set auth.keycloak.adminClientSecret=<edgentia-api secret>A values file is cleaner than many --sets for a real install:
helm install edgentia oci://ghcr.io/edgentia-core/charts/edgentia \
--version 0.1.3 -n edgentia --create-namespace -f my-values.yamlInstall one release per namespace. The API Service is named
api, which the frontend's nginx proxy depends on — two releases in one namespace would collide.
Values reference
| Key | Default | Notes |
|---|---|---|
config.appBaseUrl | — | Required. Your public URL (email links + default CORS origin). |
config.corsOrigins | [appBaseUrl] | Extra browser origins allowed to call the API. |
config.managementLevel | 1 | User-management seed (1 = directory + verified members; 2 = + invites, Keycloak only). |
security.encryptionKey | — | Required. 32-byte base64 (openssl rand -base64 32). |
auth.mode | keycloak | entra or keycloak. |
auth.entra.tenantId / .clientId | — | Required in Entra mode. |
auth.entra.clientSecret | — | Optional — only the directory "add member" picker. |
auth.keycloak.authority | — | Required in Keycloak mode (the realm issuer URL the API uses for keys). |
auth.keycloak.validIssuer | — | Set when the browser-facing issuer differs from authority. |
auth.keycloak.adminClientId | edgentia-api | Confidential client for the directory/invites. |
auth.keycloak.adminClientSecret | — | That client's secret. |
auth.keycloak.requireHttpsMetadata | true | false only if the metadata endpoint is plain HTTP. |
license.token | — | Optional — seed a signed .elic at startup (else install in the UI). |
license.checkInUrl | — | Optional — HTTPS issuer check-in endpoint (hybrid licensing). |
database.bundled | true | Run an in-cluster Postgres (TimescaleDB) with a PVC. |
database.password | — | Required (bundled DB password + the connection string). |
database.external.host / .port | — | Used when bundled=false. |
database.persistence.size | 10Gi | Bundled DB volume size. |
database.persistence.storageClass | "" | "" = cluster default. Set it explicitly if the cluster has more than one default. |
image.tag | chart appVersion | Override the image tag for both images. |
ingress.enabled | false | Off by default — wire your own (see below). |
ingress.className / .host / .tls.* | — | Used when ingress.enabled=true. |
Database: bundled vs your own
database.bundled=true (default) runs a single in-cluster Postgres on a PVC —
ideal for a quick start. For production, point at your own managed database:
database:
bundled: false
password: <password for that DB>
external:
host: postgres.internal
port: 5432The chart builds the connection string from these values and stores it in a Kubernetes Secret; no Postgres pod is deployed.
Ingress is yours
Ingress is off by default. The frontend Service (<release>-frontend, port 80)
is the single entry point — it serves the SPA and proxies /v1 + /health to the
in-cluster api Service. Expose it however you like:
- Your own ingress / LoadBalancer pointed at the frontend Service, or
- the chart's optional Ingress:
--set ingress.enabled=true --set ingress.className=nginx(host defaults toappBaseUrl's host; add--set ingress.tls.enabled=true --set ingress.tls.secretName=<tls>for TLS), or - a quick local check:
kubectl -n edgentia port-forward svc/edgentia-frontend 8080:80.
Secrets handling
The chart renders secrets (encryptionKey, connection string, auth client secret,
license) into a Kubernetes Secret and the pods read them via secretKeyRef — so
they aren't inline in the Deployment spec. The input path is the risk: a
plaintext values.yaml (especially if committed) or --set on the CLI both leak.
For production, pre-create the Secret yourself (Vault / External Secrets / Sealed
Secrets / sops) or encrypt the values file, and enable etcd encryption-at-rest with
tight RBAC on Secrets.
Sign in and license
After install, reach the UI, sign in, and install your license in Settings → License.