Deploy with Helm — End-to-End Lab
Complete guided lab: add repos, install charts, customize values, upgrade, rollback, and manage the full release lifecycle.
🧒 Simple Explanation (ELI5)
This is your hands-on kitchen session. You've learned the recipes (theory). Now you'll actually cook: add a chart repository, install a real application, change its settings, upgrade it, break it intentionally, roll it back, and clean everything up. Every command you'll need in real life, practiced step by step.
🔧 Prerequisites
- A running Kubernetes cluster (minikube, kind, Docker Desktop, or a cloud cluster)
- Helm 3.x installed (
helm version) - kubectl configured and connected (
kubectl cluster-info)
⌨️ Lab 1: Deploy NGINX from Bitnami
Step 1: Add Repository
bash
# Add the Bitnami chart repository helm repo add bitnami https://charts.bitnami.com/bitnami # Update repo index helm repo update # Search for nginx helm search repo bitnami/nginx helm search repo bitnami/nginx --versions | head -10
Step 2: Inspect Before Installing
bash
# See all configurable values helm show values bitnami/nginx | head -60 # See chart metadata helm show chart bitnami/nginx # See the README helm show readme bitnami/nginx | head -40
Step 3: Install with Default Values
bash
# Create namespace and install helm install my-nginx bitnami/nginx \ --namespace lab \ --create-namespace # Check release helm list -n lab helm status my-nginx -n lab # Watch pods kubectl get pods -n lab -w # Wait for READY 1/1, then Ctrl+C
Step 4: Access the Application
bash
# Port-forward to access locally kubectl port-forward svc/my-nginx -n lab 8080:80 & # Test curl http://localhost:8080 # Should see NGINX welcome page # Stop port-forward kill %1
Step 5: Customize with Values
bash
# Upgrade with custom values helm upgrade my-nginx bitnami/nginx \ --namespace lab \ --set replicaCount=3 \ --set service.type=ClusterIP # Verify 3 replicas kubectl get pods -n lab kubectl get deploy -n lab # Check what values are set helm get values my-nginx -n lab
Step 6: Check History and Rollback
bash
# View release history helm history my-nginx -n lab # Rollback to revision 1 (original install) helm rollback my-nginx 1 -n lab # Verify replica count is back to 1 kubectl get pods -n lab helm history my-nginx -n lab # Now shows revision 3 (rollback)
Step 7: Clean Up
bash
# Uninstall helm uninstall my-nginx -n lab # Verify everything is gone kubectl get all -n lab helm list -n lab
⌨️ Lab 2: Deploy a Custom Chart
Step 1: Create and Customize
bash
# Scaffold
helm create mywebapp
cd mywebapp
# Edit values.yaml — change these:
# replicaCount: 2
# image.tag: "1.25-alpine"
# service.port: 8080
# Add a ConfigMap
cat > templates/configmap.yaml <<'EOF'
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "mywebapp.fullname" . }}-config
labels:
{{- include "mywebapp.labels" . | nindent 4 }}
data:
APP_VERSION: {{ .Chart.AppVersion | quote }}
ENVIRONMENT: {{ .Values.environment | default "development" | quote }}
EOF
Step 2: Validate
bash
# Lint helm lint . # Render templates (check output for errors) helm template myrelease . # Render just the ConfigMap helm template myrelease . -s templates/configmap.yaml # Dry-run against cluster helm install myrelease . --dry-run --debug -n lab --create-namespace
Step 3: Deploy and Test
bash
# Install helm install myrelease . -n lab --create-namespace # Verify all resources kubectl get all -n lab kubectl get configmap -n lab # Read ConfigMap kubectl get configmap myrelease-mywebapp-config -n lab -o yaml # Run built-in test helm test myrelease -n lab # Upgrade with custom environment helm upgrade myrelease . -n lab --set environment=staging # Verify ConfigMap changed kubectl get configmap myrelease-mywebapp-config -n lab -o yaml | grep ENVIRONMENT
Step 4: Package
bash
cd .. helm package mywebapp/ ls *.tgz # Install from package helm install frompackage mywebapp-0.1.0.tgz -n lab2 --create-namespace # Cleanup helm uninstall myrelease -n lab helm uninstall frompackage -n lab2
⌨️ Lab 3: Multi-Service with Dependencies
bash
# Create a chart with Redis dependency
helm create fullstack
cd fullstack
# Add dependency to Chart.yaml
cat >> Chart.yaml <<EOF
dependencies:
- name: redis
version: "17.15.0"
repository: "https://charts.bitnami.com/bitnami"
condition: redis.enabled
EOF
# Configure Redis in values.yaml
cat >> values.yaml <<EOF
redis:
enabled: true
architecture: standalone
auth:
enabled: false
EOF
# Download dependency
helm dependency update .
ls charts/ # redis-17.15.0.tgz
# Install full stack
helm install fullstack . -n lab3 --create-namespace --timeout 5m
# Verify both app and Redis are running
kubectl get pods -n lab3
kubectl get svc -n lab3
# Disable Redis
helm upgrade fullstack . -n lab3 --set redis.enabled=false
kubectl get pods -n lab3 # Redis pods gone
# Re-enable
helm upgrade fullstack . -n lab3 --reuse-values --set redis.enabled=true
# Cleanup
helm uninstall fullstack -n lab3
📋 Command Quick Reference
| Action | Command |
|---|---|
| Add repo | helm repo add <name> <url> |
| Search charts | helm search repo <keyword> |
| Inspect values | helm show values <chart> |
| Install | helm install <name> <chart> -n <ns> |
| Upgrade | helm upgrade <name> <chart> -n <ns> |
| Rollback | helm rollback <name> <rev> -n <ns> |
| History | helm history <name> -n <ns> |
| Get values | helm get values <name> -n <ns> |
| Test | helm test <name> -n <ns> |
| Uninstall | helm uninstall <name> -n <ns> |
| Lint | helm lint <chart-dir> |
| Template | helm template <name> <chart> |
| Package | helm package <chart-dir> |
📝 Summary
- Full lifecycle practiced: repo → install → customize → upgrade → rollback → uninstall
- Custom charts: scaffold → edit → lint → template → install → test → package
- Dependencies: declare → update → install → toggle with conditions
--atomic --wait --timeoutis the production deployment pattern- K8s readiness probes directly affect Helm's rollout behavior
- Every command you'll use daily is in the quick reference above