How to Install Helm on Ubuntu 26.04 LTS (Complete Guide 2026)

how to install helm on ubuntu 26.04 lts step by step

Table of Contents

  1. What is Helm and Why You Need It
  2. Helm 2 vs Helm 3: The Critical Difference (Tiller is Gone)
  3. Prerequisites
  4. Method 1: Install via APT Repository (Recommended)
  5. Method 2: Install via Script (Quickest)
  6. Method 3: Install via Snap
  7. Method 4: Install Manually from Binary
  8. Verify the Installation
  9. Configure Shell Autocompletion
  10. Managing Helm Repositories
  11. Essential Helm Commands Cheatsheet
  12. Install Your First Application with Helm
  13. Upgrade, Rollback, and Uninstall
  14. Create Your First Helm Chart
  15. OCI Registry Support
  16. The helm diff Plugin: Preview Before Upgrade
  17. Helm in CI/CD Pipelines
  18. Helm 4.0: What’s Coming in September 2026
  19. Common Issues and Quick Fixes
  20. Next Steps

Every time you install something complex on Kubernetes — an ingress controller, a monitoring stack, a database — you’re managing dozens of YAML files that need to be applied in the right order with the right values. Change one environment (dev to staging to production) and you’re editing the same files in parallel, hoping they stay in sync. Helm solves this by treating Kubernetes applications as versioned, configurable packages — the same concept as apt for Ubuntu, but for Kubernetes.

What is Helm and Why You Need It

Helm is a package manager for Kubernetes that simplifies the process of defining, installing, and upgrading even the most complex Kubernetes applications. Helm bundles all related Kubernetes resources into a single package called a chart, making it easier to manage and distribute.

Without Helm, deploying a production-grade application to Kubernetes means:

Without Helm:
  kubectl apply -f namespace.yaml
  kubectl apply -f configmap.yaml
  kubectl apply -f secret.yaml
  kubectl apply -f deployment.yaml
  kubectl apply -f service.yaml
  kubectl apply -f ingress.yaml
  kubectl apply -f hpa.yaml
  # ...repeat for dev, staging, prod with manual value substitution
  # No easy rollback if something breaks

With Helm:
  helm install my-app ./my-chart -f values-prod.yaml
  # All resources applied in correct order
  # Values substituted from values file
  # Full rollback with: helm rollback my-app

Helm provides several key advantages over plain YAML: templating allows variables and functions in YAML files making them reusable; packaging bundles all related resources into a single chart; versioning allows easier upgrades and rollbacks; and lifecycle management provides commands for installing, upgrading, and uninstalling applications.

A Helm chart is to Kubernetes what a .deb package is to Ubuntu. When you run helm install prometheus prometheus-community/kube-prometheus-stack, Helm fetches the chart, resolves dependencies, substitutes your values, and deploys the complete Prometheus + Grafana + AlertManager stack in a single command.

Helm 2 vs Helm 3: The Critical Difference (Tiller is Gone)

In Helm 2, Tiller was the server-side component responsible for managing releases inside the Kubernetes cluster. Helm 3 removes Tiller entirely. All release management is now performed on the client side, leveraging the user’s kubeconfig and Kubernetes RBAC for authorization.

If you’ve used Helm before and remember running helm init to install Tiller — that’s Helm 2. It’s deprecated. Helm 3 is the only version you should be running in 2026.

Key differences that matter in practice:

Helm 2 (deprecated)Helm 3 (current)
TillerRequired (cluster-side component)Removed entirely
SecurityTiller had cluster-admin by defaultUses your kubeconfig RBAC
Release storageConfigMaps in kube-systemSecrets in the release namespace
helm initRequired before first useNot needed — no server-side setup
Release nameOptional (--name)Required positional argument
3-way mergeNoYes — smarter updates
OCI supportNoYes (stable since Helm 3.8)

This change simplifies the security model and aligns better with Kubernetes-native access control practices. Helm 3 needs no special cluster permissions beyond what your kubeconfig already grants — if you can kubectl apply, you can helm install.

