How to Create and Use Helm Charts
Master Helm, the Kubernetes package manager. Learn to create charts, manage releases, and template your deployments for reusability.
The Problem
You need to package, version, and deploy your Kubernetes applications consistently across multiple environments.
The Solution
Use Helm charts to template and package your Kubernetes manifests, making deployments repeatable and configurable.
Installing Helm
# macOS
brew install helm
# Linux
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# Verify installation
helm versionUsing Existing Charts
Add a Repository
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo updateSearch for Charts
helm search repo nginx
helm search hub wordpressInstall a Chart
helm install my-nginx bitnami/nginxList Releases
helm list
helm list --all-namespacesUninstall a Release
helm uninstall my-nginxCreating Your Own Chart
Generate Chart Scaffold
helm create myappThis creates:
myapp/
βββ Chart.yaml # Chart metadata
βββ values.yaml # Default configuration values
βββ charts/ # Dependencies
βββ templates/ # Kubernetes manifest templates
β βββ deployment.yaml
β βββ service.yaml
β βββ ingress.yaml
β βββ hpa.yaml
β βββ serviceaccount.yaml
β βββ _helpers.tpl # Template helpers
β βββ NOTES.txt # Post-install notes
β βββ tests/
βββ .helmignoreChart.yaml
apiVersion: v2
name: myapp
description: A Helm chart for my application
type: application
version: 0.1.0
appVersion: "1.0.0"
keywords:
- myapp
- web
maintainers:
- name: Your Name
email: your@email.com
dependencies:
- name: postgresql
version: "12.x.x"
repository: https://charts.bitnami.com/bitnami
condition: postgresql.enabledvalues.yaml
replicaCount: 2
image:
repository: myapp
pullPolicy: IfNotPresent
tag: "1.0.0"
service:
type: ClusterIP
port: 80
ingress:
enabled: false
className: nginx
hosts:
- host: myapp.example.com
paths:
- path: /
pathType: Prefix
resources:
limits:
cpu: 500m
memory: 256Mi
requests:
cpu: 100m
memory: 128Mi
autoscaling:
enabled: false
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 80
postgresql:
enabled: true
auth:
username: myapp
database: myappTemplate Examples
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "myapp.fullname" . }}
labels:
{{- include "myapp.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "myapp.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "myapp.selectorLabels" . | nindent 8 }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: 8080
protocol: TCP
livenessProbe:
httpGet:
path: /health
port: http
readinessProbe:
httpGet:
path: /ready
port: http
resources:
{{- toYaml .Values.resources | nindent 12 }}
env:
{{- if .Values.postgresql.enabled }}
- name: DATABASE_HOST
value: {{ include "myapp.fullname" . }}-postgresql
- name: DATABASE_USER
value: {{ .Values.postgresql.auth.username }}
- name: DATABASE_NAME
value: {{ .Values.postgresql.auth.database }}
{{- end }}_helpers.tpl
{{/*
Expand the name of the chart.
*/}}
{{- define "myapp.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
*/}}
{{- define "myapp.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "myapp.labels" -}}
helm.sh/chart: {{ include "myapp.chart" . }}
{{ include "myapp.selectorLabels" . }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "myapp.selectorLabels" -}}
app.kubernetes.io/name: {{ include "myapp.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}Working with Charts
Lint Your Chart
helm lint myapp/Dry Run / Template
# See rendered templates
helm template myapp ./myapp
# Dry run against cluster
helm install myapp ./myapp --dry-run --debugInstall Your Chart
helm install myapp ./myapp -f custom-values.yamlUpgrade a Release
helm upgrade myapp ./myapp --set image.tag=2.0.0Rollback
helm rollback myapp 1Package for Distribution
helm package myapp/
# Creates myapp-0.1.0.tgzEnvironment-Specific Values
Create separate value files:
# values-dev.yaml
replicaCount: 1
image:
tag: "dev"
# values-prod.yaml
replicaCount: 3
image:
tag: "1.0.0"
resources:
limits:
memory: 512MiDeploy:
helm install myapp ./myapp -f values-prod.yamlCommon Template Functions
# Default value
{{ .Values.foo | default "bar" }}
# Required value
{{ required "A valid .Values.image.tag is required!" .Values.image.tag }}
# Conditional
{{- if .Values.ingress.enabled }}
# ingress manifest
{{- end }}
# Range/Loop
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
{{- end }}
# Quote strings
value: {{ .Values.name | quote }}
# ToYaml
{{- toYaml .Values.resources | nindent 12 }}Best Practices
- Use helpers for repeated labels and names
- Validate inputs with
required - Set defaults for optional values
- Quote strings to avoid YAML issues
- Document values.yaml with comments
- Version your charts semantically
Key Takeaways
- Helm simplifies Kubernetes deployments
- Charts are reusable, versioned packages
- values.yaml configures templates
- Use
helm templateto debug - Create separate values files per environment
π Go Further with Kubernetes Recipes
Love this recipe? Thereβs so much more! This is just one of 100+ hands-on recipes in our comprehensive Kubernetes Recipes book.
Inside the book, youβll master:
- β Production-ready deployment strategies
- β Advanced networking and security patterns
- β Observability, monitoring, and troubleshooting
- β Real-world best practices from industry experts
βThe practical, recipe-based approach made complex Kubernetes concepts finally click for me.β
π Get Your Copy Now β Start building production-grade Kubernetes skills today!
π Get All 100+ Recipes in One Book
Stop searching β get every production-ready pattern with detailed explanations, best practices, and copy-paste YAML.
Want More Kubernetes Recipes?
This recipe is from Kubernetes Recipes, our 750-page practical guide with hundreds of production-ready patterns.