Mastering HELM: A Guide to Smarter Deployment


What is Helm, Really?
Think about installing software on your regular computer. You don't usually download dozens of individual configuration files and set them up by hand, right? You use a package manager:
On Debian/Ubuntu Linux: apt
On Fedora/CentOS Linux: yum or dnf
On macOS: brew
On Windows: Chocolatey or an installer (.exe/.msi)
These tools bundle software, handle its dependencies (other software it needs), and make installation, upgrades, and removal super easy with simple commands.
Helm is exactly that: the package manager for Kubernetes.
It takes all those potentially complex Kubernetes YAML files needed for an application, bundles them into a neat package called a Chart, and lets you manage the application's entire lifecycle (install, upgrade, rollback, delete) with straightforward commands.
Why Do You Really Need Helm?
Imagine deploying a typical web application on Kubernetes. You'll likely need YAML files for:
A Deployment: To manage your application's running instances (Pods).
A Service: To give your application a stable network address inside the cluster.
An Ingress: (Optional) To expose your application to the outside world (e.g., myapp.yourdomain.com).
A ConfigMap: To store non-sensitive configuration data.
A Secret: To store sensitive data like passwords or API keys.
Maybe a PersistentVolumeClaim: If your app needs to store data.
That's potentially 4, 5, 6 or even more YAML files just for one simple app! Now consider the real-world challenges:
Complexity Grows: Real applications often involve many more interconnected components.
Repetition is Tedious: Need the same app for development, testing, and production? You'd be copying, pasting, and carefully editing values (like domain names, replica counts, database passwords, resource limits) in multiple files for each environment. It's boring and easy to make mistakes!
Updates are Hard: How do you update the application's container image version consistently across all relevant files without missing one?
Sharing is Difficult: How do you easily give your entire application setup (all the YAMLs and instructions) to a colleague or the open-source community? Emailing zip files of YAML? There has to be a better way!
Rollbacks are Scary: What if an update breaks something? Manually figuring out which versions of which files to revert to and reapplying them under pressure is stressful and error-prone.
Helm elegantly solves all these problems by introducing standardization and automation.
Before You Start: ( Prerequisites)
A Kubernetes Cluster: This could be anything from:
A local cluster on your machine (like Minikube, Kind, k3d, Docker Desktop Kubernetes).
A cloud-managed cluster (Google Kubernetes Engine - GKE, Amazon Elastic Kubernetes Service - EKS, Azure Kubernetes Service - AKS, etc.).
Any other conformant Kubernetes cluster.
kubectl Installed and Configured: Helm uses your local Kubernetes configuration file (usually located at ~/.kube/config) to communicate with your cluster. Make sure kubectl is installed and commands like kubectl get nodes work correctly and target the cluster you intend to use.
Installing Helm:
Method 1: The Official Script (Linux/macOS)
This is often the quickest way to get the latest version:
# Download the installer script
$ curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
# Make the script executable
$ chmod 700 get_helm.sh
# Run the script to install Helm
$ ./get_helm.sh
Method 2: Using Package Managers (Recommended for Easy Updates)
macOS (using Homebrew):
brew install helm
Windows (using Chocolatey):
choco install kubernetes-helm
Linux (using Snap):
sudo snap install helm --classic
Linux (Debian/Ubuntu using Apt): (Official Helm instructions)
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null sudo apt-get install apt-transport-https --yes echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list sudo apt-get update sudo apt-get install helm
Verify Installation:
Open a new terminal and run:
helm version
Core Helm Concepts Explained Simply
Understanding these three core terms is essential:
Chart:
What it is: The Helm package format. It's a collection of files organized in a specific directory structure that describes a related set of Kubernetes resources. Think of it as the "recipe" or "blueprint" for deploying an application.
Key Contents: Templates (Kubernetes YAML with placeholders), default values (values.yaml), and chart metadata (Chart.yaml).
Repository (Repo):
What it is: A place where Charts are stored and shared. It's essentially a web server hosting packaged chart files and an index file. Think of it like an App Store, apt repository, or Docker Hub, but for Kubernetes applications.
Examples: The popular bitnami repository, Artifact Hub (a central search engine for charts), cloud provider marketplaces, and your own private repositories.
Release:
What it is: A specific instance of a Chart that has been deployed to your Kubernetes cluster using Helm.
Key Idea: You install a Chart to create a Release. You can install the same chart multiple times on the same cluster (e.g., my-app-staging, my-app-production), each creating a unique Release with potentially different configurations. Helm tracks each release individually.
How Helm Works:
When you run helm install or helm upgrade, here’s a simplified view of what happens:
Fetch: Helm retrieves the specified Chart (from a repository or a local path).
Combine Values: Helm takes the default configuration values from the chart's values.yaml file. It then merges these with any custom values you provide (e.g., using --set on the command line or via custom value files specified with -f). Your custom values override the defaults.
Render Templates: Helm processes the template files (usually .yaml files inside the chart's templates/ directory). It uses the Go templating engine to replace placeholders (like {{ .Values.replicaCount }} or {{ .Release.Name }}) with the final combined values from the previous step. This generates standard, ready-to-use Kubernetes YAML manifests.
Deploy to Kubernetes: Helm sends these generated YAML manifests to your Kubernetes cluster's API server. Kubernetes then works to create or modify the resources (Deployments, Services, etc.) to match the desired state described in the YAML.
Track Release: Helm stores information about this specific deployment (which chart and version were used, what values were applied) as a Release object within Kubernetes itself (as a Secret by default). This history allows Helm to manage future upgrades, rollbacks, and uninstallation.
Getting Your Hands Dirty:
Let's dive into the practical commands you'll use most often. We'll use the popular bitnami repository for many examples.
Add a Chart Repository:
Tell Helm about a source for charts.# Add the Bitnami repository under the name 'bitnami' helm repo add bitnami https://charts.bitnami.com/bitnami
- Best Practice: Always update your local cache after adding a repo or periodically.
helm repo update
Search for Charts:
Find available charts in your configured repositories.# Search all configured repos for charts containing 'nginx' helm search repo nginx # Search specifically in the 'bitnami' repo for 'redis' helm search repo bitnami/redis
Install a Chart (Create a Release):
Deploy an application using a chart.# Syntax: helm install <YOUR_RELEASE_NAME> <CHART_NAME> [FLAGS] helm install my-webserver bitnami/nginx
my-webserver is your unique name for this deployment instance (the Release).
bitnami/nginx is the chart to use.
List Your Releases:
See Helm releases deployed in the current Kubernetes namespace.helm list
Get Status of a Release:
Check details, notes, and Kubernetes resources for a specific release.helm status my-webserver
Inspect Chart Information:
Show Chart Metadata (Chart.yaml):
helm show chart bitnami/nginx
Show Default Values (values.yaml): Crucial for knowing what you can customize!
helm show values bitnami/nginx # Tip: Pipe to 'less' or save to a file for easier viewing # helm show values bitnami/nginx | less # helm show values bitnami/nginx > nginx-defaults.yaml
Install with Custom Values (Overrides):
Using --set (simple command-line overrides):
helm install my-other-webserver bitnami/nginx --set replicaCount=3 --set service.type=LoadBalancer
Using a custom values file (-f or --values): Best for many or complex overrides.
Create my-values.yaml:
# my-values.yaml replicaCount: 2 service: type: ClusterIP port: 8080
Install using the file:
helm install my-file-webserver bitnami/nginx -f my-values.yaml
Precedence: --set values override -f file values, which override chart defaults.
Upgrade an Existing Release:
Modify configuration or update the chart version of a deployed release.# Change replica count for 'my-webserver' helm upgrade my-webserver bitnami/nginx --set replicaCount=2 # Upgrade 'my-webserver' to a specific chart version (if available) # helm upgrade my-webserver bitnami/nginx --version <NEW_CHART_VERSION>
View Release History:
See the revision history for a release (each upgrade/rollback creates a revision).helm history my-webserver
Rollback a Release:
Revert a release to a previous revision (a true lifesaver!).# Rollback 'my-webserver' to its first revision (check 'helm history' first) helm rollback my-webserver 1
Download a Chart Locally:
Get the chart source files for inspection or modification.# Fetch the chart package (.tgz file) helm pull bitnami/nginx # Fetch and unpack into a directory named 'nginx' helm pull bitnami/nginx --untar
Template Locally (Dry Run & Debugging):
See the final Kubernetes YAML Helm would generate, without deploying.# See YAML with default values helm template my-test-release bitnami/nginx # See YAML with custom values helm template my-test-release bitnami/nginx --set replicaCount=5 > generated.yaml
Uninstall a Release:
Clean up and remove all Kubernetes resources associated with a release.helm uninstall my-webserver
Two Common Helm Scenarios: Using vs. Creating
✅ Scenario 1: Using Pre-Built Charts (Consuming)
This is where most people start. You leverage charts created by others (like Bitnami, official projects, or internal teams) to quickly deploy standard software.
Goal: Deploy something like Nginx or a database without writing the Kubernetes YAML yourself.
You Need: The name of the chart and the repository it's in.
🔹 Step-by-Step Using Bitnami’s Nginx Chart:
Add the Bitnami Chart Repository (One-time setup):
helm repo add bitnami https://charts.bitnami.com/bitnami helm repo update
Search for the Chart (Optional verification):
helm search repo bitnami/nginx
Install the Chart (Basic Deployment):
This deploys NGINX using the default values configured by Bitnami. Give your deployment a unique release name.helm install my-nginx bitnami/nginx
Optional: Install with Customizations:
Use --set or a -f values.yaml file to tweak the deployment.helm install my-nginx-custom bitnami/nginx --set replicaCount=3 --set service.type=LoadBalancer
Check Deployment Status:
helm list helm status my-nginx helm status my-nginx-custom
🛠️ Scenario 2: Creating Your Own Helm Chart (Producing)
When you have your own custom application, or need very specific Kubernetes configurations not offered by public charts, you'll package it by creating your own Helm chart.
Goal: Package your application for easy, repeatable, and configurable deployment on Kubernetes.
You Need: Your application's container image and an understanding of the K8s resources it requires.
🔹 Step-by-Step to Create and Use Your Own Chart:
Create the Chart Scaffold:
Helm provides a command to generate a standard chart directory structure.# This creates a directory named 'my-cool-app/' helm create my-cool-app
For Packages the Helm Chart
helm package my-cool-app
Explore and Edit the Generated Files:
Navigate into the my-cool-app/ directory. You'll need to customize these key files:Chart.yaml: Edit metadata like name, description, version (of the chart), and appVersion (of your application).
values.yaml: This is crucial! Define the default configuration options for your chart. Think about what users (including yourself) might want to change: image repository/tag, replica count, service ports, resource limits, configuration settings, etc.
templates/deployment.yaml, templates/service.yaml, etc.: Modify these Kubernetes manifest templates. Replace the placeholder image, ports, etc., with template directives referencing your values.yaml (e.g., image: {{ .Values.image.repository }}:{{ .Values.image.tag }}, replicas: {{ .Values.replicaCount }}). Add new template files (e.g., for an Ingress, ConfigMap) as needed for your application. Remove unused example templates.
templates/_helpers.tpl: (Advanced) Used for defining reusable template snippets to keep your main templates clean.
templates/NOTES.txt: Customize the helpful notes displayed after a successful installation.
Lint Your Chart (Check for Errors):
Catch common mistakes and validate formatting.# Run this from the directory containing Chart.yaml, or specify path helm lint ./my-cool-app
Install Your Local Chart:
Deploy your application using the chart directory you just customized.helm install my-app-release ./my-cool-app
my-app-release is the name you give this specific deployment instance.
./my-cool-app tells Helm to use the chart located in that local directory.
Optional: Install/Upgrade with Overrides:
Even with your own chart, you can override the defaults from values.yaml at deploy time.helm install my-app-prod ./my-cool-app --set replicaCount=5 --set image.tag="v1.2.3" # Or upgrade an existing release helm upgrade my-app-release ./my-cool-app --set service.type=LoadBalancer
Check Deployment Status:
helm list helm status my-app-release
Understanding Your Own Chart Structure (The Files in Detail)
When you run helm create my-app, here's a closer look at the generated files/folders:
Chart.yaml: (File) Metadata about your chart.
Beginner: Like the label on a software box (name, version).
Pro: Defines API version (v2 recommended for Helm 3+), dependencies on other charts, keywords for search, maintainer info. Crucial for versioning and sharing.
values.yaml: (File) The default configuration settings.
Beginner: The user manual showing default settings; users override these.
Pro: The public API of your chart. Structure logically (e.g., nested database.host, ingress.enabled). Clear comments are essential for usability.
templates/: (Directory) Contains the Kubernetes YAML files written as Go templates.
Beginner: Blueprints with blanks ({{ .Values.xyz }}) filled in by Helm using values.
Pro: The core logic. Uses Go templating functions/logic (if, range, include, etc.) and built-in objects (.Values, .Release, .Chart, .Capabilities).
templates/NOTES.txt: (File) A template rendered and shown after successful install/upgrade.
Beginner: Print simple "how to access" instructions.
Pro: Use template logic to provide dynamic instructions based on configuration (e.g., show LoadBalancer IP only if service.type is LoadBalancer).
templates/_helpers.tpl: (File) Defines reusable template snippets ("named templates").
Beginner: Place for common bits of code used in multiple template files.
Pro: Essential for DRY (Don't Repeat Yourself). Define common labels, resource names, complex logic blocks here using {{ define "mychart.myhelper" }} ... {{ end }} and call with {{ include "mychart.myhelper" . }}.
templates/deployment.yaml, service.yaml, etc.: (Files) Example Kubernetes resource templates.
Beginner: Starting points showing how to use values. You'll edit/replace these heavily.
Pro: The core application definition. You'll add templates for ConfigMaps, Secrets, Ingresses, PersistentVolumeClaims, ServiceAccounts, RBAC, HPA, etc., all driven by values.yaml.
.helmignore: (File) Specifies files/patterns Helm should ignore when packaging the chart (like .git, README.md, etc.).
charts/: (Directory) Subcharts (dependencies) are placed here, typically managed declaratively in Chart.yaml and fetched via helm dependency update.
Basic File Structure:
Why Helm is Your Friend (Benefits Recap)
Simplicity: Manage complex apps with easy commands (install, upgrade, uninstall).
Consistency & Repeatability: Deploy the same way every time, across environments (dev, staging, prod), using value overrides for differences.
Reusability & Sharing: Package once, deploy anywhere. Share charts easily via repositories.
Discoverability: Find existing applications packaged as charts (e.g., on Artifact Hub).
Lifecycle Management: Helm cleanly handles installations, upgrades, rollbacks, and deletions.
Dependency Management: Charts can declare dependencies on other charts (e.g., your app chart depending on a database chart).
Where to Go Next?
Practice! Install various charts from bitnami or other repos. Try overriding different values using --set and -f. Upgrade and rollback releases.
Official Helm Documentation: The definitive source: https://helm.sh/docs/ - Read the "Chart Template Guide"!
Artifact Hub: Explore existing charts: https://artifacthub.io/
Try helm create: Take a simple application you know and try packaging it into your own chart. Start small!
Subscribe to my newsletter
Read articles from Debjyoti Shit directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Debjyoti Shit
Debjyoti Shit
I share what I learn about Cloud Computing, DevOps, and Web Development in one place. I gather knowledge from different sources and simplify it, so you get the most useful information easily.