Helm Values & Overrides
Values are the chart's configuration API. Use environment-specific files in Git, render before applying, diff against the live release, and roll back via helm history when something breaks.
Values Precedence
Later sources override earlier ones. When debugging "why did my value not apply?", walk this list bottom-up.
- Chart
values.yamldefaults. - Parent chart values passed to subcharts.
- User-supplied files from
-f, in the order given. --set,--set-string, and--set-file(highest priority).
Environment Overlays
| File | Purpose |
|---|---|
values.yaml | Safe defaults committed in the chart |
values-dev.yaml | Lower replicas, debug logging, internal URLs |
values-staging.yaml | Prod-like sizing, staging ingress host |
values-prod.yaml | Production replicas, resources, ingress, PDBs |
# Later files override earlier ones.
helm upgrade --install web-api ./chart -n app \
-f values.yaml \
-f values-prod.yaml \
--set image.tag="${GIT_SHA}"
Production Values Shape
This values file shows the kind of knobs you normally expose for production: replicas, image, service, resources, ingress, globals, and app env. Use it as a starting shape, then remove options the client does not support.
replicaCount: 4
image:
repository: registry.example.com/platform/web-api
tag: "abc123f" # Immutable commit SHA or digest — never "latest" in prod.
service:
type: ClusterIP
port: 80
targetPort: 8080
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: "1"
memory: 512Mi
ingress:
enabled: true
className: nginx
host: api.example.com
# Passed to subcharts via global key.
global:
environment: prod
storageClass: gp3
env:
LOG_LEVEL: info
--set Overrides
Use --set for small temporary overrides and CI-injected values such as image tags. Prefer values files for stable environment config, and use --set-string when a numeric-looking value must remain a string.
# --set coerces types; use --set-string for IDs and version strings.
helm upgrade web-api ./chart -n app \
--set replicaCount=6 \
--set-string image.tag="1.2.3" \
--set ingress.enabled=true
# Inject a secret file without committing it to Git.
helm upgrade web-api ./chart -n app \
--set-file config.json=./secrets/config.json
# Override a subchart value (postgresql is the subchart name).
helm upgrade web-api ./chart -n app \
--set postgresql.auth.password="${DB_PASSWORD}"
Safe Upgrade Workflow
This is the safer operator flow for changing a Helm release: update dependencies, lint, render, diff, upgrade with wait/atomic, then verify history. Use it for client environments where rollback must be quick and auditable.
helm dependency update ./chart
helm lint ./chart
helm template web-api ./chart -n app -f values-prod.yaml > /tmp/rendered.yaml
# Install helm-diff plugin: helm plugin install https://github.com/databus23/helm-diff
helm diff upgrade web-api ./chart -n app -f values-prod.yaml
helm upgrade --install web-api ./chart -n app \
-f values-prod.yaml \
--atomic \
--wait \
--timeout 10m
helm history web-api -n app
helm rollback web-api <revision> -n app --wait --timeout 10m
Debugging Releases
Use these commands when you need to understand what Helm believes it installed and how that compares to live Kubernetes objects. They are especially useful after a failed upgrade or unexpected drift.
helm list -A
helm status web-api -n app
helm get values web-api -n app --all # Effective values including --set overrides.
helm get manifest web-api -n app # Last applied Kubernetes YAML.
helm get notes web-api -n app # Post-install NOTES.txt output.
# Compare live cluster vs what Helm thinks it deployed.
kubectl get deploy,svc,ingress -n app -l app.kubernetes.io/instance=web-api
kubectl get events -n app --sort-by=.lastTimestamp | tail -n 50
Uninstall
Use uninstall only when the release truly should be removed. Check PVCs, cloud resources, hooks, and finalizers first, because uninstalling a chart can delete Kubernetes objects while leaving external dependencies behind.
helm uninstall web-api -n app
helm uninstall web-api -n app --keep-history # Keep release history for audit.
helm list -A --pending # Find stuck pending-uninstall releases.
Quick Fixes
| Symptom | Check |
|---|---|
| Value not applied | helm get values <release> --all — confirm precedence |
| Upgrade changed nothing | Chart version unchanged; verify image.tag in rendered output |
| Subchart config ignored | Use subchart name prefix: postgresql.auth.password |
| Manual kubectl edit reverted | Expected — next Helm upgrade restores chart state |
Gotchas
- --set typing: use
--set-stringfor account IDs, versions, and numeric strings Helm would coerce to numbers. - --atomic is not magic: it rolls back Kubernetes resources, not external side effects like DB migrations.
- Drift: manual
kubectl editchanges are overwritten on the next upgrade unless the client uses a drift-tolerant GitOps policy. - Null vs empty: setting a value to
nullin YAML removes the key; an empty string may still render in templates.