Repository navigation
feat(helm): add optional PostgreSQL backing store for gateway persistence #1599
Copy link
Copy link
Closed
Labels
state:agent-readyApproved for agent implementationApproved for agent implementation
Description
Problem Statement
The OpenShell gateway defaults to SQLite for persistence (sqlite:/var/openshell/openshell.db). While SQLite works well for single-replica development and testing, it is not suitable for production or high-availability deployments where multiple gateway replicas need shared, durable storage with concurrent write support.
Operators deploying OpenShell in production need the option to use PostgreSQL as the backing database.
Proposed Design
Add an optional postgres section to the Helm chart values that lets operators enable PostgreSQL and choose between two modes:
Values schema
postgres:
enabled: false # Toggle SQLite → PostgreSQL
mode: "internal" # "internal" (Bitnami subchart) or "external" (bring your own)
host: "" # External mode: PostgreSQL hostname
port: 5432
database: "openshell"
username: "openshell"
password: "" # Used to populate the Kubernetes Secret
sslmode: "prefer"Internal mode (postgres.mode: internal)
- Add the Bitnami PostgreSQL chart as an optional subchart dependency (condition:
postgres.enabled). - Credentials flow through a generated Kubernetes Secret, not plaintext values.
External mode (postgres.mode: external)
- Operators provide
host,port,database,username, andpassword. - The chart creates a Secret containing the assembled
db-urlconnection string. - No subchart is deployed.
Template changes
db-secret.yaml(new): Opaque Secret containing the fully assembledpostgresql://connection string under thedb-urlkey._helpers.tpl: Helper to construct the connection string from postgres values, selecting the correct host for internal vs external mode.statefulset.yaml: Whenpostgres.enabled, injectOPENSHELL_DB_URLfrom the Secret viasecretKeyRefand omit the--db-urlCLI flag. When disabled, pass--db-urlwith the SQLite path as before.gateway-config.yaml: Conditionally omit thedb_urlfield from the TOML config when PostgreSQL is enabled (the env var takes precedence).Chart.yaml: Add Bitnami PostgreSQL as an optional dependency withcondition: postgres.enabled..gitignore: Ignoredeploy/helm/openshell/charts/(subchart tarballs regenerated byhelm dependency build).tasks/helm.toml: Addhelm dependency buildbefore lint and unittest tasks so the subchart is present.
Credential management
Credentials must never appear as plaintext in rendered manifests. The chart should:
- Create an Opaque Secret with the full
postgresql://connection string. - Mount it into the gateway pod via
secretKeyRefon theOPENSHELL_DB_URLenv var. - Roll the StatefulSet on Secret content changes via a
checksum/db-secretpod annotation.
Alternatives Considered
- Direct
--db-urlflag with PostgreSQL URL: Simpler but exposes credentials in pod spec andkubectl describe. - External secret management only (e.g., External Secrets Operator): Too opinionated; the chart should provide a baseline Secret and allow operators to override with their own.
- ConfigMap for connection string: ConfigMaps are not suited for credential storage.
Agent Investigation
Explored the current Helm chart structure:
statefulset.yamlpasses--db-urlas a CLI arg with the SQLite default.gateway-config.yamlrenders a TOML config mounted at/etc/openshell/gateway.toml.- The gateway binary accepts
OPENSHELL_DB_URLas an env var override for the database connection string. - Existing patterns for Secret-based injection (TLS certs, JWT keys) can be followed for the database credential Secret.
Definition of Done
-
postgres.enabled=false(default) preserves existing SQLite behavior with no changes -
postgres.mode=internaldeploys Bitnami PostgreSQL subchart with credentials in a Secret -
postgres.mode=externalcreates a Secret from user-provided connection details -
OPENSHELL_DB_URLenv var is injected from the Secret, not from plaintext values -
helm lintpasses for default, internal, and external configurations -
helm unittestcovers all three configuration variants - Chart README documents the new
postgres.*values
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
state:agent-readyApproved for agent implementationApproved for agent implementation
Activity