Prerequisites

Verify kubectl access:

kubectl get nodes
# All nodes should show Ready

kubectl version --client
# Should show v1.36.x

Helm doesn’t need a cluster to install, but it needs one to deploy charts. You can install Helm on any machine that has kubectl access to the cluster.

Method 1: Install via APT Repository (Recommended)

The APT repository method is recommended for Ubuntu because it integrates with system updates and security patches.

# Install prerequisites
sudo apt update
sudo apt install -y curl gnupg apt-transport-https

# Add Helm's official GPG key
curl https://baltocdn.com/helm/signing.asc | \
  gpg --dearmor | \
  sudo tee /usr/share/keyrings/helm.gpg > /dev/null

# Add Helm stable APT repository
echo "deb [arch=$(dpkg --print-architecture) \
  signed-by=/usr/share/keyrings/helm.gpg] \
  https://baltocdn.com/helm/stable/debian/ all main" | \
  sudo tee /etc/apt/sources.list.d/helm-stable-debian.list

# Update package index and install
sudo apt update
sudo apt install -y helm

Advantage of APT method: sudo apt upgrade will automatically update Helm alongside other system packages. This is the cleanest approach for long-running servers where you want security patches applied consistently.

Method 2: Install via Script (Quickest)

The official Helm installer script detects your OS and architecture, downloads the latest stable release, and installs it automatically:

curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

The script:

  1. Detects your OS (Linux/macOS/Windows)
  2. Detects your architecture (amd64/arm64)
  3. Downloads the latest stable release (v3.21.3 at time of writing)
  4. Verifies the checksum
  5. Installs to /usr/local/bin/helm

For a specific version (useful in CI/CD to pin the Helm version):

DESIRED_VERSION="v3.21.3"
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | \
  DESIRED_VERSION=$DESIRED_VERSION bash

Method 3: Install via Snap

The snap package is the fastest way to get Helm up and running on Ubuntu.

sudo snap install helm --classic

The --classic flag is required because Helm needs access to your home directory (for ~/.kube/config) and system paths — beyond what confined snaps allow by default.

Trade-off: Snap packages are containerized and typically larger than the native binary. The snap version may lag slightly behind the latest release. For most use cases this is fine; use APT or the binary method if you need the absolute latest version.

Method 4: Install Manually from Binary

For air-gapped environments or when you need a specific version not yet in the APT repository:

HELM_VERSION="v3.21.3"
ARCH="amd64"   # or arm64 for ARM servers

# Download the release archive
curl -LO "https://get.helm.sh/helm-${HELM_VERSION}-linux-${ARCH}.tar.gz"

# Verify checksum
curl -LO "https://get.helm.sh/helm-${HELM_VERSION}-linux-${ARCH}.tar.gz.sha256sum"
sha256sum -c helm-${HELM_VERSION}-linux-${ARCH}.tar.gz.sha256sum
# Expected: helm-v3.21.3-linux-amd64.tar.gz: OK

# Extract and install
tar -zxvf helm-${HELM_VERSION}-linux-${ARCH}.tar.gz
sudo mv linux-${ARCH}/helm /usr/local/bin/helm
sudo chmod +x /usr/local/bin/helm

# Clean up
rm -rf linux-${ARCH} helm-${HELM_VERSION}-linux-${ARCH}.tar.gz*

Always verify the checksum before installing — this protects against corrupted downloads and supply chain attacks.

Verify the Installation

helm version

Expected output:

version.BuildInfo{
  Version:"v3.21.3",
  GitCommit:"...",
  GitTreeState:"clean",
  GoVersion:"go1.23.x"
}

Check Helm’s environment configuration:

helm env
# HELM_BIN="helm"
# HELM_CACHE_HOME="/home/user/.cache/helm"
# HELM_CONFIG_HOME="/home/user/.config/helm"
# HELM_DATA_HOME="/home/user/.local/share/helm"
# HELM_DEBUG="false"
# HELM_KUBEAPISERVER=""
# HELM_KUBECAFILE=""
# HELM_KUBECONTEXT=""
# HELM_KUBETOKEN=""
# HELM_MAX_HISTORY="10"
# HELM_NAMESPACE="default"
# HELM_REPOSITORY_CACHE="/home/user/.cache/helm/repository"
# HELM_REPOSITORY_CONFIG="/home/user/.config/helm/repositories.yaml"

