Two modes — Bundled Evaluation vs Production install
The same Helm chart supports two installation shapes. They share the application Deployment, Service, Route, and migration Job; they differ in who owns PostgreSQL and Redis and who owns the secrets that connect them.
This document explains the choice, the trade-offs, and what each mode looks like in practice.
Why two modes
Enterprise customers split into two camps when it comes to running stateful services like PostgreSQL and Redis:
- Some want the chart to handle everything. They're evaluating
the software, running a pilot, doing internal training, or
operating at a scale where dedicated database operators are
overkill. They want one
helm installand a working stack. - Others want to use what they already operate. They have a Crunchy / CloudNativePG cluster, a Redis Enterprise install, an external managed database, or strict policy that says "all databases go through the platform team's blessed operator." They want the chart to be a thin layer that consumes their existing infrastructure.
A single chart serving both camps via Helm conditional dependencies is cleaner than two separate charts: one set of templates, one release lifecycle, one upgrade path. Customers who start in Bundled mode and graduate to Production can do so without learning a new chart.
Mode A — Bundled Evaluation install
Audience
- Pilots, demos, lab environments, training installs.
- Internal proof-of-concept where the customer wants to see the software running without committing infrastructure.
- Single-team deployments where the cost of standing up dedicated postgres / redis would exceed the value being evaluated.
- Air-gapped environments where the customer has not yet stood up shared services and just needs the application working in isolation.
What the chart deploys
- Application Deployment (Rails app, single replica).
- Service + OpenShift Route for ingress.
- PostgreSQL StatefulSet via Bitnami's
postgresqlsubchart. - Redis Deployment via Bitnami's
redissubchart. - PVCs for application storage, postgres data, redis persistence — all on the cluster's default StorageClass.
- Migration Job (Helm
pre-install/pre-upgradehook). - Optional NetworkPolicy for egress lockdown.
What the customer provides
- An OpenShift project / namespace.
- Image-pull access (either GHCR public, or a mirrored image in the customer's internal registry).
- A Route hostname (DNS that resolves to the cluster ingress).
- A license file.
- Whatever the cluster's default StorageClass already gives them.
Mode A values.yaml example
# Minimum-viable Bundled Evaluation install.
image:
repository: ghcr.io/<vendor>/<app>
tag: "1.0.0"
route:
host: app.evaluate.example.com
# Bundled subcharts on
postgresql:
enabled: true
auth:
database: app_production
# Password generated by chart and persisted in a Secret
redis:
enabled: true
# Chart creates the secret from generated values
secrets:
generate: true
# Customer-provided license, pre-created
licensing:
fileSecretName: app-license
# Default storage class, 10 GiB
persistence:
size: 10Gi
Pros
- One
helm installproduces a working stack. - No coordination with other platform teams.
- Easy to tear down (
helm uninstall) and re-install fresh. - Same chart, same upgrade path as Production — practice now, scale later.
Cons (and when not to use)
- Single-replica postgres. No HA. Pod restart = ~30s database unavailability. Acceptable for eval, not for production.
- No automated backups. Customer is responsible for backup of postgres / redis / application-storage PVCs.
- Single-replica application.
ReadWriteOncestorage prevents scaling beyond one application replica. - Bundled postgres tuning is generic. Bitnami defaults work but aren't tuned to the customer's workload.
- Secret rotation is manual. Chart-generated secrets persist; rotating them means uninstall + reinstall (or careful manual Secret edits + pod rolls).
If any of those constraints don't fit, you want Mode B.
Mode B — Production install
Audience
- Production deployments serving real users with real uptime expectations.
- Customers with a platform team that mandates a specific postgres operator (Crunchy, CloudNativePG, EDB), redis solution (Redis Enterprise, Redis Operator), or managed external database.
- Multi-replica HA application deployments.
- Compliance regimes (FedRAMP, IL5, etc.) where stateful services must be running under a specific operator with documented configuration management.
What the chart deploys
- Application Deployment (replicas configurable, default 2).
- Service + OpenShift Route for ingress.
- Migration Job.
- Optional NetworkPolicy.
- Optional PVC for application storage (or skip in favor of S3-compatible object storage).
What the customer provides
- An OpenShift project / namespace.
- Image-pull access.
- A running PostgreSQL 15+ instance the chart can reach via a Service / DNS name in the same cluster, or external endpoint.
- A running Redis 7+ instance likewise reachable.
- Pre-created secrets for database credentials, the Rails master key, the application's session signing key, and any image pull credentials.
- Storage class choice (RWO for single-replica with PVC; RWX or S3 for multi-replica).
- Backup procedures for postgres, redis, and application storage.
- Route TLS posture (cluster wildcard cert vs customer cert vs passthrough).
Mode B values.yaml example
# Production install. Customer operates postgres + redis externally.
image:
repository: registry.internal.example.com/<vendor>/<app>
tag: "1.0.0"
pullSecrets:
- name: registry-credentials
replicaCount: 2
route:
host: app.example.com
tls:
termination: reencrypt
certSecretName: app-tls-cert
# Bundled subcharts off — bring your own
postgresql:
enabled: false
redis:
enabled: false
# Customer-provided endpoints
externalDatabase:
host: postgres-cluster-primary.databases.svc.cluster.local
port: 5432
database: app_production
username: app # role name (not sensitive)
existingSecret: app-db-credentials # holds key `password`
sslmode: verify-full
sslRootCertSecret: postgres-ca-cert # optional
externalRedis:
host: redis-master.cache.svc.cluster.local
port: 6379
existingSecret: app-redis-credentials # holds key `password` (or empty)
tls: true
# Customer-provided secrets — chart references, never generates
secrets:
existingSecret: app-rails-secrets # RAILS_MASTER_KEY + SECRET_KEY_BASE
licensing:
fileSecretName: app-license
# RWX storage for HA replicas
persistence:
storageClass: ocs-storagecluster-cephfs
accessMode: ReadWriteMany
size: 50Gi
# Or skip PVC entirely and use object storage:
# persistence:
# enabled: false
# objectStorage:
# provider: s3
# bucket: app-uploads
# existingSecret: app-s3-credentials
Pros
- Database and cache run under whatever operator the customer already trusts and monitors.
- HA application replicas are safe — sessions in Redis, files in RWX PVC or S3, no single-pod state.
- Secret rotation goes through the customer's standard secret- management workflow; chart does not own credentials.
- Backups are the customer's existing backups for those services.
- Compliance auditors see one set of postgres / redis configurations across the customer's whole estate.
Cons (and when not to use)
- More moving parts to set up. The customer must have postgres and redis running and reachable before the chart will install.
- Tighter coordination required. Application's database needs to exist with the right name; the chart's migration Job will fail loudly if it can't authenticate.
- No "demo mode." First-install-with-blank-environment isn't a one-liner; pre-requisites take real time.
For evaluation or pilot work, the friction overhead of Production mode rarely justifies the extra durability — start with Bundled and migrate when committing to production.
Decision matrix
| If you want… | Use… |
|---|---|
| To see the software running in 30 minutes | Bundled |
| To run a 4-week pilot with internal users | Bundled |
| To deploy production for a paying customer | Production |
| Multi-replica HA on the application tier | Production |
| To use Crunchy / CloudNativePG / Redis Enterprise | Production |
| To stand up an air-gapped lab and "just see it work" | Bundled |
| FedRAMP / IL5 / DoD authorization with mandated stateful operators | Production |
| Backups managed by the customer's platform team's existing tooling | Production |
When in doubt, start with Bundled and graduate; the same chart supports both, and the data migration path between them is documented below.
Migrating from Bundled to Production
Customers who outgrow Bundled mode can migrate to Production mode without redeploying the application image. The data migration is the substantive part:
- Stand up the production-mode postgres (Crunchy / CloudNativePG / etc.) in its own namespace or cluster.
- Take a
pg_dumpof the bundled postgres pod, restore into the production-mode database. - Snapshot the application-storage PVC, restore into the new storage class (RWX or S3).
- Same for redis if persistence matters (usually it doesn't — redis in this app holds cache and sessions; an empty redis on the production side just causes one re-login).
helm upgradewith the Production-mode values file. Chart tears down the bundled postgres / redis subcharts; application reconnects to the external endpoints.- Verify, then delete the now-orphan PVCs from the bundled side.
This is a one-way migration; rolling back to Bundled would be the same procedure in reverse and is not a supported workflow.
Common questions
Can I use Bundled postgres in production if my app is small? Technically yes; we don't recommend it. You give up automated backups, replication, and the operational maturity that a postgres operator provides. If you have a pilot that turned into production, plan a migration.
Can I use bundled postgres but external redis (or vice-versa)? Yes. The two subchart toggles are independent — you can enable one and disable the other.
What about S3 for Active Storage instead of a PVC?
Supported in both modes. Skip the PVC, point the chart at an
S3-compatible bucket via objectStorage.* values. Recommended for
multi-replica deployments and customers who already have a tested
object-storage backup story.
What happens if I switch a subchart from enabled: true to
enabled: false mid-stream without migrating data?
The chart deletes the subchart's StatefulSet on helm upgrade; the
PVC remains by default (Bitnami subchart's persistence.enabled
controls this). Application can no longer reach its database. Do
not do this unless you have already migrated the data and pointed
externalDatabase.* at the new endpoint.