Helm is often described as “the package manager for Kubernetes.” But if you’ve used tools like apt
, yum
, or brew
, that analogy doesn’t quite tell the full story.
Yes, Helm helps you install apps in your cluster—but more importantly, it helps you manage the complexity of deploying Kubernetes resources in a consistent, reusable, and configurable way.
Why Helm Exists (and Why You’ll Care Eventually)
You can absolutely write raw YAML and kubectl apply -f
your way through life. And for small, static apps, that might be enough.
But once your workloads grow, or you have to:
- Deploy the same app across multiple environments (dev, staging, prod)
- Pass in different values (DB endpoints, feature flags, resource limits)
- Handle versioning and rollbacks
- Share templates across teams
- Install common off-the-shelf software (Prometheus, NGINX, ArgoCD, etc.)
…you’ll quickly realize that managing raw manifests manually is painful and error-prone.
Helm solves this by turning your Kubernetes resources into a parameterized, versioned package—complete with defaults, overrides, dependency management, and upgrade logic.
The Core Concepts (Without the Buzzwords)
Helm introduces a few key ideas you’ll need to know:
1. Chart
A Chart is a package of Kubernetes manifests, parameterized with templates. It usually includes:
templates/
– folder with your YAML templates (e.g., Deployment, Service)Chart.yaml
– metadata about the chart (name, version, etc.)values.yaml
– default configuration values- Optional:
charts/
(for dependencies) andREADME.md
You can think of it as a folder that describes how to deploy something, and it’s easy to version, lint, and share.
2. Values
Helm templates use Go templating syntax to insert dynamic content—powered by a values.yaml
file.
Example values file:
replicaCount: 3
image:
repository: nginx
tag: stable
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
Inside your templates, you reference these values like this:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-nginx
spec:
replicas: {{ .Values.replicaCount }}
template:
spec:
containers:
- name: nginx
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
You can override any of these values at install time:
helm install my-nginx ./nginx-chart --values custom-values.yaml
Or set a quick value inline:
helm install my-nginx ./nginx-chart --set replicaCount=5
3. Release
A Release is an instance of a chart deployed to a Kubernetes cluster. You can install the same chart multiple times with different configurations.
Example:
helm install staging ./myapp-chart --namespace staging
helm install prod ./myapp-chart --namespace production
Each of those is a different release—even if they came from the same chart.
Installing Helm and Using It
First, install Helm. Then add a chart repo—like the official one from Bitnami or Prometheus:
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
Now install something:
helm install my-redis bitnami/redis
Boom—you’ve just deployed Redis to your cluster with sane defaults, persistent storage, and metrics enabled.
Want to customize it?
helm show values bitnami/redis > redis-values.yaml
Then tweak the config and install:
helm install my-redis bitnami/redis -f redis-values.yaml
Upgrades, Rollbacks, and History
Helm tracks the state of each release. You can upgrade it when something changes:
helm upgrade my-redis bitnami/redis -f redis-values.yaml
Or rollback if something breaks:
helm rollback my-redis 1
You can see the release history:
helm history my-redis
This is where Helm really shines: upgrades and rollbacks feel like first-class operations, not a pile of kubectl apply
diffs you hope won’t break anything.
How It Fits Into GitOps and CI/CD
Helm is a great building block for GitOps pipelines. You can store your Helm charts in Git, render them with tools like helm template
, or use them directly with ArgoCD, Flux, or Jenkins.
In GitOps, you often don’t run helm install
manually. Instead, you define your values in Git, and let your automation system deploy them.
That said, Helm works just as well for day-to-day ops:
- Quickly spinning up dev environments
- Testing app config changes
- Deploying standard services like metrics, logging, or cert managers
When Not to Use Helm
Helm is powerful, but it’s not perfect. Here are a few caveats:
- The templating language (Go templates) can be clunky, especially for conditionals or nested logic
- Chart sprawl: you can end up with 30 different charts for small variations of the same app
- Debugging template rendering issues is a pain at first
- Charts from the ecosystem may have too many knobs or too much abstraction
If you’re doing very simple deployments or prefer full control over rendered manifests, tools like Kustomize or even plain YAML + kubectl
might be enough.
Summary
If you’re managing more than one environment, deploying anything third-party, or want to avoid repeating the same YAML 10 different ways—learn Helm.
It’s not a silver bullet, but it’s the most battle-tested tool we have right now for packaging, parameterizing, and managing Kubernetes apps.
Once you get past the initial learning curve, Helm makes life a whole lot easier—and far more consistent.
See Also
- Official Documentation
- Kustomize – alternative for managing overlays in raw YAML
- Github – manage many Helm releases declaratively