A Helm chart is a package — a directory of YAML templates, default values, and metadata that describes one deployable unit on Kubernetes. When you run helm install, Helm renders those templates against your supplied values, feeds the rendered manifests to the Kubernetes API, and records the outcome as a release. This lesson walks through every command you need to confidently install, upgrade, roll back, and introspect releases in a production cluster.
Working with Repositories
Before installing a chart you need a source. Helm 3 ships with no default repositories — you add them explicitly.
# Add the Bitnami repo (most commonly used public repo)
helm repo add bitnami https://charts.bitnami.com/bitnami
# Refresh the local index cache (always run this before searching or installing)
helm repo update
# List configured repos
helm repo list
# Search for a chart by keyword
helm search repo redis
# Show all available versions of a specific chart
helm search repo bitnami/redis --versions
At big-tech companies, internal charts live in private OCI registries (Amazon ECR, Google Artifact Registry, Azure ACR, or Harbor). You log in with helm registry login <registry-host> and then reference charts as oci://registry-host/path/chart-name rather than using helm repo add. OCI is the modern standard — learn it early.
helm install — Your First Release
The minimal install syntax is helm install <release-name> <chart>. Helm names every deployed instance a release, so you can install the same chart multiple times under different release names (e.g., redis-cache and redis-session).
# Install Redis, release name = my-redis, into the current namespace
helm install my-redis bitnami/redis
# Install into a specific namespace (create it if missing)
helm install my-redis bitnami/redis \
--namespace data-layer \
--create-namespace
# Install a pinned chart version (always pin in production!)
helm install my-redis bitnami/redis --version 18.6.4
# Dry-run: render manifests and validate against the cluster without applying
helm install my-redis bitnami/redis --dry-run --debug
# View the rendered YAML without contacting the cluster at all
helm template my-redis bitnami/redis
Never install without --version in production. Omitting it installs the latest chart version, which can change out from under you when you re-run the command weeks later. Pin the chart version and track it in Git — that is what GitOps requires.
Overriding Values
Every chart ships with a values.yaml that documents all knobs. You override defaults through three complementary mechanisms, applied in order from lowest to highest precedence:
--set key=value — quick one-liners, great for CI secrets; not for complex structures
--values my-values.yaml (or -f) — the standard production approach; commit this file to Git
# Inspect all available values and their defaults before overriding
helm show values bitnami/redis --version 18.6.4 > redis-defaults.yaml
# Override a single value inline
helm install my-redis bitnami/redis \
--set auth.password=supersecret \
--version 18.6.4
# Override via a values file (recommended for everything beyond one key)
# my-redis-values.yaml
# ------------------------------------------
# architecture: standalone
# auth:
# enabled: true
# existingSecret: redis-secret # reference a pre-created K8s Secret
# master:
# persistence:
# enabled: true
# size: 20Gi
# resources:
# requests:
# cpu: 250m
# memory: 512Mi
# limits:
# cpu: 500m
# memory: 1Gi
# ------------------------------------------
helm install my-redis bitnami/redis \
-f my-redis-values.yaml \
--version 18.6.4 \
--namespace data-layer
Use helm show values (not just reading the chart README) to see every configurable field. Charts expose dozens of options that are not documented anywhere except values.yaml.
Releases — Tracking What You Deployed
Helm stores each release as a secret in the target namespace (the default storage backend in Helm 3). Every install and upgrade increments the revision counter.
# List all releases in the current namespace
helm list
# List across all namespaces
helm list --all-namespaces
# Show detailed status and last-rendered manifest
helm status my-redis
# Show the values actually used for a release (merged result)
helm get values my-redis
# Show the full rendered YAML that was applied to the cluster
helm get manifest my-redis
# Show release history (all revisions)
helm history my-redis
helm upgrade — Changing a Live Release
Upgrading applies a diff — Helm computes the delta between the current release manifests and the newly rendered ones, and sends only the changed objects to the API server.
# Upgrade to a newer chart version with the same values file
helm upgrade my-redis bitnami/redis \
-f my-redis-values.yaml \
--version 18.7.0 \
--namespace data-layer
# Install-or-upgrade in one command (the production standard)
helm upgrade --install my-redis bitnami/redis \
-f my-redis-values.yaml \
--version 18.7.0 \
--namespace data-layer \
--create-namespace
# Add --atomic: rolls back automatically if the upgrade fails
helm upgrade --install my-redis bitnami/redis \
-f my-redis-values.yaml \
--version 18.7.0 \
--namespace data-layer \
--atomic \
--timeout 5m
helm upgrade --install is the idiomatic CI/CD command. It behaves as an install on first run and as an upgrade on subsequent runs, making your pipeline declarative and rerunnable without any branching logic. Pair it with --atomic so a failed rollout triggers an automatic rollback rather than leaving your release in a broken state.
Helm Release Lifecycle Diagram
Helm release lifecycle: charts and values merge into a release record; upgrades add a revision; rollback re-applies a previous revision's manifests.
helm rollback — Recovering from a Bad Upgrade
Helm stores every rendered manifest for every revision. Rolling back replays a previous revision's manifests against the cluster — it does not restore a database or stateful data, only Kubernetes object definitions.
# View revision history first
helm history my-redis --namespace data-layer
# Roll back to the immediately previous revision
helm rollback my-redis --namespace data-layer
# Roll back to a specific revision number
helm rollback my-redis 3 --namespace data-layer
# Verify the rollback succeeded
helm status my-redis --namespace data-layer
helm history my-redis --namespace data-layer
# NOTE: rollback creates a NEW revision (e.g., rev 4 = replica of rev 3)
Rollback only resets Kubernetes manifests. If your upgrade ran a database migration, rolling back the Helm release will not reverse those schema changes. Coordinate with your application team and use a blue/green or canary deployment strategy for stateful services, so the database schema remains backward-compatible throughout the rollout.
Uninstalling a Release
Removing a release deletes all rendered Kubernetes objects and the release record by default.
# Uninstall a release (removes K8s objects + release history)
helm uninstall my-redis --namespace data-layer
# Keep the release history in the store (useful for audit trails)
helm uninstall my-redis --namespace data-layer --keep-history
Production Patterns at a Glance
Always pin chart versions in your values file or CI pipeline — treat chart versions like software dependency versions.
Store your -f values.yaml files in Git alongside your application code. One values file per environment (values-staging.yaml, values-prod.yaml).
Use --atomic in CI so a failed deployment rolls back automatically and never leaves a half-applied release.
Never use --set for secrets. Pass secrets via existing Kubernetes Secrets (created out-of-band by Vault, External Secrets Operator, or Sealed Secrets) and reference them in your values file.
Run helm diff upgrade (requires the helm-diff plugin) in your CI pipeline to surface what will change before you apply — the Kubernetes equivalent of terraform plan.