Helm
.mdVerified against Helm v3.18.6, flags verified via `helm <cmd> --help` run locally, 2026-08-21 · official docs
Repos, install/upgrade/rollback, and the commands for previewing what a change would actually do before it hits a cluster.
Managing chart repositories#
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update # refresh the local index of all added repos
helm repo list
helm search repo postgresql # search across all added reposInstalling a release#
helm install my-release bitnami/postgresql --namespace my-app --create-namespace
helm install my-release ./my-chart -f values-prod.yaml
helm install my-release ./my-chart --set image.tag=v2.1.0,replicaCount=3
helm install my-release ./my-chart --version 1.4.2 # pin a specific chart version-f values.yaml and --set key=value can both be used together — --set values win when the same key is set both ways, which makes it the standard way to override one or two values from a CI pipeline without maintaining a separate values file per environment.
Upgrading a release#
helm upgrade my-release ./my-chart -f values-prod.yaml
helm upgrade --install my-release ./my-chart -f values-prod.yaml # upgrade if it exists, install if it doesn't
helm upgrade my-release ./my-chart --atomic # auto-rollback the whole upgrade on failure--install on upgrade (or the equivalent upgrade -i) is the standard pattern for idempotent CI/CD deploy scripts — one command works whether this is the first deploy or the hundredth, no separate install-vs-upgrade branching logic needed.
Previewing changes before applying#
helm install my-release ./my-chart --dry-run --debug # render manifests locally, no cluster call
helm template my-release ./my-chart -f values-prod.yaml # render manifests to stdout, no release created at all
helm diff upgrade my-release ./my-chart -f values-prod.yaml # requires the helm-diff plugin — shows an actual diffhelm diff is a plugin, not built into core Helm — install it with helm plugin install https://github.com/databus23/helm-diff. It's the closest thing Helm has to terraform plan: an actual before/after diff against the live cluster state, versus template/--dry-run which only show the rendered output in isolation.
Rolling back#
helm history my-release # list all revisions of a release
helm rollback my-release # roll back to the previous revision
helm rollback my-release 3 # roll back to a specific revision numberListing and removing releases#
helm list --namespace my-app
helm list --all-namespaces
helm status my-release
helm uninstall my-release --namespace my-appChart development helpers#
helm lint ./my-chart # catch template/schema issues before installing
helm create my-new-chart # scaffold a new chart from the standard starter template
helm package ./my-chart # produce a .tgz for distributionDebugging rendered templates#
helm template my-release ./my-chart -s templates/deployment.yaml # render just one template
helm template my-release ./my-chart --debug # show the computed values alongside the output
helm template my-release ./my-chart --validate # validate rendered manifests against the live cluster's API
helm template my-release ./my-chart --set replicaCount=3 --set-string image.tag=1.2.3-s/--show-only (repeatable) is the fastest way to check one resource in a chart with dozens of templates without scrolling past everything else. --validate actually contacts the cluster to check the rendered manifests against its API — plain template never does, which is why it can render manifests referencing a CRD that doesn't exist in that cluster without complaint.
Managing chart dependencies#
cat my-chart/Chart.yaml # dependencies are declared here: name, version, repository
helm dependency list ./my-chart # show declared deps vs what's actually in charts/
helm dependency update ./my-chart # pull deps declared in Chart.yaml into charts/, writes Chart.lock
helm dependency build ./my-chart # rebuild charts/ from the existing Chart.lock (no re-resolution)update re-resolves version ranges against the repo index and can pick up a newer chart than last time; build reproduces exactly what's pinned in Chart.lock. Use build in CI for reproducible installs, update when you deliberately want to bump a dependency.
Testing a release#
helm test my-release # run the test hooks defined in the chart (helm.sh/hook: test)
helm test my-release --logs # also dump logs from the test pods after they complete
helm test my-release --filter name=connection-test # run only a specific named testTest hooks are just Pods annotated "helm.sh/hook": test in the chart's templates — helm test finds and runs them against a release that's already installed, then reports pass/fail per pod. It's a post-install smoke test, not a substitute for helm lint/--dry-run at deploy time.
Linting a chart#
helm lint ./my-chart --strict # treat warnings as failures (use in CI)
helm lint ./my-chart --with-subcharts # also lint every dependency chart under charts/
helm lint ./my-chart -f values-prod.yaml # lint against a specific values file instead of the defaultsPlain helm lint only emits [WARNING] for style/convention issues and exits 0 — --strict is what actually fails a CI pipeline on those warnings, so add it once a chart's conventions are settled.
Searching and removing repositories#
helm search repo postgresql --versions # every version of postgresql across added repos
helm search hub ingress # search Artifact Hub itself, not just your added repos
helm repo remove bitnami # drop a repo you added earliersearch repo only searches repos you've already helm repo added locally; search hub queries Artifact Hub (artifacthub.io) directly, which is useful for discovering a chart before you know which repo it lives in.