Skip to Content
DeployHelm

Helm

Gestalt publishes a Helm chart for deploying gestaltd to Kubernetes.

Install The Chart

helm upgrade --install gestalt \ oci://ghcr.io/valon-technologies/gestalt/charts/gestalt \ --namespace gestalt \ --set image.tag=<version> \ -f values.yaml

Provide a values.yaml file that sets the required datastore and server settings, and auth settings when you enable platform login, along with the matching extraEnv entries.

The default chart profile is intentionally minimal:

  • platform authentication omitted
  • SQLite on a PVC mounted at /data
  • a static dev-only server.encryptionKey
  • one replica
  • no ingress

That profile is suitable for local development and trusted internal clusters. It is not a production-ready security posture. Override config.server.encryptionKey before any shared, persistent, or production deployment.

Production Install Pattern

For production, override the default authentication and datastore settings and provide the required environment variables through extraEnv. Prefer enabling the separate management listener and internal management Service so /admin and /metrics do not share the public listener.

config: server: baseUrl: "${GESTALT_BASE_URL}" encryptionKey: "${GESTALT_ENCRYPTION_KEY}" providers: auth: oidc indexeddb: main providers: auth: oidc: source: https://artifacts.example.com/auth/oidc/v0.0.1-alpha.1/provider-release.yaml config: issuerUrl: "${OIDC_ISSUER_URL}" clientId: "${OIDC_CLIENT_ID}" clientSecret: "${OIDC_CLIENT_SECRET}" indexeddb: main: source: https://artifacts.example.com/indexeddb/relationaldb/v0.0.1-alpha.1/provider-release.yaml config: dsn: "${DATABASE_URL}" extraEnv: - name: GESTALT_BASE_URL value: "https://gestalt.example.com" - name: GESTALT_ENCRYPTION_KEY valueFrom: secretKeyRef: name: gestalt-secrets key: encryption-key - name: DATABASE_URL valueFrom: secretKeyRef: name: gestalt-secrets key: database-url pluginInit: enabled: true

Apply that with:

helm upgrade --install gestalt \ oci://ghcr.io/valon-technologies/gestalt/charts/gestalt \ --namespace gestalt \ --set image.tag=<version> \ -f values-production.yaml

Important Chart Values

ValuePurpose
configRendered as /etc/gestalt/config.yaml.
extraEnvEnvironment variables used by ${VAR} placeholders in config.
persistencePVC settings for SQLite or other local state.
pluginInit.enabledRuns gestaltd init in an init container before the main server starts. Use it when the chart should prepare locked state for published provider packages or packaged UI bundles.
ingressStandard ingress settings.
ingress.hosts[].pathsPer-host ingress paths and path types.
managementServiceOptional internal Service for a separate management listener.

Example Values

service: type: LoadBalancer port: 8080 managementService: enabled: true type: ClusterIP port: 9090 config: server: public: port: 8080 management: host: 0.0.0.0 port: 9090 baseUrl: "${GESTALT_BASE_URL}" encryptionKey: "${GESTALT_ENCRYPTION_KEY}" providers: auth: oidc indexeddb: main providers: auth: oidc: source: https://artifacts.example.com/auth/oidc/v0.0.1-alpha.1/provider-release.yaml config: issuerUrl: "${OIDC_ISSUER_URL}" clientId: "${OIDC_CLIENT_ID}" clientSecret: "${OIDC_CLIENT_SECRET}" redirectUrl: "${OIDC_REDIRECT_URL}" indexeddb: main: source: https://artifacts.example.com/indexeddb/relationaldb/v0.0.1-alpha.1/provider-release.yaml config: dsn: "${DATABASE_URL}" extraEnv: - name: GESTALT_BASE_URL value: "https://gestalt.example.com" - name: GESTALT_ENCRYPTION_KEY valueFrom: secretKeyRef: name: gestalt-secrets key: encryption-key - name: OIDC_ISSUER_URL value: "https://login.example.com" - name: OIDC_CLIENT_ID valueFrom: secretKeyRef: name: gestalt-secrets key: oidc-client-id - name: OIDC_CLIENT_SECRET valueFrom: secretKeyRef: name: gestalt-secrets key: oidc-client-secret - name: OIDC_REDIRECT_URL value: "https://gestalt.example.com/api/v1/auth/login/callback" - name: DATABASE_URL valueFrom: secretKeyRef: name: gestalt-secrets key: database-url pluginInit: enabled: true

This configuration keeps the public UI and API on port 8080 while exposing /admin and /metrics only through the internal gestalt-management Service on port 9090. If operators need browser access to /admin, place an internal-only ingress, VPN, or identity-aware proxy in front of that management Service rather than exposing it on the public ingress.

When to enable pluginInit

Enable the init container when your config uses published provider metadata URLs under plugins.*.source, providers.authentication.*.source, providers.indexeddb.*.source, or providers.ui.*.source and you want that state prepared before the main container starts. The init container copies the rendered config and runs:

/gestaltd init --config /etc/gestalt/config.yaml

The main container then starts in locked mode against the prepared state.

See Configuration for how the lockfile and prepared artifacts fit together.