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) and README.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