[EN] Helm für Einsteiger: Schluss mit der Kubernetes-YAML-Hölle

Julian | Dec 14, 2025 min read

Kubernetes has completely changed the way we deploy software. It’s powerful, scalable and… honestly often quite overwhelming. Maybe you know the feeling: you understand the basics of pods and services, but suddenly you’re drowning in a flood of manifest files. What was manageable in a small project quickly becomes chaos within the team.

In this article I’ll show you the tool that no modern tech stack should be without: Helm. We’ll look at why it’s the de facto standard for Kubernetes deployments and how it helps you keep your infrastructure as clean as your code.

Let’s tame the chaos.

The problem with “Raw” Kubernetes

Hand on heart: your first steps with Kubernetes probably looked like mine. You followed a tutorial, wrote a deployment.yaml, maybe a service.yaml, and booted everything up with kubectl apply -f .. Magical, right?

But then everyday life came. You need an environment for Dev, one for Staging and one for Production. Suddenly you have:

  • deployment-dev.yaml (Replicas: 1)
  • deployment-staging.yaml (Replicas: 2)
  • deployment-prod.yaml (Replicas: 5, andere CPU-Limits, andere Env-Vars)

Now if you want to change one thing (e.g. the image tag), you have to touch three files. The risk of you making a typo or forgetting a file in Production feels like 100%. You are violating the DRY principle (Don’t Repeat Yourself), which is sacred to us when it comes to coding but is often ignored when it comes to infrastructure.

Welcome to “YAML hell”. And here’s the way out: Helmet.

What exactly is a helmet?

Very simple: If Kubernetes is the operating system, then Helm is the package manager. Think npm for Node.js, pip for Python or apt for Ubuntu.

Helm basically does two things:

  1. It bundles complex Kubernetes applications into a reusable package (called Chart).
  2. It allows you to configure these packages without having to rewrite the actual files.

Instead of manually managing dozens of YAML files, you install a package with one command. But the real power for us developers lies under the hood: in the templates.

The Magic: Templates & Values

(Your new best friend) This is where the real shift in mindset happens. In “Raw” Kubernetes, values ​​are hard-coded. In Helm, values ​​are variables.

Imagine you have your deployment.

Without helmet (static & inflexible):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 1  # <--- Hartkodiert. Schlecht für Prod.
  template:
    spec:
      containers:
        - name: my-app
          image: my-company/app:v1.0.0 # <--- Hartkodiert. Muss bei jedem Release geändert werden.

With Helmet (Dynamic & Reusable): In Helm the file looks like this (often templates/deployment.yaml):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-app
spec:
  replicas: {{ .Values.replicaCount }}  # <--- Variable!
  template:
    spec:
      containers:
        - name: my-app
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" # <--- Variable!

Do you see the {{ ... }} syntax? This is Go templating. Helm now looks into a separate file called values.yaml to fill these placeholders.

Your values.yaml is the only thing you still touch:

# values.yaml
replicaCount: 1
image:
  repository: my-company/app
  tag: v1.0.0

Why is this awesome? You now have one template for all environments.

  • For Dev use the standard values.yaml.
  • For Prod, just overwrite the replicaCount to 5 when installing. The template remains untouched. No more copy-paste errors.

Anatomy, terms and the command line

The vocabulary

Only 3 termsTo understand Helm, you don’t have to memorize a dictionary. There are only three concepts that matter:

  1. Chart: The package. Think of a .deb file on Linux or a .msi on Windows. A chart contains all the templates your app needs.
  2. Repository: The warehouse. The location where charts reside (like Docker Hub for images or npm registry for nodes).
  3. Release: The instance. When you install a chart, a release is created. This is important: You can install the same chart five times (e.g. wordpress-dev, wordpress-staging, etc.) - that’s five different releases.

Anatomy of a chart: Where is what?

A chart is not a black box, but simply a folder with a clear structure. If you type helm create my-chart you get exactly this:

mein-chart/
  ├── Chart.yaml          # Metadaten (Name, Version, Beschreibung)
  ├── values.yaml         # Deine "Knöpfe & Regler" (Hier spielt die Musik!)
  ├── charts/             # Abhängigkeiten (falls dein Chart z.B. eine DB braucht)
  └── templates/          # Die eigentlichen K8s-Manifeste mit Platzhaltern
      ├── deployment.yaml
      └── service.yaml

The most important file for your everyday life? The values.yaml. It is your interface for configuration.

Die Magie in Action: Templates vs. Values

Let’s look at how Helm turns static YAML into dynamic code.

The template (templates/deployment.yaml): Here we define the structure, but leave gaps for the variable data.

apiVersion: apps/v1
kind: Deployment
metadata:
  # Der Name wird dynamisch anhand des Releases generiert
  name: {{ .Release.Name }}-web
spec:
  # Wir greifen auf die Config zu
  replicas: {{ .Values.replicaCount }}
  template:
    spec:
      containers:
        - name: nginx
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"

The configuration (values.yaml): Here we define the standards (“defaults”).

replicaCount: 1
image:
  repository: nginx
  tag: stable

If you install now, Helm will “render” the template. It replaces {{ .Values.replicaCount }} with 1. The result is valid Kubernetes YAML that goes directly to the cluster.

Cheatsheet: The commands for everyday life

You don’t have to know all 50 Helm Commands. These cover 90% of your everyday life:

Manage repositories

  • helm repo add [name] [url] Adds a source (e.g. Bitnami).
  • helm repo update Updates your local list (like apt-get update).
  • helm search repo [keyword] Searches for charts (e.g. helm search repo nginx).

Install & Upgrade

  • helm install [release-name] [chart-name] Installs a chart. Example: helm install my-wiki bitnami/dokuwiki
  • helm upgrade [release-name] [chart-name] The most important command in CI/CD: Updates a release with a new image or new config.
  • helm list Shows you what is currently running in your cluster.
  • helm uninstall [release-name] Clean up and delete everything that belongs to the chart.

Pro-Tip: Use helm install --dry-run --debug. This will show you the generated YAML without installing it. Perfect for debugging before you break something.

The real power: overwriting values

Why are we doing this? So that we can use different values ​​for Production than for Dev without changing the chart.

You have two options to override the values.yaml:

Option A: The Quick-Fix (Command Line) Perfect for quick tests or small changes. helm install my-app ./my-chart --set replicaCount=3

Option B: The professional way (own file) You create your own file for the environment, e.g. values-prod.yaml. helm install my-app ./my-chart -f values-prod.yaml

The values-prod.yaml then only contains the differences to the standard (e.g. more replicas, ingress activated). This is Infrastructure as Code in its purest form.