Helm Best Practices
A field guide to shipping Helm charts and Kustomize overlays that stay reviewable, reproducible, and safe to upgrade.
Search across all documentation pages
A field guide to shipping Helm charts and Kustomize overlays that stay reviewable, reproducible, and safe to upgrade.
Treat each item as a check you can enforce in CI or in code review.
Groups A through E move from packaging discipline through security and delivery; adopt them in order if you are starting fresh.
None of these require exotic tooling - helm, kustomize, and kubectl cover all of them.
version in Chart.yaml dependencies and commit Chart.lock so builds are reproducible.version on every chart change. GitOps controllers key on chart version to detect drift; a missed bump hides changes.appVersion in sync with the image. Use .Chart.AppVersion as the default image tag so the packaged app and chart agree.latest, or your cluster and CI will diverge.values.schema.json. Validate user-supplied values at install and upgrade so bad input fails fast with a clear message.values.yaml.values.yaml so consumers know what is tunable and its default.--set chains. Files are reviewable and version-controlled; inline --set flags are easy to lose.global values for cross-cutting settings. Share registry, image pull secrets, and labels across parent and subcharts via .Values.global.helm template and kustomize build on every PR and diff the result so surprises surface before merge._helpers.tpl and include them so every object carries the recommended app.kubernetes.io/* labels.{{-/-}} and pipe include output through nindent to avoid malformed YAML.configMapGenerator/secretGenerator name-suffix hashes enabled so config changes restart pods.runAsNonRoot: true, drop capabilities, and use seccompProfile: RuntimeDefault in templates.helm upgrade --install in CI so the same command installs or upgrades safely.--atomic and --wait. Auto-rollback on failure and block until resources report ready.helm.sh/hook plus hook-delete-policy so migration Jobs run at the right phase and do not accumulate.helm lint in CI and only then helm package and push to your OCI registry.helm install against the same release.You should be able to render any environment offline, review a PR and see exactly what changes, and upgrade with automatic rollback on failure.
If a change to a ConfigMap does not roll pods, or a chart edit ships without a version bump, revisit groups A and C.
Why test helm template in CI? It catches malformed YAML and unexpected rendered changes before they reach the cluster, without touching a live API server.
Pin by tag or digest? Tag for charts (semver version), digest for the underlying container images in production.
Where do environment values belong? In per-environment values or overlay files, never in the chart's default values.yaml.
How do I stop stale ConfigMaps? Keep Kustomize generator hash suffixes enabled, or roll the Deployment via a checksum annotation in Helm.
Should I use hooks for database migrations? Yes, a pre-upgrade hook Job with a hook-delete-policy is the standard pattern.
How do I make upgrades safe? Combine --install, --atomic, and --wait so failed upgrades roll back automatically.
Stack versions: This page was written for Kubernetes 1.36.2, Docker Engine 29.6.1 (BuildKit default), containerd (CRI runtime on nodes), Helm 3, Compose v2, Argo CD (latest - verify at build), and Gateway API (GA - verify controller support at build).
Reviewed by Chris St. John·Last updated Jul 16, 2026