Deploy Todo App with Helm
Package and Deploy Todo Application with Helm Charts
Learn templating, packaging, and environment-specific deployments with Helm.
What You’ll Learn
- Helm charts - Package Kubernetes applications
- Templating - DRY with Go templates and values
- Values files - Environment-specific configurations
- Chart structure - Best practices and organization
- Release management - Install, upgrade, rollback
Prerequisites:
- Completed Exercise 3 (Deploy with Kustomize)
- Helm 3.x installed
- Docker images available (from Exercise 2)
- kubectl configured for Docker Desktop and/or EKS
Understanding Helm
What is Helm?
Helm is the package manager for Kubernetes - think of it as apt/yum/homebrew for K8s.
Key concepts:
- Chart: Package of Kubernetes resources (like a .deb or .rpm)
- Template: YAML with variables
{{ .Values.something }} - Values: Configuration that varies per environment
- Release: Deployed instance of a chart
Why Helm over Kustomize?
| Feature | Kustomize | Helm |
|---|---|---|
| Templating | Patches/overlays | Go templates |
| Reusability | Good | Excellent |
| Complexity | Simple | More powerful |
| Dependencies | Manual | Built-in |
| Rollback | Manual | Built-in |
| Packaging | No | Yes |
| Community | Growing | Massive |
When to use Helm:
- Need complex templating
- Want to package and distribute charts
- Need dependency management
- Want built-in rollback
- Deploying to many environments
When to use Kustomize:
- Simpler deployments
- Prefer pure YAML (no templating)
- Already using kubectl
- Want lighter tooling
Step 1: Install Helm
Verify Helm Installation
helm versionExpected output:
version.BuildInfo{Version:"v3.x.x", ...}Install Helm (if needed)
macOS:
brew install helmLinux:
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bashWindows:
choco install kubernetes-helmStep 2: Create Helm Chart Structure
2.1 Create Chart Directory
cd /path/to/implementation
mkdir -p "4. Deploy Todo App with Helm"
cd "4. Deploy Todo App with Helm"
# Create chart
helm create todo-app-chartThis creates the default structure. We’ll customize it.
2.2 Clean Up Default Files
cd todo-app-chart
rm -rf templates/*.yaml templates/tests2.3 Final Chart Structure
todo-app-chart/
βββ Chart.yaml # Chart metadata
βββ values.yaml # Default values
βββ values-docker-desktop.yaml
βββ values-eks-dockerhub.yaml
βββ values-eks-ecr.yaml
βββ templates/
βββ _helpers.tpl # Template helpers
βββ namespace.yaml
βββ storageclass.yaml
βββ mongodb-statefulset.yaml
βββ mongodb-service.yaml
βββ mongodb-init-job.yaml
βββ webapp-configmap.yaml
βββ webapp-deployment.yaml
βββ webapp-service.yaml
βββ mongo-express-deployment.yaml
βββ mongo-express-service.yamlStep 3: Create Chart Metadata
Chart.yaml
Create Chart.yaml:
apiVersion: v2
name: todo-app
description: A full-stack Todo application with MongoDB backend
type: application
version: 1.0.0
appVersion: "1.0.0"
keywords:
- todo
- mongodb
- asp.net
maintainers:
- name: Your Name
email: your.email@example.comKey fields:
apiVersion: v2- Helm 3 charttype: application- Deployable application (vs library)version- Chart version (semver)appVersion- Application version
Step 4: Create Template Helpers
templates/_helpers.tpl
Create templates/_helpers.tpl:
{{/*
Expand the name of the chart.
*/}}
{{- define "todo-app.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
*/}}
{{- define "todo-app.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "todo-app.labels" -}}
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
app.kubernetes.io/name: {{ include "todo-app.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "todo-app.selectorLabels" -}}
app.kubernetes.io/name: {{ include "todo-app.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}These helpers:
- Generate consistent naming
- Create standard labels
- Enable chart reusability
Step 5: Create Default Values
values.yaml
Create values.yaml:
# Default values for todo-app chart
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
# Global settings
namespace: todo-app
# Container image configuration
image:
repository: larsappel/todo-app
tag: latest
pullPolicy: Always
# MongoDB configuration
mongodb:
enabled: true
replicas: 1
image: mongo:latest
storage:
enabled: true
size: 1Gi
# storageClass will be set per environment
storageClass: ""
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
database: "ToDoAppDb"
# WebApp configuration
webapp:
enabled: true
replicas: 2
port: 8080
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
service:
type: LoadBalancer
port: 80
# AWS Load Balancer annotations (only for EKS)
annotations: {}
# Mongo Express configuration
mongoExpress:
enabled: true
replicas: 1
image: mongo-express:latest
port: 8081
username: admin
password: pass
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
service:
type: LoadBalancer
port: 80
annotations: {}
# Init job configuration
initJob:
enabled: true
backoffLimit: 4
todos:
- id: 1
name: "Learn Kubernetes"
isComplete: false
- id: 2
name: "Deploy MongoDB"
isComplete: true
# Storage class (environment-specific)
storageClass:
enabled: false
name: ebs-sc
provisioner: ebs.csi.eks.amazonaws.com
volumeBindingMode: WaitForFirstConsumer
parameters:
type: gp3
encrypted: "true"Step 6: Create Templated Manifests
6.1 Namespace Template
Create templates/namespace.yaml:
apiVersion: v1
kind: Namespace
metadata:
name: {{ .Values.namespace }}
labels:
{{- include "todo-app.labels" . | nindent 4 }}6.2 StorageClass Template
Create templates/storageclass.yaml:
{{- if .Values.storageClass.enabled }}
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: {{ .Values.storageClass.name }}
labels:
{{- include "todo-app.labels" . | nindent 4 }}
provisioner: {{ .Values.storageClass.provisioner }}
volumeBindingMode: {{ .Values.storageClass.volumeBindingMode }}
parameters:
{{- toYaml .Values.storageClass.parameters | nindent 2 }}
{{- end }}6.3 MongoDB StatefulSet Template
Create templates/mongodb-statefulset.yaml:
{{- if .Values.mongodb.enabled }}
---
apiVersion: v1
kind: Service
metadata:
name: mongodb-service
namespace: {{ .Values.namespace }}
labels:
{{- include "todo-app.labels" . | nindent 4 }}
app: mongodb
spec:
selector:
app: mongodb
ports:
- port: 27017
targetPort: 27017
clusterIP: None
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongodb
namespace: {{ .Values.namespace }}
labels:
{{- include "todo-app.labels" . | nindent 4 }}
app: mongodb
spec:
serviceName: mongodb-service
replicas: {{ .Values.mongodb.replicas }}
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongodb
image: {{ .Values.mongodb.image }}
ports:
- containerPort: 27017
volumeMounts:
- name: mongodb-data
mountPath: /data/db
resources:
{{- toYaml .Values.mongodb.resources | nindent 10 }}
{{- if .Values.mongodb.storage.enabled }}
volumeClaimTemplates:
- metadata:
name: mongodb-data
spec:
accessModes: ["ReadWriteOnce"]
{{- if .Values.mongodb.storage.storageClass }}
storageClassName: {{ .Values.mongodb.storage.storageClass }}
{{- end }}
resources:
requests:
storage: {{ .Values.mongodb.storage.size }}
{{- end }}
{{- end }}6.4 MongoDB Init Job Template
Create templates/mongodb-init-job.yaml:
{{- if .Values.initJob.enabled }}
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "todo-app.fullname" . }}-mongodb-init
namespace: {{ .Values.namespace }}
labels:
{{- include "todo-app.labels" . | nindent 4 }}
app: mongodb-init
spec:
template:
spec:
containers:
- name: mongo-init
image: {{ .Values.mongodb.image }}
command:
- /bin/bash
- -c
- |
sleep 10
mongosh mongodb-service:27017/{{ .Values.mongodb.database }} --eval '
db.TodoItems.insertMany([
{{- range $index, $todo := .Values.initJob.todos }}
{{- if $index }},{{ end }}
{
"Id": {{ $todo.id }},
"Name": "{{ $todo.name }}",
"IsComplete": {{ $todo.isComplete }}
}
{{- end }}
]);
print("Database initialized successfully!");
'
restartPolicy: OnFailure
backoffLimit: {{ .Values.initJob.backoffLimit }}
{{- end }}6.5 WebApp ConfigMap Template
Create templates/webapp-configmap.yaml:
{{- if .Values.webapp.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: webapp-config
namespace: {{ .Values.namespace }}
labels:
{{- include "todo-app.labels" . | nindent 4 }}
data:
MONGODB_HOST: "mongodb-service"
MONGODB_PORT: "27017"
MONGODB_DATABASE: {{ .Values.mongodb.database | quote }}
{{- end }}6.6 WebApp Deployment Template
Create templates/webapp-deployment.yaml:
{{- if .Values.webapp.enabled }}
---
apiVersion: v1
kind: Service
metadata:
name: todo-webapp-service
namespace: {{ .Values.namespace }}
labels:
{{- include "todo-app.labels" . | nindent 4 }}
app: todo-webapp
{{- with .Values.webapp.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.webapp.service.type }}
selector:
app: todo-webapp
ports:
- port: {{ .Values.webapp.service.port }}
targetPort: {{ .Values.webapp.port }}
{{- if and (eq .Values.webapp.service.type "NodePort") .Values.webapp.service.nodePort }}
nodePort: {{ .Values.webapp.service.nodePort }}
{{- end }}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: todo-webapp
namespace: {{ .Values.namespace }}
labels:
{{- include "todo-app.labels" . | nindent 4 }}
app: todo-webapp
spec:
replicas: {{ .Values.webapp.replicas }}
selector:
matchLabels:
app: todo-webapp
template:
metadata:
labels:
app: todo-webapp
spec:
containers:
- name: webapp
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: {{ .Values.webapp.port }}
envFrom:
- configMapRef:
name: webapp-config
resources:
{{- toYaml .Values.webapp.resources | nindent 10 }}
{{- end }}6.7 Mongo Express Deployment Template
Create templates/mongo-express-deployment.yaml:
{{- if .Values.mongoExpress.enabled }}
---
apiVersion: v1
kind: Service
metadata:
name: mongo-express-service
namespace: {{ .Values.namespace }}
labels:
{{- include "todo-app.labels" . | nindent 4 }}
app: mongo-express
{{- with .Values.mongoExpress.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.mongoExpress.service.type }}
selector:
app: mongo-express
ports:
- port: {{ .Values.mongoExpress.service.port }}
targetPort: {{ .Values.mongoExpress.port }}
{{- if and (eq .Values.mongoExpress.service.type "NodePort") .Values.mongoExpress.service.nodePort }}
nodePort: {{ .Values.mongoExpress.service.nodePort }}
{{- end }}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongo-express
namespace: {{ .Values.namespace }}
labels:
{{- include "todo-app.labels" . | nindent 4 }}
app: mongo-express
spec:
replicas: {{ .Values.mongoExpress.replicas }}
selector:
matchLabels:
app: mongo-express
template:
metadata:
labels:
app: mongo-express
spec:
containers:
- name: mongo-express
image: {{ .Values.mongoExpress.image }}
ports:
- containerPort: {{ .Values.mongoExpress.port }}
env:
- name: ME_CONFIG_MONGODB_URL
value: "mongodb://mongodb-service:27017"
- name: ME_CONFIG_BASICAUTH_USERNAME
value: {{ .Values.mongoExpress.username | quote }}
- name: ME_CONFIG_BASICAUTH_PASSWORD
value: {{ .Values.mongoExpress.password | quote }}
resources:
{{- toYaml .Values.mongoExpress.resources | nindent 10 }}
{{- end }}Step 7: Create Environment-Specific Values Files
7.1 Docker Desktop Values
Create values-docker-desktop.yaml:
# Docker Desktop environment configuration
# Use Docker Hub image
image:
repository: larsappel/todo-app
tag: latest
# MongoDB storage - use hostpath
mongodb:
storage:
storageClass: hostpath
# WebApp service - NodePort for local access
webapp:
service:
type: NodePort
nodePort: 30080
# Mongo Express service - NodePort for local access
mongoExpress:
service:
type: NodePort
nodePort: 30081
# Don't create StorageClass (use built-in hostpath)
storageClass:
enabled: false7.2 EKS with Docker Hub Values
Create values-eks-dockerhub.yaml:
# EKS environment with Docker Hub image
# Use Docker Hub image
image:
repository: larsappel/todo-app
tag: latest
# MongoDB storage - use EBS
mongodb:
storage:
storageClass: ebs-sc
# WebApp service - LoadBalancer with AWS annotations
webapp:
service:
type: LoadBalancer
annotations:
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
# Mongo Express service - LoadBalancer with AWS annotations
mongoExpress:
service:
type: LoadBalancer
annotations:
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
# Create EBS StorageClass
storageClass:
enabled: true
name: ebs-sc
provisioner: ebs.csi.eks.amazonaws.com
volumeBindingMode: WaitForFirstConsumer
parameters:
type: gp3
encrypted: "true"7.3 EKS with ECR Values
Create values-eks-ecr.yaml:
# EKS environment with ECR private registry
# Use ECR image
image:
repository: 880731366811.dkr.ecr.eu-west-1.amazonaws.com/todo-app
tag: latest
# MongoDB storage - use EBS
mongodb:
storage:
storageClass: ebs-sc
# WebApp service - LoadBalancer with AWS annotations
webapp:
service:
type: LoadBalancer
annotations:
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
# Mongo Express service - LoadBalancer with AWS annotations
mongoExpress:
service:
type: LoadBalancer
annotations:
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
# Create EBS StorageClass
storageClass:
enabled: true
name: ebs-sc
provisioner: ebs.csi.eks.amazonaws.com
volumeBindingMode: WaitForFirstConsumer
parameters:
type: gp3
encrypted: "true"Step 8: Validate and Preview Helm Chart
8.1 Lint the Chart
cd /path/to/todo-app-chart
helm lint .Expected output:
==> Linting .
[INFO] Chart.yaml: icon is recommended
1 chart(s) linted, 0 chart(s) failed8.2 Preview Rendered Templates
For Docker Desktop:
helm template my-todo-app . -f values-docker-desktop.yamlFor EKS with Docker Hub:
helm template my-todo-app . -f values-eks-dockerhub.yamlFor EKS with ECR:
helm template my-todo-app . -f values-eks-ecr.yamlThis shows exactly what YAML will be deployed.
8.3 Dry Run
# Dry run for Docker Desktop
helm install my-todo-app . -f values-docker-desktop.yaml --dry-run --debugStep 9: Deploy to Docker Desktop
9.1 Switch Context
kubectl config use-context docker-desktop9.2 Install Chart
cd /path/to/todo-app-chart
helm install todo-app-local . -f values-docker-desktop.yamlExpected output:
NAME: todo-app-local
LAST DEPLOYED: ...
NAMESPACE: default
STATUS: deployed
REVISION: 19.3 Verify Deployment
# List Helm releases
helm list
# Check resources
kubectl get all -n todo-app
# Check PVC
kubectl get pvc -n todo-app9.4 Wait for Pods
kubectl wait --for=condition=ready pod -l app=mongodb -n todo-app --timeout=180s
kubectl wait --for=condition=ready pod -l app=todo-webapp -n todo-app --timeout=60s9.5 Test Application
Todo App:
curl http://localhost:30080/api/todosMongo Express:
http://localhost:30081Login: admin / pass
Step 10: Deploy to EKS with Docker Hub
10.1 Switch to EKS Context
kubectl config use-context <your-eks-context>10.2 Install Chart
cd /path/to/todo-app-chart
helm install todo-app-eks . -f values-eks-dockerhub.yaml10.3 Monitor Deployment
# Watch pods
kubectl get pods -n todo-app -w
# Check services
kubectl get svc -n todo-app10.4 Get LoadBalancer URLs
# WebApp URL
kubectl get svc todo-webapp-service -n todo-app -o jsonpath='{.status.loadBalancer.ingress[0].hostname}'
# Mongo Express URL
kubectl get svc mongo-express-service -n todo-app -o jsonpath='{.status.loadBalancer.ingress[0].hostname}'10.5 Test from Internet
WEBAPP_URL=$(kubectl get svc todo-webapp-service -n todo-app -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
curl http://${WEBAPP_URL}/api/todosStep 11: Upgrade to ECR Image
11.1 Upgrade Release
helm upgrade todo-app-eks . -f values-eks-ecr.yamlWhat happens:
- Helm calculates diff between current and desired state
- Updates only changed resources
- Keeps revision history for rollback
11.2 Check Revision History
helm history todo-app-eksOutput:
REVISION UPDATED STATUS CHART DESCRIPTION
1 ... superseded todo-app-1.0.0 Install complete
2 ... deployed todo-app-1.0.0 Upgrade complete11.3 Verify Image Changed
kubectl describe deployment todo-webapp -n todo-app | grep Image:Should show ECR image URL.
Step 12: Helm Release Management
12.1 View Release Status
helm status todo-app-eksShows current state, resources, and notes.
12.2 Rollback to Previous Version
# Rollback to revision 1 (Docker Hub image)
helm rollback todo-app-eks 112.3 Get Values from Release
# Show all values used in current release
helm get values todo-app-eks
# Show all values including defaults
helm get values todo-app-eks --all12.4 Uninstall Release
# Delete release (keeps history)
helm uninstall todo-app-eks
# Delete release and purge history
helm uninstall todo-app-eks --purgeStep 13: Advanced Helm Features
13.1 Override Values via CLI
# Change replica count on the fly
helm install todo-app . \
-f values-docker-desktop.yaml \
--set webapp.replicas=3 \
--set mongoExpress.enabled=false13.2 Use Multiple Values Files
# Combine base + environment + custom overrides
helm install todo-app . \
-f values.yaml \
-f values-eks-dockerhub.yaml \
-f values-custom.yamlLater files override earlier ones.
13.3 Template Functions
Check if a value is set:
{{- if .Values.webapp.ingress.enabled }}
# Include ingress resource
{{- end }}Default values:
replicas: {{ .Values.webapp.replicas | default 2 }}Loops:
{{- range .Values.initJob.todos }}
- id: {{ .id }}
name: {{ .name }}
{{- end }}13.4 Chart Dependencies
Add to Chart.yaml:
dependencies:
- name: mongodb
version: "13.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: mongodb.enabledThen:
helm dependency update
helm install todo-app .Step 14: Compare Helm vs Kustomize
Side-by-Side Comparison
Same task - Change image tag:
Kustomize:
# In kustomization.yaml
images:
- name: todo-app
newName: larsappel/todo-app
newTag: v2.0.0 # Manual edit neededHelm:
# Command line - no file edit
helm upgrade todo-app . --set image.tag=v2.0.0Same task - Enable/disable Mongo Express:
Kustomize:
# Need to manually edit kustomization.yaml
# Comment out mongo-express resourcesHelm:
# Single flag
helm upgrade todo-app . --set mongoExpress.enabled=falseSame task - Different environments:
Kustomize:
kubectl apply -k overlays/docker-desktop
kubectl apply -k overlays/eks-dockerhub
kubectl apply -k overlays/eks-ecrHelm:
helm install todo-app . -f values-docker-desktop.yaml
helm install todo-app . -f values-eks-dockerhub.yaml
helm install todo-app . -f values-eks-ecr.yamlStep 15: Troubleshooting
Chart Won’t Install
Symptom: Error: YAML parse error
Check:
# Validate YAML syntax
helm lint .
# Use --debug to see rendered templates
helm install todo-app . --debug --dry-runTemplate Rendering Issues
Symptom: Variables not replacing
Check:
# Preview exact output
helm template todo-app . -f values-docker-desktop.yaml > output.yaml
cat output.yamlCommon issues:
- Wrong indentation in templates
- Missing values in values file
- Incorrect template syntax
{{ }}vs{{- }}
Upgrade Fails
Symptom: Error: UPGRADE FAILED
Check:
# See what changed
helm diff upgrade todo-app . -f values-eks-ecr.yaml
# View current values
helm get values todo-app
# Rollback if needed
helm rollback todo-appRelease Stuck
Symptom: Helm install hangs
Check:
# See Kubernetes events
kubectl get events -n todo-app --sort-by='.lastTimestamp'
# Check pod status
kubectl get pods -n todo-app
kubectl describe pod <pod-name> -n todo-appStep 16: Cleanup
Delete Helm Releases
Docker Desktop:
helm uninstall todo-app-local
kubectl delete namespace todo-appEKS:
helm uninstall todo-app-eks
kubectl delete namespace todo-app
kubectl delete storageclass ebs-scKey Takeaways
Helm Benefits
β Templating Power: Go templates with functions, loops, conditionals β Reusability: Package once, deploy anywhere β Release Management: Built-in versioning, rollback, history β Dependency Management: Declare chart dependencies β Community: Massive library of public charts β Packaging: Distribute charts as .tgz archives
When to Use Helm
β Good for:
- Complex applications with many environments
- Need to distribute/share applications
- Want built-in rollback capability
- Need dependency management
- Deploying from CI/CD pipelines
- Using community charts
β Overkill for:
- Very simple deployments
- Only deploying to one environment
- Team prefers plain YAML
- Don’t need templating
Helm vs Kustomize Summary
| Aspect | Kustomize | Helm |
|---|---|---|
| Learning curve | Lower | Higher |
| Flexibility | Good | Excellent |
| Tooling | Built into kubectl | Separate tool |
| Community | Growing | Massive |
| Best for | Simple to medium | Medium to complex |
You can use both! Many teams use Kustomize for simple apps and Helm for complex ones.
Next Steps
Now that you’ve mastered Helm, you can:
- Publish charts - Create a Helm repository (GitHub Pages, ChartMuseum)
- Use public charts - Leverage community charts (Bitnami, etc.)
- Chart hooks - Pre/post install/upgrade actions
- GitOps with ArgoCD - Automate Helm deployments from Git
- Helmfile - Manage multiple Helm releases declaratively
Congratulations! π
You’ve successfully:
- β Created a production-ready Helm chart
- β Templated Kubernetes manifests with Go templates
- β Deployed to 3 different environments with values files
- β Managed releases with install, upgrade, rollback
- β Understood when to use Helm vs Kustomize
You’re now ready for production Helm deployments and GitOps!
Reference Commands
Chart Development
helm create <chart-name> # Create new chart
helm lint . # Validate chart
helm template <name> . # Preview rendered templates
helm install <name> . --dry-run # Test without installingRelease Management
helm install <name> . -f values.yaml # Install release
helm upgrade <name> . -f values.yaml # Upgrade release
helm rollback <name> <revision> # Rollback to revision
helm uninstall <name> # Delete releaseRelease Information
helm list # List all releases
helm status <name> # Show release status
helm history <name> # Show revision history
helm get values <name> # Get current values
helm get manifest <name> # Get deployed manifestChart Repository
helm repo add <name> <url> # Add chart repository
helm repo update # Update repositories
helm search repo <chart> # Search for charts
helm pull <chart> # Download chart