Why?
Rationale
- Best practises (fits 80/20 of use cases)
- Convention over configuration (sane defaults)
- Configuration over code (don't repeat yourself)
Features
Workloads
- Multiple named Deployments, Services, Ingresses, CronJobs, Jobs and PVCs — all in one chart
- Single-resource shorthands (
deployment:,service:,ingress:) for simple single-app deployments - Bare keys for Deployments, CronJobs and Jobs produce a working resource with no configuration needed
- HPA (autoscaling/v2) with shorthand CPU/memory metrics or full metrics list
- Ingress TLS smart defaults —
tls: trueauto-derives hosts andsecretNamefrom the ingress; list and dict modes fill in any omitted fields
Configuration management
variablesstored in a ConfigMap,secretsin a Secret,sealedSecretsin a SealedSecret — all auto-mounted as environment variablesconfigure.*flags per container: opt-in or opt-out of any auto-behaviour (variables, secrets, files, persistence) at the global, pod, or container level- Both list-style and dict-style
env,envFrom, andports— dict keys become thenamefield automatically - Automatic pod rollouts on ConfigMap/Secret changes via checksum annotations
Files and persistence
- Mountable config files (
mountedFiles), secret files (mountedSecretFiles), and sealed secret files (mountedSealedSecretFiles) - PVCs with optional auto-mount; reuse existing claims via
claimName - Bitnami Sealed Secrets as first-class citizens — env vars and file mounts
Containers
- Init containers and sidecar containers with opt-in
configureflags (no accidental secret leakage to utility containers) - Per-container
securityContext,resources,healthChecks,command,args,imagePullPolicy - Health checks at
/healthz/readyand/healthz/liveby convention
What makes this chart different
Most generic Helm charts dump all global configuration onto every container. This chart takes a different approach:
Native Kubernetes YAML as values — no chart-specific schema to learn
Fields like healthChecks, securityContext, affinity, volumes, resources, and ports accept standard Kubernetes YAML directly. You write exactly what goes into the manifest. This means every Kubernetes feature works immediately — no waiting for a chart update to expose a new probe type, security flag, or scheduling option. Charts that define their own abstraction schema for every field (200+ parameters) are harder to learn, inevitably lag behind the Kubernetes API, and break when you need something they haven't modelled. This chart doesn't have that problem.
configure.* flags are explicit, not implicit
Variables, secrets, files, and persistence are only mounted where you opt in. Init containers and sidecar containers default to no auto-configuration — a log shipper sidecar will never accidentally receive database credentials.
Multiple workloads, one chart
deployments:, services:, ingresses: are maps — define a frontend, an API, and a worker in a single values.yaml with shared config (image, secrets, variables) and per-resource overrides.
Sealed Secrets as a first-class feature
Most charts treat secrets as an afterthought. This chart supports Bitnami Sealed Secrets natively for both environment variables and mounted files, making GitOps-safe secret management straightforward.
extraManifests as a universal escape hatch
Any Kubernetes resource the chart doesn't natively generate — NetworkPolicies, ExternalSecrets, OpenShift Routes, cert-manager Certificates, CRDs — can be declared inline in extraManifests. Dict mode auto-injects name, namespace, and labels; list mode gives full control. No forking required.
Dict and list style are interchangeable — everywhere
Standard Kubernetes YAML uses lists for env vars, ports, and volumes, which is verbose and repetitive for simple cases. This chart accepts both styles for every list field, and promotes dict keys to name fields automatically:
# Kubernetes list style — always works, familiar to anyone who knows K8s
env:
- name: DATABASE_HOST
value: postgres
- name: DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
# Dict style — concise for simple values, full objects still supported
env:
DATABASE_HOST: postgres
DATABASE_PASSWORD:
valueFrom:
secretKeyRef:
name: db-secret
key: passwordThe same applies to ports, envFrom, volumeMounts, and extraManifests. You can mix styles freely. This makes values files dramatically shorter without learning a new abstraction.
Build application charts on top — a composable alternative to Kustomize
Every chart in this repository (archivebox, bookstack, akeneo, and others) is an application-specific chart that lists standard as a dependency and sets opinionated defaults under the standard: key. The application chart ships with sensible defaults for its use case; operators override only what they need in their own values file. No forking, no patching, no YAML overlay files.
This is the same problem Kustomize solves — apply environment-specific overrides to a shared base — but with Helm's full templating, type-safe values, and the Helm release lifecycle (diff, rollback, hooks). The chart is the base; your values.yaml is the overlay.
# charts/myapp/values.yaml — opinionated defaults shipped with the chart
standard:
image:
repository: myorg/myapp
variables:
APP_ENV: production
services:
myapp:
ports:
http:
port: 80
deployments:
myapp:
configure:
persistence: true# deploy/staging/values.yaml — operator overrides only what differs
standard:
variables:
APP_ENV: staging
image:
tag: "abc123"Bare keys just work
A deployment, cron job or job entry with no value produces a complete working resource using global defaults. No required fields, no empty {} blocks.
Helm criticisms
Helm is sometimes criticised for adding complexity without proportional benefit. Some of those criticisms apply to poorly-written charts, not to Helm itself. Here is how this chart addresses each one:
"Go templating in YAML is too complex."
As a chart user you never write Go templates. You write plain YAML values files. The templating is inside the chart, handled once, and tested. You get the power of templating without touching it.
"Minor value changes can unexpectedly enable hidden chart features."
This chart uses explicit opt-in via configure.* flags. Nothing is automatically enabled unless you turn it on. Changing a value does exactly what you expect — no hidden interactions.
"It's hard to see what the final YAML will look like before deploying."
Set debug: true to render the chart with internal state visible as comments. Use helm template to preview the full output locally before any cluster interaction. The base-chart + values overlay pattern also makes changes predictable: the application chart defaults are stable; your values file is the only moving part.
"Chart quality varies — you end up forking or patching."
The base-chart dependency pattern means you never fork. Your application chart inherits from standard, sets its own defaults, and operators override only what they need. Updates to standard flow through automatically. The extraManifests escape hatch covers any resource the chart doesn't natively support — no forking needed for one-off additions.
"Helm is overkill for simple apps."
A working deployment, service, and ingress requires three lines:
deployment:
service:
ingress:
hosts: [myapp.example.com]The shorthand pattern and bare-key convention make this chart as simple as a docker-compose.yaml for straightforward cases while scaling to complex multi-workload setups.