Containers & Kubernetes12 min
Helm — Package Manager Cheat Sheet
Essential Helm commands — install, upgrade, rollback, template rendering, chart creation, repository management, and values overriding.
Setup & Repositories
# Install Helm (Linux/macOS)
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# Check version
helm version
# Add repositories
helm repo add stable https://charts.helm.sh/stable
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo add cert-manager https://charts.jetstack.io
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
# Update repos (like apt-get update)
helm repo update
# List repos
helm repo list
# Remove repo
helm repo remove stable
# Search for charts
helm search repo nginx
helm search repo bitnami/postgres
helm search hub wordpress # search Artifact Hub (public registry)
Install & Upgrade
# Install a chart
helm install my-release bitnami/mysql
helm install my-release bitnami/mysql --namespace my-ns --create-namespace
helm install my-release bitnami/mysql --version 9.14.0 # pin version
# Install with values
helm install my-release bitnami/mysql \
--set auth.rootPassword=secret \
--set primary.persistence.size=10Gi
# Install with values file
helm install my-release bitnami/mysql -f custom-values.yaml
# Install + wait until ready
helm install my-release bitnami/mysql --wait --timeout 5m
# Dry run (validate without deploying)
helm install my-release bitnami/mysql --dry-run
# Upgrade (create if not exists with --install)
helm upgrade my-release bitnami/mysql --set auth.rootPassword=new-secret
helm upgrade --install my-release bitnami/mysql -f values.yaml
# Upgrade with atomic (auto-rollback on failure)
helm upgrade my-release bitnami/mysql --atomic --timeout 5m
List & Status
# List releases
helm list # Current namespace
helm list --all-namespaces
helm list -A # Short form
helm list --failed # Only failed releases
helm list --deployed # Only deployed
helm list --pending
# Status of a release
helm status my-release
# Get all info about a release
helm get all my-release
helm get values my-release # Current values (user-supplied)
helm get values my-release --all # All values (computed defaults too)
helm get manifest my-release # Rendered Kubernetes manifests
helm get hooks my-release
helm get notes my-release
Rollback & Uninstall
# Rollback to previous version
helm rollback my-release
# Rollback to specific revision
helm rollback my-release 2
# History
helm history my-release
# Uninstall (removes all K8s resources)
helm uninstall my-release
helm uninstall my-release --namespace my-ns
helm uninstall my-release --keep-history # Keep release history (can rollback later)
Template Rendering
# Render templates locally (debug without applying)
helm template my-release bitnami/mysql -f values.yaml
# Render specific template
helm template my-release bitnami/mysql --show-only templates/deployment.yaml
# Validate rendered templates against cluster
helm template my-release bitnami/mysql | kubectl apply --dry-run=server -f -
# Lint a chart
helm lint ./my-chart/
helm lint ./my-chart/ -f custom-values.yaml
Values
# Show default values for a chart
helm show values bitnami/mysql
helm show values bitnami/mysql > default-values.yaml
# Show chart metadata
helm show chart bitnami/mysql
# Show readme
helm show readme bitnami/mysql
# Override precedence (highest wins):
# 1. --set (command line)
# 2. -f values.yaml (file, last file wins if multiple)
# 3. Chart's default values.yaml
# Set nested values
helm install my-release my-chart --set "ingress.hosts[0].host=app.example.com"
# Set multiple values
helm install my-release my-chart \
--set replicaCount=3 \
--set image.tag=v2 \
--set service.type=LoadBalancer
Creating Charts
# Create a new chart scaffold
helm create my-chart
# Chart structure:
# my-chart/
# Chart.yaml ← metadata (name, version, description)
# values.yaml ← default values
# charts/ ← dependencies
# templates/ ← Kubernetes manifests with templating
# deployment.yaml
# service.yaml
# ingress.yaml
# _helpers.tpl ← named templates / helpers
# Package chart
helm package ./my-chart/
# Creates: my-chart-0.1.0.tgz
# Package with signed provenance
helm package --sign ./my-chart/
# Index a chart repo directory
helm repo index ./charts/ --url https://charts.example.com
Bicep/Helm Template Syntax Cheatsheet
# values.yaml
replicaCount: 2
image:
repository: nginx
tag: "1.25"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "my-chart.fullname" . }}
labels:
{{- include "my-chart.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "my-chart.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "my-chart.selectorLabels" . | nindent 8 }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: {{ .Values.service.port }}
{{- if .Values.resources }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- end }}
Common template functions:
| Function | Example |
|---|---|
{{ .Values.key }} | Access values |
{{ .Release.Name }} | Release name |
{{ .Chart.Version }} | Chart version |
{{ include "name" . }} | Call named template |
{{- ... -}} | Trim whitespace |
| nindent N | Indent by N spaces |
| toYaml | Render as YAML |
| default "val" | Default if empty |
| quote | Wrap in quotes |
{{- if .Values.enabled }} | Conditional |
{{- range .Values.list }} | Loop |
Plugins
# Install plugin
helm plugin install https://github.com/databus23/helm-diff
helm plugin install https://github.com/jkroepke/helm-secrets
# List plugins
helm plugin list
# Useful: helm-diff (show what upgrade would change)
helm diff upgrade my-release bitnami/mysql -f values.yaml
# Useful: helm-secrets (encrypt values.yaml with GPG/SOPS)
helm secrets enc values.secret.yaml
helm secrets install my-release my-chart -f values.secret.yaml
