The Package Manager for Kubernetes
Helm has become an essential tool in the Kubernetes ecosystem, used by 70% of organizations in their cloud environments. As the official package manager for Kubernetes, Helm transforms complex application deployments from managing dozens of YAML files into a single, repeatable command. This guide will walk you through everything from Helm fundamentals to advanced practices for production deployments.
What is Helm and Why Does It Matter?
Helm is a templating engine and package manager that simplifies deploying applications on Kubernetes. A Helm Chart is a collection of pre-configured Kubernetes resources that define how an application should be deployed.
The core concepts are straightforward:
| Term | Definition |
|---|---|
| Chart | A Helm package containing all Kubernetes manifests needed to deploy an application |
| Release | An instance of a chart deployed in your cluster with a specific configuration |
| Repository | An HTTP server hosting downloadable Helm charts |
| Values | Configuration parameters you pass to the chart to customize the deployment |
Without Helm, deploying a complex application like WordPress requires managing separate YAML files for Deployments, Services, PersistentVolumeClaims, Ingress, and Secrets—often 15-25 files per service. With Helm, a single command handles everything.
Installation and Getting Started
Installing Helm
Install Helm on your preferred operating system:
macOS:
bash
brew install helm
Linux:
bash
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
Windows:
bash
choco install kubernetes-helm
Verify your installation:
bash
helm version
Adding Repositories
Helm repositories work like package registries. Add the Bitnami repository—one of the most trusted sources for production-ready charts:
bash
helm repo add bitnami https://charts.bitnami.com/bitnami helm repo update
Deploying WordPress with Helm
Deploying WordPress on Kubernetes demonstrates Helm’s power. With one command, you get a fully functional WordPress installation with a MariaDB database:
bash
helm install my-wordpress oci://registry-1.docker.io/bitnamicharts/wordpress
After deployment, retrieve your WordPress credentials:
bash
# Get the admin password
kubectl get secret my-wordpress -o jsonpath="{.data.wordpress-password}" | base64 -d
# Get the service URL
export SERVICE_IP=$(kubectl get svc my-wordpress --template "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}")
echo "WordPress URL: http://$SERVICE_IP/"
Customizing Deployments with Values
While the default installation works, real-world deployments require customization. Helm offers three ways to override default values:
1. Command-Line Overrides
For quick changes:
bash
helm install my-wordpress bitnami/wordpress \ --set wordpressBlogName="My Awesome Blog" \ --set wordpressUsername=admin
2. Custom Values File
For multiple overrides, create a custom-values.yaml file:
yaml
wordpressBlogName: My Awesome Blog
wordpressEmail: admin@example.com
replicaCount: 2
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
Then deploy with:
bash
helm install my-wordpress bitnami/wordpress -f custom-values.yaml
3. Local Chart Modification
Pull the chart locally and edit the built-in values.yaml:
bash
helm pull --untar bitnami/wordpress # Edit wordpress/values.yaml helm install my-wordpress ./wordpress
Managing Release Lifecycle
Helm provides robust lifecycle management that manual kubectl apply cannot match:
Upgrading
bash
helm upgrade my-wordpress bitnami/wordpress -f updated-values.yaml
Viewing History
bash
helm history my-wordpress
Rolling Back
bash
# Rollback to revision 1 helm rollback my-wordpress 1
This capability is critical for production environments. A rollback takes approximately 30 seconds with zero downtime.
Uninstalling
bash
helm uninstall my-wordpress
Advanced Configuration for Production
Resource Management
For production workloads, always set resource requests and limits. The Bitnami WordPress chart provides resourcesPreset values, but custom configuration is recommended for production:
yaml
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
External Database Support
For managed database services or shared database servers:
yaml
mariadb: enabled: false externalDatabase: host: myexternalhost user: myuser password: mypassword database: mydatabase port: 3306
Enabling Memcached for Performance
Cache database queries to improve website performance:
yaml
wordpressConfigureCache: true memcached: enabled: true
Ingress Configuration
yaml
ingress: enabled: true hostname: wordpress.example.com tls: true
Creating Your Own Charts
When you need to package your own applications, Helm provides a complete framework:
Generate Chart Structure
bash
helm create my-app
This creates:
text
my-app/ ├── Chart.yaml # Chart metadata ├── values.yaml # Default values ├── templates/ # Kubernetes templates │ ├── deployment.yaml │ ├── service.yaml │ ├── ingress.yaml │ └── _helpers.tpl # Helper functions └── charts/ # Dependencies
Best Practices for Chart Development
1. Separate Environment Values:
Create environment-specific values files:
text
values-dev.yaml values-staging.yaml values-prod.yaml
2. Limit Template Logic:
Keep templates clean and avoid complex conditionals. Templates should look like configuration, not application code.
3. Version Charts Semantically:
- Patch for fixes
- Minor for backward-compatible updates
- Major for breaking changes
4. Manage Secrets Externally:
Never store secrets in plain values files. Reference Kubernetes Secrets or use external secret managers.
bash
# Lint the chart helm lint my-app # Preview rendered templates helm template my-app ./my-app -f custom-values.yaml # Dry-run installation helm install my-app ./my-app --dry-run --debug
Helm and GitOps with ArgoCD
While Helm handles packaging and deployment, ArgoCD extends it with GitOps capabilities:
Helm alone: A developer runs helm upgrade from a CI/CD pipeline when code is pushed.
Helm + ArgoCD: ArgoCD monitors Git and automatically syncs the cluster to match the Git state. Manual changes are detected and reverted—the cluster is self-healing.
The combination creates a powerful workflow where promoting from staging to production is simply a Git operation—update the image tag in the production values file and merge the PR.
Common Pitfalls to Avoid
1. Not Committing Charts to Git:
When Helm tries to manage resources created with kubectl apply, it can’t track them. Always commit charts to Git.
2. Configuration Drift Across Environments:
Without Helm, maintaining three sets of near-identical YAML files for dev, staging, and production leads to drift. One chart with environment-specific values solves this.
3. Immutable Field Errors:spec.selector cannot be changed after creation. Plan for this in your templates.
4. Overloaded Templates:
Keep templates small and focused. Avoid deep nesting and hidden behavior.
Conclusion
Helm has become the standard for Kubernetes deployments for good reason. It eliminates the complexity of managing hundreds of YAML files, provides version-controlled rollbacks, and enables consistent deployments across environments.
Whether you’re deploying WordPress or your own applications, Helm transforms Kubernetes from a complex orchestration platform into a manageable, repeatable deployment system. Combined with GitOps practices using ArgoCD, it creates a complete, auditable deployment pipeline that scales with your organization.