Notable defaults: HELM_MAX_HISTORY="10" means Helm keeps only the last 10 release revisions. Increase it if you need deeper rollback history: export HELM_MAX_HISTORY=25

Configure Shell Autocompletion

Helm includes autocompletion for bash, zsh, fish, and PowerShell. Setting this up saves significant time when working with long chart names and release names:

# Bash autocompletion
echo 'source <(helm completion bash)' >> ~/.bashrc
source ~/.bashrc

# Zsh autocompletion
echo 'source <(helm completion zsh)' >> ~/.zshrc
source ~/.zshrc

# Fish shell
helm completion fish > ~/.config/fish/completions/helm.fish

After enabling autocompletion, helm ins<TAB> completes to helm install, and helm install prom<TAB> searches for matching chart names.

Managing Helm Repositories

A Helm repository is a collection of charts hosted at an HTTP endpoint — the equivalent of a Ubuntu PPA. Helm ships with no repositories preconfigured:

# Add popular 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 jetstack https://charts.jetstack.io           # cert-manager
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo add grafana https://grafana.github.io/helm-charts
helm repo add metallb https://metallb.github.io/metallb
helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/

# Update all repositories (fetch latest chart index)
helm repo update

# List configured repositories
helm repo list
# NAME                    URL
# bitnami                 https://charts.bitnami.com/bitnami
# prometheus-community    https://prometheus-community.github.io/helm-charts
# ...

# Search for charts across all repositories
helm search repo nginx
# NAME                              CHART VERSION   APP VERSION   DESCRIPTION
# bitnami/nginx                     18.x.x          1.27.x        NGINX Open Source is a web server that...
# ingress-nginx/ingress-nginx       4.x.x           1.11.x        Ingress controller for Kubernetes using NGINX

# Search for a specific app version
helm search repo postgresql --versions | head -10

# Remove a repository
helm repo remove stable

Essential Helm Commands Cheatsheet

Master the install/upgrade/rollback lifecycle — these are the commands you use daily.

# ── INSTALLATION ──────────────────────────────────────────────
# Install a chart
helm install <release-name> <chart> [flags]

# Install with custom values file
helm install my-app bitnami/nginx -f values.yaml

# Install with inline value overrides
helm install my-app bitnami/nginx \
  --set service.type=NodePort \
  --set replicaCount=3

# Install in a specific namespace (create if not exists)
helm install my-app bitnami/nginx \
  --namespace my-namespace \
  --create-namespace

# Install and wait until all resources are ready
helm install my-app bitnami/nginx --wait --timeout 5m

# Dry run — show what would be installed without applying
helm install my-app bitnami/nginx --dry-run

# ── INSPECTION ────────────────────────────────────────────────
# List all installed releases
helm list -A    # -A shows all namespaces

# Show release status
helm status my-app

# Show all resources for a release
helm get all my-app

# Show the values used for a release
helm get values my-app

# Show the rendered YAML templates
helm get manifest my-app

# Show release history
helm history my-app

# ── SEARCH AND INSPECT CHARTS ─────────────────────────────────
# Search repositories
helm search repo redis

# Show chart details and values
helm show chart bitnami/redis
helm show values bitnami/redis

# Render templates locally without installing
helm template my-release bitnami/redis -f values.yaml

# ── UPGRADE ───────────────────────────────────────────────────
# Upgrade an existing release
helm upgrade my-app bitnami/nginx --set replicaCount=5

# Upgrade or install if not already installed
helm upgrade --install my-app bitnami/nginx -f values.yaml

# Upgrade with atomic rollback on failure
helm upgrade --install my-app bitnami/nginx \
  --atomic \
  --timeout 5m

