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.yamlProvide 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: trueApply that with:
helm upgrade --install gestalt \
oci://ghcr.io/valon-technologies/gestalt/charts/gestalt \
--namespace gestalt \
--set image.tag=<version> \
-f values-production.yamlImportant Chart Values
| Value | Purpose |
|---|---|
config | Rendered as /etc/gestalt/config.yaml. |
extraEnv | Environment variables used by ${VAR} placeholders in config. |
persistence | PVC settings for SQLite or other local state. |
pluginInit.enabled | Runs 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. |
ingress | Standard ingress settings. |
ingress.hosts[].paths | Per-host ingress paths and path types. |
managementService | Optional 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: trueThis 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.