How to Deploy Helm Chart
How to Deploy Helm Chart Helm is the package manager for Kubernetes, designed to simplify the deployment, management, and scaling of applications on Kubernetes clusters. A Helm chart is a collection of templated Kubernetes manifest files bundled together with metadata that defines how an application should be installed and configured. Deploying a Helm chart allows DevOps teams to automate complex
How to Deploy Helm Chart
Helm is the package manager for Kubernetes, designed to simplify the deployment, management, and scaling of applications on Kubernetes clusters. A Helm chart is a collection of templated Kubernetes manifest files bundled together with metadata that defines how an application should be installed and configured. Deploying a Helm chart allows DevOps teams to automate complex deployments with consistency, repeatability, and version control—critical for modern cloud-native environments.
Before Helm, deploying applications on Kubernetes required manually writing and managing dozens of YAML files for deployments, services, config maps, secrets, and more. This approach was error-prone, difficult to version, and hard to share across teams. Helm solved these problems by introducing charts—reusable, parameterized templates that can be customized for different environments (development, staging, production) with a single command.
Today, Helm is the de facto standard for application packaging in Kubernetes ecosystems. Over 80% of organizations using Kubernetes rely on Helm to deploy stateful and stateless applications—from databases and message queues to web services and machine learning pipelines. Whether you're managing a small cluster or a multi-cluster enterprise platform, mastering Helm chart deployment is essential for operational efficiency and scalability.
This guide provides a comprehensive, step-by-step walkthrough on how to deploy Helm charts—from setting up your environment to troubleshooting common issues. You’ll learn best practices, explore real-world examples, and gain access to essential tools and resources that will elevate your Kubernetes deployment workflow.
Step-by-Step Guide
Prerequisites
Before deploying a Helm chart, ensure your environment meets the following requirements:
- A running Kubernetes cluster (minikube, kind, EKS, GKE, AKS, or any other distribution)
- kubectl installed and configured to communicate with your cluster
- Helm CLI installed (version 3.0 or higher recommended)
To verify your setup, run the following commands in your terminal:
kubectl version --short
helm version
You should see output indicating both Kubernetes and Helm are installed and properly configured. If kubectl cannot connect to your cluster, use kubectl config current-context to check your active context and switch if necessary with kubectl config use-context <context-name>.
Step 1: Add a Helm Repository
Helm charts are distributed through repositories, similar to package managers like apt or npm. The most popular public repository is Bitnami, which hosts over 100 production-ready charts for databases, messaging systems, monitoring tools, and more. Another widely used source is the stable repository (now deprecated but still referenced in legacy guides), and the official Kubernetes Charts repository hosted by the Helm community.
To add the Bitnami repository, run:
helm repo add bitnami https://charts.bitnami.com/bitnami
Verify the repository was added successfully:
helm repo list
You should see output similar to:
NAME URL
bitnami https://charts.bitnami.com/bitnami
Always update your local repository cache after adding a new repo:
helm repo update
This ensures you have the latest chart versions available for deployment.
Step 2: Search for a Helm Chart
Once the repository is added, you can search for available charts. For example, to find a Redis chart:
helm search repo bitnami/redis
This returns a list of matching charts with their versions and descriptions:
NAME CHART VERSION APP VERSION DESCRIPTION
bitnami/redis 17.5.2 7.2.5 Redis is an open source key-value store that...
bitnami/redis-cluster 10.1.2 7.2.5 Redis Cluster is an implementation of Redis...
Use the helm show chart <chart-name> command to inspect the chart’s metadata, including dependencies, values schema, and supported Kubernetes versions:
helm show chart bitnami/redis
Step 3: Inspect Chart Values
Every Helm chart includes a values.yaml file that defines default configuration parameters. These values control aspects like image tags, resource limits, replica counts, persistence settings, and network policies.
To view the default values for the Redis chart:
helm show values bitnami/redis
This outputs a large YAML structure. For example:
image:
registry: docker.io
repository: bitnami/redis
tag: 7.2.5-debian-12-r0
pullPolicy: IfNotPresent
replicaCount: 1
resources:
limits:
cpu: 250m
memory: 256Mi
requests:
cpu: 250m
memory: 256Mi
persistence:
enabled: true
storageClass: "standard"
accessModes:
- ReadWriteOnce
size: 8Gi
Understanding these defaults is critical. For production deployments, you’ll likely override values such as resource limits, persistence storage class, and security settings.
Step 4: Customize Values with a Custom values.yaml File
Instead of overriding values via command-line flags (which can become unwieldy), create a custom values-production.yaml file to manage environment-specific configurations.
Create a file named redis-values-prod.yaml:
replicaCount: 3
image:
tag: 7.2.5-debian-12-r0
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 500m
memory: 1Gi
persistence:
enabled: true
storageClass: "gp2"
AWS EBS
size: 20Gi
auth:
enabled: true
password: "your-strong-password-123"
service:
type: LoadBalancer
ports:
redis: 6379
metrics:
enabled: true
serviceMonitor:
enabled: true
This configuration scales Redis to three replicas, increases memory limits, enables authentication, exposes the service via a cloud load balancer, and enables Prometheus metrics for monitoring.
Step 5: Install the Helm Chart
Now that you’ve customized your values, deploy the chart using the helm install command:
helm install my-redis bitnami/redis -f redis-values-prod.yaml --namespace redis-system --create-namespace
Breakdown of the command:
my-redis: The release name (arbitrary, but must be unique per namespace)bitnami/redis: The chart name-f redis-values-prod.yaml: Applies your custom values file--namespace redis-system: Deploys into a dedicated namespace (recommended for isolation)--create-namespace: Creates the namespace if it doesn’t exist
Helm will output a summary of the deployment:
NAME: my-redis
LAST DEPLOYED: Thu Apr 4 10:30:15 2024
NAMESPACE: redis-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Please be patient while the chart is being deployed
Redis can be accessed via port 6379 on the following DNS names from within your cluster:
my-redis-redis-headless.redis-system.svc.cluster.local for read/write operations
my-redis-redis.redis-system.svc.cluster.local for read-only operations
To connect to your Redis server:
1. Run a Redis pod that you can use as a client:
kubectl run my-redis-client --rm --tty -i --restart='Never' --namespace redis-system --image docker.io/bitnami/redis:7.2.5-debian-12-r0 --command -- bash
2. Connect using the Redis CLI:
redis-cli -h my-redis-redis.redis-system.svc.cluster.local
Step 6: Verify Deployment
After installation, verify that all resources were created successfully:
kubectl get pods -n redis-system
You should see three Redis pods (if replicaCount=3) in Running status:
NAME READY STATUS RESTARTS AGE
my-redis-redis-0 1/1 Running 0 2m
my-redis-redis-1 1/1 Running 0 2m
my-redis-redis-2 1/1 Running 0 2m
Check the service:
kubectl get svc -n redis-system
Look for a service of type LoadBalancer with an external IP assigned (if on a cloud provider):
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-redis-redis LoadBalancer 10.100.120.12 35.200.12.34 6379:31234/TCP 3m
my-redis-redis-headless ClusterIP None 6379/TCP 3m
Check the Helm release status:
helm list -n redis-system
Confirm the release is in deployed state.
Step 7: Upgrade and Rollback
Helm’s versioning system allows you to upgrade and rollback releases safely. Suppose you need to update Redis to a newer version or change a configuration.
First, update your redis-values-prod.yaml file to change the image tag to 7.2.6-debian-12-r0.
Then, upgrade the release:
helm upgrade my-redis bitnami/redis -f redis-values-prod.yaml -n redis-system
Helm will perform a rolling update and show progress:
Release "my-redis" has been upgraded. Happy Helming!
NAME: my-redis
LAST DEPLOYED: Thu Apr 4 11:05:22 2024
NAMESPACE: redis-system
STATUS: deployed
REVISION: 2
To view the history of releases:
helm history my-redis -n redis-system
You’ll see:
REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
1 Thu Apr 4 10:30:15 2024 deployed redis-17.5.2 7.2.5 Install complete
2 Thu Apr 4 11:05:22 2024 deployed redis-17.5.2 7.2.6 Upgrade complete
If the upgrade introduces issues, rollback to the previous revision:
helm rollback my-redis 1 -n redis-system
Helm will revert the deployment to revision 1, preserving your original configuration.
Step 8: Uninstall the Chart
To remove the entire Helm release and all associated resources:
helm uninstall my-redis -n redis-system
This deletes all Kubernetes objects created by the chart—deployments, services, config maps, secrets, and persistent volume claims (if not set to retain).
By default, Helm retains release history. To purge all traces including history:
helm uninstall my-redis -n redis-system --purge
Note: The --purge flag is deprecated in Helm 3; instead, use --keep-history to retain history. To remove history entirely, use helm uninstall and then delete the release history manually with helm history and helm delete if needed.
Best Practices
Use Dedicated Namespaces
Always deploy Helm charts into dedicated namespaces. This isolates applications, simplifies RBAC configuration, and prevents naming conflicts. For example, use redis-system, postgresql-production, or monitoring instead of deploying everything into default.
Version Control Your Values Files
Treat your values.yaml files as code. Store them in Git repositories alongside your application code or infrastructure-as-code (IaC) projects. Use branching strategies (e.g., dev/prod branches) to manage environment-specific configurations. This ensures auditability, peer review, and rollback capabilities.
Pin Chart Versions
Never use latest in production. Always specify exact chart versions in your CI/CD pipelines. For example:
helm install my-app bitnami/nginx --version 12.3.4
Use helm repo update and helm search repo --versions to check available versions before deployment.
Use Helmfile for Multi-Chart Management
For complex applications requiring multiple charts (e.g., a microservice stack with Redis, PostgreSQL, Kafka, and Grafana), use Helmfile. Helmfile is a declarative tool that lets you define multiple Helm releases in a single YAML file:
releases:
- name: redis
namespace: redis-system
chart: bitnami/redis
version: 17.5.2
values:
- redis-values-prod.yaml
- name: postgres
namespace: db-system
chart: bitnami/postgresql
version: 12.1.0
values:
- postgres-values-prod.yaml
Deploy with: helmfile sync
Enable Resource Limits and Requests
Always define CPU and memory limits and requests in your values files. This prevents resource starvation and enables Kubernetes to schedule pods efficiently. For production workloads, use resource quotas and LimitRanges at the namespace level.
Secure Your Deployments
- Enable authentication where supported (e.g., Redis, PostgreSQL)
- Use secrets for passwords and API keys—never hardcode them in values files
- Set
securityContextto run containers as non-root users - Apply network policies to restrict traffic between services
Monitor and Log
Integrate Helm-deployed applications with monitoring tools like Prometheus and Grafana. Enable metrics endpoints in charts (e.g., metrics.enabled: true). Use Fluentd or Loki for centralized logging. Add liveness and readiness probes to ensure application health.
Test Charts Before Production
Use Helm’s template command to render templates locally without installing:
helm template my-test-release bitnami/redis -f redis-values-prod.yaml
This outputs the final Kubernetes manifests. Review them for errors, misconfigurations, or unintended defaults. Use tools like KubeLinter or Checkov to scan generated manifests for security and compliance issues.
Use Helmfile or Argo CD for GitOps
For enterprise environments, adopt GitOps practices using tools like Argo CD or Flux. These tools continuously sync your Git repository with your cluster state, automatically deploying Helm charts when changes are pushed. This eliminates manual helm install commands and enforces consistency across environments.
Tools and Resources
Essential Helm CLI Commands
Master these core Helm commands for daily operations:
helm repo add– Add a new chart repositoryhelm repo update– Refresh local chart indexhelm search repo– Search for chartshelm show chart– View chart metadatahelm show values– View default valueshelm install– Deploy a charthelm upgrade– Update a releasehelm rollback– Revert to a previous revisionhelm list– List releaseshelm history– View release historyhelm uninstall– Remove a releasehelm template– Render templates locally
Popular Helm Repositories
Use these trusted public repositories for production-ready charts:
- Bitnami – https://github.com/bitnami/charts – Comprehensive, well-maintained, and secure
- Argo CD – https://argoproj.github.io/argo-helm – For GitOps tooling
- Prometheus Community – https://prometheus-community.github.io/helm-charts – Monitoring stack
- Jetstack – https://charts.jetstack.io – Cert-Manager, Vault, and Kubernetes security tools
- HashiCorp – https://helm.releases.hashicorp.com – Vault, Consul, Nomad
Chart Validation and Linting Tools
- Helm Lint – Built-in:
helm lint ./my-chart - KubeLinter – Static analysis for Kubernetes manifests: https://github.com/stackrox/kube-linter
- Checkov – Infrastructure-as-code scanning: https://www.checkov.io
- Yamllint – Validates YAML syntax: https://github.com/adrienverge/yamllint
Chart Development Tools
If you’re creating your own Helm charts, use these tools:
- helm create – Generates a boilerplate chart structure
- ChartMuseum – Self-hosted Helm chart repository
- Chartpress – Automates chart versioning with Git tags
- helm-unittest – Unit testing framework for Helm charts
Documentation and Learning Resources
- Helm Documentation – https://helm.sh/docs
- Helm Best Practices Guide – https://helm.sh/docs/chart_best_practices
- Awesome Helm – https://github.com/helm/awesome-helm – Curated list of tools, tutorials, and charts
- Kubernetes Helm Tutorial (DigitalOcean) – https://www.digitalocean.com/community/tutorials/how-to-use-helm-to-manage-applications-on-kubernetes
- YouTube: Helm 101 by TechWorld with Nana – Practical walkthroughs
Real Examples
Example 1: Deploying a WordPress Site with MySQL
Deploying a full-stack application like WordPress with a MySQL backend is a common use case. Here’s how to do it with Helm:
Add the Bitnami repository:
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
Create a wordpress-values.yaml:
wordpress:
username: admin
password: "secure-wordpress-password-123"
email: admin@example.com
service:
type: LoadBalancer
port: 80
mariadb:
enabled: true
auth:
rootPassword: "secure-mariadb-root-password"
database: wordpress_db
username: wp_user
password: "wp_user_password_456"
persistence:
enabled: true
size: 10Gi
Install:
helm install my-wordpress bitnami/wordpress -f wordpress-values.yaml --namespace wordpress-system --create-namespace
After deployment, get the external IP:
kubectl get svc -n wordpress-system
Visit the external IP in your browser to complete the WordPress setup. All resources (deployment, service, PVC, config maps) are managed by Helm. To upgrade WordPress, simply update the image tag in values and run helm upgrade.
Example 2: Deploying Prometheus and Grafana for Monitoring
Set up a full observability stack using Helm charts from the Prometheus community:
Add the repo:
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
Create prometheus-values.yaml:
server:
persistence:
enabled: true
size: 20Gi
resources:
limits:
cpu: 1000m
memory: 2Gi
alertmanager:
enabled: true
grafana:
enabled: true
adminPassword: "admin123"
service:
type: LoadBalancer
persistence:
enabled: true
size: 5Gi
Install:
helm install monitoring prometheus-community/kube-prometheus-stack -f prometheus-values.yaml --namespace monitoring --create-namespace
Access Grafana via the external IP and log in with the admin password. Prometheus will automatically scrape metrics from your cluster nodes and pods. This entire stack is now version-controlled, upgradeable, and reproducible across environments.
Example 3: Custom Helm Chart for Internal Microservice
Suppose your team develops a Python-based microservice called api-gateway. Create a custom Helm chart:
helm create api-gateway
This generates a folder structure:
api-gateway/
├── Chart.yaml
├── values.yaml
├── charts/
├── templates/
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ └── ...
└── .helmignore
Edit templates/deployment.yaml to use your container image:
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
ports:
- containerPort: {{ .Values.service.port }}
resources:
limits:
cpu: {{ .Values.resources.limits.cpu }}
memory: {{ .Values.resources.limits.memory }}
requests:
cpu: {{ .Values.resources.requests.cpu }}
memory: {{ .Values.resources.requests.memory }}
Update values.yaml:
image:
repository: your-registry.com/api-gateway
tag: v1.2.3
pullPolicy: IfNotPresent
service:
port: 8080
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 250m
memory: 256Mi
Test locally:
helm template api-gateway . --debug
Package and push to ChartMuseum:
helm package api-gateway
helm push api-gateway-0.1.0.tgz oci://your-chart-repo
Now your team can deploy the internal service with:
helm install api-gateway your-registry/api-gateway --namespace api-gateway-system
FAQs
What is the difference between Helm 2 and Helm 3?
Helm 3 removed Tiller, the server-side component used in Helm 2. This improved security by eliminating a central control plane and allowed Helm to use Kubernetes RBAC directly. Helm 3 also introduced better chart structure, OCI registry support, and improved dependency management. All new deployments should use Helm 3.
Can I use Helm with any Kubernetes cluster?
Yes. Helm works with any Kubernetes cluster, whether it’s self-hosted (kubeadm), managed (EKS, GKE, AKS), or local (minikube, kind). As long as kubectl can communicate with the cluster, Helm can deploy charts.
How do I update a Helm chart to a new version?
Use helm upgrade <release-name> <chart-name> --version <new-version>. Always test new versions in a non-production environment first. Check the chart’s changelog for breaking changes before upgrading.
What happens if I delete a Helm release?
By default, Helm deletes all Kubernetes resources created by the chart. However, persistent volumes (PVCs) are not deleted unless explicitly configured. Use helm uninstall --keep-history to retain release history for auditing.
How do I share my custom Helm charts with my team?
Package your chart using helm package and host it in a private Helm repository like ChartMuseum, Harbor, or GitHub Packages. Alternatively, store the chart directory in your Git repository and use helm install ./path/to/chart directly from the repo.
Is Helm secure?
Helm 3 is secure by design, using Kubernetes RBAC and avoiding server-side components. However, security depends on how you use it. Always validate charts from unknown sources, use signed charts with Helm’s content trust feature, and scan for vulnerabilities in container images and values files.
Can Helm deploy to multiple clusters at once?
Helm itself doesn’t manage multiple clusters, but tools like Helmfile, Argo CD, or Flux can. These tools read a single configuration and apply it across multiple clusters by switching kubeconfigs or using cluster context selectors.
Why is my Helm release stuck in “pending-install” or “pending-upgrade”?
This usually indicates a failure in one of the Kubernetes resources. Check logs with kubectl get events -n <namespace> and kubectl describe pod <pod-name>. Common causes include insufficient resources, image pull errors, or misconfigured secrets.
Do I need to use Helm if I’m using Kubernetes Operators?
Not necessarily. Operators are designed to manage complex stateful applications (e.g., databases, Kafka) with custom controllers. Helm is ideal for stateless apps and simple deployments. Many operators are distributed as Helm charts, so you can use both together.
Conclusion
Deploying Helm charts is a foundational skill for modern Kubernetes operations. By abstracting complex application configurations into reusable, version-controlled templates, Helm empowers teams to deploy applications faster, more reliably, and with fewer errors. From installing a simple Redis instance to orchestrating multi-tier microservice architectures, Helm provides the tooling to manage complexity at scale.
This guide has walked you through the entire lifecycle of Helm chart deployment—from setting up your environment and selecting the right chart, to customizing values, upgrading releases, and troubleshooting issues. You’ve explored best practices for security, scalability, and maintainability, and seen real-world examples of deploying WordPress, Prometheus, and custom internal services.
As Kubernetes adoption continues to grow, Helm remains the most widely used deployment tool in the ecosystem. Whether you’re a developer, DevOps engineer, or platform operator, mastering Helm chart deployment will significantly enhance your productivity and the reliability of your applications.
Remember: treat your Helm charts like code. Version them, test them, secure them, and automate their deployment. Combine Helm with GitOps tools like Argo CD to achieve true continuous delivery. With the right practices, Helm becomes not just a deployment tool—but the cornerstone of your cloud-native infrastructure.