# ── ROLLBACK ──────────────────────────────────────────────────
# Roll back to the previous revision
helm rollback my-app

# Roll back to a specific revision
helm rollback my-app 2

# View history before rolling back
helm history my-app

# ── UNINSTALL ─────────────────────────────────────────────────
# Uninstall a release (removes all Kubernetes resources)
helm uninstall my-app

# Uninstall but keep history (allows reinstall with rollback)
helm uninstall my-app --keep-history

# ── PLUGINS ───────────────────────────────────────────────────
# Install a plugin
helm plugin install https://github.com/databus23/helm-diff

# List installed plugins
helm plugin list

# Update all plugins
helm plugin update $(helm plugin list | awk 'NR>1 {print $1}')

Install Your First Application with Helm

Deploy NGINX as a real-world example — the same NGINX Ingress Controller used in our NGINX Ingress Controller guide:

# Add the ingress-nginx repository
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

# Preview the default values
helm show values ingress-nginx/ingress-nginx | head -50

# Install with 2 replicas and Prometheus metrics enabled
helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx \
  --create-namespace \
  --set controller.replicaCount=2 \
  --set controller.metrics.enabled=true \
  --wait

# Verify installation
helm list -n ingress-nginx
# NAME            NAMESPACE       REVISION   STATUS     CHART
# ingress-nginx   ingress-nginx   1          deployed   ingress-nginx-4.x.x

helm status ingress-nginx -n ingress-nginx

Install the Prometheus + Grafana monitoring stack (one command for the entire stack):

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

helm upgrade --install kube-prometheus-stack \
  prometheus-community/kube-prometheus-stack \
  --namespace monitoring \
  --create-namespace \
  --set grafana.adminPassword=your-secure-password \
  --wait

# Access Grafana
kubectl port-forward -n monitoring svc/kube-prometheus-stack-grafana 3000:80
# Open http://localhost:3000 — login: admin / your-secure-password

This deploys Prometheus, Grafana, Alertmanager, Node Exporter, kube-state-metrics, and all required RBAC in a single command — replacing what would otherwise be hundreds of lines of individual YAML files.

Upgrade, Rollback, and Uninstall

# Show current release
helm list -n ingress-nginx
# REVISION 1

# Upgrade to a newer chart version
helm upgrade ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx \
  --reuse-values \   # Keep existing values, only change what's specified
  --version 4.12.0

# Check history
helm history ingress-nginx -n ingress-nginx
# REVISION  STATUS      CHART                   DESCRIPTION
# 1         superseded  ingress-nginx-4.11.0    Install complete
# 2         deployed    ingress-nginx-4.12.0    Upgrade complete

# Something broke — roll back to revision 1
helm rollback ingress-nginx 1 -n ingress-nginx
# Rollback was a success! Happy Helming!

helm history ingress-nginx -n ingress-nginx
# REVISION  STATUS      CHART                   DESCRIPTION
# 1         superseded  ingress-nginx-4.11.0    Install complete
# 2         superseded  ingress-nginx-4.12.0    Upgrade complete
# 3         deployed    ingress-nginx-4.11.0    Rollback to 1

# Uninstall when done
helm uninstall ingress-nginx -n ingress-nginx

--atomic flag for production upgrades:

helm upgrade my-app bitnami/nginx \
  --atomic \
  --timeout 5m \
  --cleanup-on-fail

--atomic makes the upgrade automatically roll back if it fails — the single best flag to add to all production upgrade commands. It turns a potentially broken cluster into a guaranteed-working-previous-version cluster.

Create Your First Helm Chart

The helm create command scaffolds a complete chart with best-practice templates.

# Create a new chart scaffold
helm create my-webapi

# View the generated structure
tree my-webapi
# my-webapi/
# ├── Chart.yaml            ← Chart metadata (name, version, description)
# ├── values.yaml           ← Default configuration values
# ├── charts/               ← Chart dependencies
# └── templates/
#     ├── _helpers.tpl      ← Template helper functions
#     ├── deployment.yaml   ← Deployment template
#     ├── hpa.yaml          ← HorizontalPodAutoscaler
#     ├── ingress.yaml      ← Ingress
#     ├── NOTES.txt         ← Post-install message
#     ├── service.yaml      ← Service
#     ├── serviceaccount.yaml
#     └── tests/
#         └── test-connection.yaml

