What is Helm?
Helm is the package manager for Kubernetes. It simplifies the deployment and management of Kubernetes applications by packaging related resources into reusable, versioned charts. Think of Helm charts as the "apt" or "brew" equivalent for Kubernetes — instead of managing dozens of individual YAML manifests, you install a single chart.
Helm Key Concepts
- Chart: A Helm package containing all Kubernetes resource definitions needed to run an application
- Release: A running instance of a chart. You can install the same chart multiple times with different configurations
- Repository: A place where charts are collected and shared (like Docker Hub for images)
- Values: Configuration parameters that customize a chart for a specific environment
Installing Helm
# Install Helm
# macOS
brew install helm
# Linux
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# Verify installation
helm version
# Add popular chart repositories
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo add jetstack https://charts.jetstack.io
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
# Update repositories
helm repo update
# Search for charts
helm search repo nginx
helm search repo postgres
Installing Charts
# Install PostgreSQL from Bitnami
helm install my-postgres bitnami/postgresql \
--namespace database \
--create-namespace \
--set auth.postgresPassword=mySecretPassword \
--set auth.database=myapp \
--set primary.persistence.size=10Gi
# Install with a values file
helm install my-postgres bitnami/postgresql \
--namespace database \
--create-namespace \
-f postgres-values.yaml
# List installed releases
helm list -A
# Get release status
helm status my-postgres -n database
# View generated manifests
helm get manifest my-postgres -n database
# Upgrade a release
helm upgrade my-postgres bitnami/postgresql \
--namespace database \
-f postgres-values.yaml \
--set primary.persistence.size=20Gi
# Rollback to a previous revision
helm rollback my-postgres 1 -n database
# Uninstall a release
helm uninstall my-postgres -n database
Creating Your Own Chart
# Create a new chart
helm create my-web-app
# Chart directory structure:
# my-web-app/
# Chart.yaml # Chart metadata
# values.yaml # Default configuration values
# charts/ # Dependency charts
# templates/ # Kubernetes manifest templates
# deployment.yaml
# service.yaml
# ingress.yaml
# hpa.yaml
# serviceaccount.yaml
# _helpers.tpl # Template helpers
# NOTES.txt # Post-install notes
# .helmignore # Files to ignore
Chart.yaml
# Chart.yaml
apiVersion: v2
name: my-web-app
description: A Helm chart for my web application
type: application
version: 0.1.0 # Chart version
appVersion: "1.0.0" # Application version
keywords:
- web
- nodejs
- api
maintainers:
- name: DevOps Team
email: devops@company.com
dependencies:
- name: postgresql
version: "13.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
- name: redis
version: "18.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: redis.enabled
values.yaml
# values.yaml
replicaCount: 3
image:
repository: myregistry/my-web-app
tag: "1.0.0"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
ingress:
enabled: true
className: nginx
hosts:
- host: app.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: app-tls
hosts:
- app.example.com
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 70
env:
NODE_ENV: production
LOG_LEVEL: info
postgresql:
enabled: true
auth:
database: myapp
redis:
enabled: false
Template Example
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "my-web-app.fullname" . }}
labels:
{{- include "my-web-app.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "my-web-app.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "my-web-app.selectorLabels" . | nindent 8 }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: 3000
env:
{{- range $key, $value := .Values.env }}
- name: {{ $key }}
value: {{ $value | quote }}
{{- end }}
resources:
{{- toYaml .Values.resources | nindent 10 }}
# Lint your chart
helm lint my-web-app/
# Render templates locally (dry run)
helm template my-release my-web-app/ -f production-values.yaml
# Install your chart
helm install my-release my-web-app/ -f production-values.yaml -n production
# Package the chart for distribution
helm package my-web-app/
# Push to an OCI registry
helm push my-web-app-0.1.0.tgz oci://ghcr.io/myorg/charts
Key Takeaways
- Helm is the Kubernetes package manager — it simplifies complex deployments into reusable charts
- Charts package all Kubernetes resources together with configurable values
- Use values files to customize charts per environment (dev, staging, production)
- Helm supports versioning, rollbacks, and dependency management
- Always lint and template-render charts locally before deploying to a cluster