Chart.yaml — the chart’s identity:

apiVersion: v2
name: my-webapi
description: A Helm chart for My Web API
type: application
version: 0.1.0          # Chart version (increment on chart changes)
appVersion: "1.2.3"     # Application version (tracks app releases)
maintainers:
  - name: Ramansah
    email: admin@bckinfo.com

values.yaml — default configuration:

replicaCount: 2

image:
  repository: myregistry.com/my-webapi
  pullPolicy: IfNotPresent
  tag: "1.2.3"

service:
  type: ClusterIP
  port: 80

ingress:
  enabled: true
  className: "nginx"
  hosts:
    - host: api.yourdomain.com
      paths:
        - path: /
          pathType: Prefix

resources:
  requests:
    cpu: 100m
    memory: 128Mi
  limits:
    cpu: 500m
    memory: 512Mi

autoscaling:
  enabled: false
  minReplicas: 2
  maxReplicas: 10
  targetCPUUtilizationPercentage: 80

Test, lint, and render before installing:

# Lint: check for syntax errors and best practice violations
helm lint ./my-webapi
# ==> Linting ./my-webapi
# [INFO] Chart.yaml: icon is recommended
# 1 chart(s) linted, 0 chart(s) failed

# Render templates to stdout — verify generated YAML
helm template my-webapi-release ./my-webapi \
  --set image.tag=1.3.0 \
  --set ingress.hosts[0].host=api.staging.yourdomain.com

# Install from local chart
helm install my-webapi ./my-webapi -f values-production.yaml

# Package the chart for distribution
helm package ./my-webapi
# Successfully packaged chart and saved it to: my-webapi-0.1.0.tgz

OCI Registry Support

Helm 3 supports OCI registries, using the same infrastructure as container images. Instead of hosting a separate Helm repository, you can store charts alongside your container images in a standard container registry (Docker Hub, GitHub Container Registry, AWS ECR, etc.):

# Package your chart
helm package ./my-webapi
# Creates: my-webapi-0.1.0.tgz

# Push to GitHub Container Registry
helm push my-webapi-0.1.0.tgz oci://ghcr.io/myorg/charts

# Install directly from OCI registry
helm install my-release \
  oci://ghcr.io/myorg/charts/my-webapi \
  --version 0.1.0

# Pull to local without installing
helm pull oci://ghcr.io/myorg/charts/my-webapi --version 0.1.0

Practical benefit: OCI-based chart storage works with the same authentication (docker login) and access controls as your container images — no need to manage a separate Helm repository server.

The helm diff Plugin: Preview Before Upgrade

The helm diff plugin is the single best addition to your workflow after the basics — it turns upgrades from surprises into reviewed changes.

# Install the diff plugin
helm plugin install https://github.com/databus23/helm-diff

# Preview what an upgrade would change before applying it
helm diff upgrade ingress-nginx ingress-nginx/ingress-nginx \
  --namespace ingress-nginx \
  --reuse-values \
  --version 4.12.0

Output shows a git-diff-style preview:

ingress-nginx, ingress-nginx-controller, Deployment (apps) has changed:
  # Source: ingress-nginx/templates/controller-deployment.yaml
  ...
-       image: registry.k8s.io/ingress-nginx/controller:v1.11.0@sha256:...
+       image: registry.k8s.io/ingress-nginx/controller:v1.12.0@sha256:...
  ...

Review the diff, confirm only expected changes are present, then apply. This single habit catches most production upgrade surprises before they happen.

Helm in CI/CD Pipelines

Standard pattern for deploying to Kubernetes from GitLab CI or GitHub Actions:

# .gitlab-ci.yml — Helm deployment stage
deploy-production:
  stage: deploy
  image: alpine/helm:3.21.3    # Pin Helm version for reproducibility
  script:
    # Add and update repos
    - helm repo add myorg oci://ghcr.io/myorg/charts
    - helm repo update

    # Deploy with --atomic for automatic rollback on failure
    - helm upgrade --install my-webapi myorg/my-webapi
        --namespace production
        --create-namespace
        --set image.tag=$CI_COMMIT_SHORT_SHA
        --set ingress.hosts[0].host=api.yourdomain.com
        --atomic
        --timeout 5m
        --cleanup-on-fail
        --wait
  environment:
    name: production
    url: https://api.yourdomain.com
  only:
    - main

Key CI/CD best practices:

  • Always use --atomic — automatic rollback on failure prevents a broken deployment from staying broken
  • Pin the Helm image version (alpine/helm:3.21.3) — avoids unexpected behavior from automatic minor updates in CI
  • Use $CI_COMMIT_SHORT_SHA as the image tag — every deployment is traceable to a specific commit
  • Use --wait — the pipeline only succeeds when Kubernetes reports all resources ready, not just when kubectl apply finished

Helm 4.0: What’s Coming in September 2026

Helm 4.0 and 3.22.0 are the next minor releases scheduled for September 9, 2026.

Helm 4 will bring some breaking changes worth knowing about if you plan to upgrade:

  • Removed --reuse-values default — Helm 4 will require explicit values on every upgrade, reducing surprising “reuse of old values” bugs
  • Stricter schema validation — chart values will be more strictly validated against values.schema.json
  • Library chart improvements — better support for shared helper templates across chart ecosystems
  • Improved 3-way strategic merge — more accurate detection of out-of-band changes to managed resources

For current production deployments: stay on Helm 3.21.x until Helm 4.0 is released and tested by the community (typically 1-2 months post-release before enterprise adoption).

Common Issues and Quick Fixes

SymptomLikely CauseFix
helm: command not found after APT installPATH not updatedRun source ~/.bashrc or open a new terminal
Error: INSTALLATION FAILED: cannot re-use a nameRelease name already existsUse helm upgrade --install instead of helm install
Error: release has no deployed releasesRelease in failed statehelm history <release> to check; helm rollback or helm uninstall then reinstall
Chart upgrade times outPods not becoming readyCheck kubectl get pods -n <namespace>; check resource limits and image pull status
Error: repo already existsRepository already addedRun helm repo update instead; or helm repo remove then re-add
helm diff shows no outputNo changes detectedExpected — upgrade would make no changes
Error: rendered manifests contain a resource that already existsPre-existing resource not owned by HelmAdd --force flag or manually delete the conflicting resource
Snap Helm version lags behindSnap update cycle slower than releasesSwitch to APT or binary install method

Reset a failed release:

# List all releases including failed ones
helm list -A --all

# Delete a failed release and start fresh
helm uninstall my-release -n my-namespace

# Or force delete
helm uninstall my-release -n my-namespace --no-hooks

Next Steps

With Helm installed and working on Ubuntu 26.04:

  • Install an Ingress Controller — use Helm to deploy the NGINX Ingress Controller with a single command: helm install ingress-nginx ingress-nginx/ingress-nginx. See our Deploy NGINX Ingress Controller guide for the full configuration.
  • Install MetalLBhelm install metallb metallb/metallb — see our Install MetalLB on Bare Metal Kubernetes guide for the post-install IP pool configuration.
  • Deploy Prometheus + Grafanahelm install kube-prometheus-stack prometheus-community/kube-prometheus-stack — see our Prometheus + Grafana Monitoring Stack guide for dashboard and alerting configuration.
  • Install KubeSpherehelm install ks-core https://charts.kubesphere.io/main/ks-core-1.1.3.tgz for a full web-based cluster management UI — see our KubeSphere and Kubernetes Security guide.
  • Learn chart development — the helm create scaffold is the starting point; add values.schema.json for input validation, write tests in templates/tests/, and publish to an OCI registry for team sharing.

(Visited 4 times, 1 visits today)

You may also like