10 Helm Chart Examples for Kubernetes Deployments

10 Helm chart examples with real repos and values.yaml: helm create, cert-manager, Traefik, kube-prometheus-stack, Argo CD, Vault, Jenkins and more.

Dec 8, 2025 - 17:21
Nov 7, 2026 - 05:16
 0  379
10 Helm Chart Examples for Kubernetes Deployments

The most useful Helm chart examples to learn are a chart you build yourself with helm create, plus widely used community charts such as cert-manager, Traefik, kube-prometheus-stack, Argo CD, Vault, Jenkins, GitLab Runner and CloudNativePG. Each one teaches a different Helm skill: values, CRDs, secrets, persistence, high availability or dependencies.

This guide walks through 10 examples with the real chart repository for each, a working values.yaml snippet and the install command. Repository URLs and value keys were checked against each project's own chart documentation and Artifact Hub listing in November 2026. For where Helm fits in a cluster, start with our Kubernetes architecture components guide.

Key takeaways

  • Helm 4 is the current major release (it went GA in November 2025). Charts written for Helm 3 still deploy with Helm 4, and every command in this article works on both.
  • Helm 3 receives security fixes only until February 10, 2027, so plan your upgrade to Helm 4 now.
  • In Helm 4, --atomic is renamed to --rollback-on-failure and --force to --force-replace. The old flags still work with a deprecation warning.
  • Many projects now publish charts as OCI artifacts (for example oci://quay.io/jetstack/charts/cert-manager), so you can install without helm repo add.
  • Never put passwords or tokens directly in values.yaml committed to Git. Most charts accept an existingSecret value instead.
  • Pin chart versions with --version in every environment so an upstream release cannot change production without review.

Helm 3 or Helm 4: what changes for these examples

The Helm maintainers released Helm 4 in November 2025. The final Helm 3 feature release shipped on September 9, 2026, and Helm 3 security patches end on February 10, 2027. After that date Helm 3 gets no updates at all.

For chart users the move is small. The Helm 4 overview states that charts deployable with Helm 3 should be deployable by Helm 4, and existing releases can be upgraded by the new binary. The changes most likely to break a CI script are:

AreaHelm 3Helm 4
Roll back on failed install or upgrade--atomic--rollback-on-failure (old flag deprecated)
Delete and recreate resources--force--force-replace (old flag deprecated)
Apply method for new installsClient-side applyServer-side apply by default; existing releases keep their previous method
helm registry loginAccepted full URLsDomain name only
Post-renderersPath to an executableMust be a Helm plugin
Chart APIapiVersion: v2v2 unchanged; v3 is experimental behind HELM_EXPERIMENTAL_CHART_V3=1

All the charts below use apiVersion: v2, so they work the same way on both versions.

The 10 Helm chart examples at a glance

#ExampleChart sourceHelm skill it teaches
1Your own web app charthelm createChart structure, templates, values
2cert-manageroci://quay.io/jetstack/charts/cert-managerOCI install, CRDs, post-install resources
3Traefik ingress controllerhttps://traefik.github.io/chartsService type, IngressClass, Gateway API toggles
4kube-prometheus-stackoci://ghcr.io/prometheus-community/charts/kube-prometheus-stackLarge umbrella chart, storage, CRD upgrades
5Argo CDhttps://argoproj.github.io/argo-helmHA values, autoscaling, nested config
6HashiCorp Vaulthttps://helm.releases.hashicorp.comStatefulSet, Raft HA, persistence
7Jenkinshttps://charts.jenkins.ioExisting secrets, plugin lists, config as code
8GitLab Runnerhttps://charts.gitlab.ioTokens in secrets, RBAC, multi-line config
9CloudNativePG (PostgreSQL)https://cloudnative-pg.github.io/chartsOperator plus custom-resource chart
10Microservices umbrella chartYour own Chart.yamlDependencies, conditions, aliases, global values

Example 1: Build your own chart with helm create

helm create generates a working chart for an NGINX web server. It is the fastest way to see how a chart is laid out.

helm create webapp
tree webapp
# webapp/
#   Chart.yaml          chart name, version, appVersion
#   values.yaml         default configuration
#   charts/             dependency charts
#   templates/          deployment.yaml, service.yaml, ingress.yaml, hpa.yaml, _helpers.tpl, NOTES.txt ...

Templates read from .Values. This is a trimmed version of the generated Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "webapp.fullname" . }}
  labels:
    {{- include "webapp.labels" . | nindent 4 }}
spec:
  {{- if not .Values.autoscaling.enabled }}
  replicas: {{ .Values.replicaCount }}
  {{- end }}
  template:
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
          resources:
            {{- toYaml .Values.resources | nindent 12 }}

Override the defaults with an environment-specific values file instead of editing values.yaml for every environment:

# values-prod.yaml
replicaCount: 3
image:
  repository: registry.example.com/team/webapp
  tag: "1.4.2"
resources:
  requests:
    cpu: 100m
    memory: 128Mi
  limits:
    memory: 256Mi
ingress:
  enabled: true
  className: traefik
  hosts:
    - host: app.example.com
      paths:
        - path: /
          pathType: Prefix
helm lint ./webapp -f values-prod.yaml
helm template webapp ./webapp -f values-prod.yaml | less
helm upgrade --install webapp ./webapp -n web --create-namespace -f values-prod.yaml --wait

Run helm lint and helm template in CI on every pull request. They catch indentation and missing-value errors before anything reaches a cluster. Our YAML essentials for Kubernetes covers the indentation rules that trip up most template edits.

Example 2: cert-manager for automatic TLS certificates

cert-manager issues and renews TLS certificates inside the cluster. Its chart is a good example of two common patterns: installing from an OCI registry, and a chart that installs CustomResourceDefinitions (CRDs).

helm install cert-manager oci://quay.io/jetstack/charts/cert-manager \
  --version v1.21.3 \
  --namespace cert-manager \
  --create-namespace \
  --set crds.enabled=true

The cert-manager docs recommend the OCI chart. The classic repository at https://charts.jetstack.io still exists but is updated a few hours after the OCI release. Set crds.enabled=true so the chart manages the CRDs; without it, you must apply them yourself before creating issuers.

After the chart is running, create an issuer. This resource is not part of the chart, which keeps environment-specific settings out of the upstream values:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt-prod-account-key
    solvers:
      - http01:
          ingress:
            ingressClassName: traefik

Check the cert-manager installation page for the current version before you copy the command. v1.21.3 was current when this article was written.

Example 3: Traefik as the ingress controller

Many older tutorials use the ingress-nginx chart here. The Kubernetes project has retired ingress-nginx: best-effort maintenance ended in March 2026, and there are no further releases, bug fixes or security updates. Existing installs keep working, but new clusters should pick a maintained controller. Traefik is one option, and its chart shows how to toggle Ingress and Gateway API support from values.

helm repo add traefik https://traefik.github.io/charts
helm repo update
helm install traefik traefik/traefik -n traefik --create-namespace -f traefik-values.yaml
# or, without adding a repo:
# helm install traefik oci://ghcr.io/traefik/helm/traefik -n traefik --create-namespace
# traefik-values.yaml
ingressClass:
  enabled: true
  isDefaultClass: true

service:
  spec:
    type: LoadBalancer      # use NodePort on bare metal without a load balancer

providers:
  kubernetesIngress:
    enabled: true
  kubernetesGateway:
    enabled: false          # set true to serve Gateway API HTTPRoutes

ingressRoute:
  dashboard:
    enabled: false          # keep the dashboard off unless it is protected

Notice that service settings sit under service.spec in this chart, not directly under service. Every chart has its own value layout, which is why helm show values is the first command to run before writing an override file:

helm show values traefik/traefik > traefik-defaults.yaml

Example 4: kube-prometheus-stack for monitoring

kube-prometheus-stack installs the Prometheus Operator, Prometheus, Alertmanager, Grafana and a set of dashboards and alert rules. It is large, so it is a good chart for learning how to override deeply nested values.

helm install monitoring oci://ghcr.io/prometheus-community/charts/kube-prometheus-stack \
  -n monitoring --create-namespace -f monitoring-values.yaml
# monitoring-values.yaml
grafana:
  admin:
    existingSecret: grafana-admin       # Secret with keys admin-user and admin-password

prometheus:
  prometheusSpec:
    retention: 15d
    serviceMonitorSelectorNilUsesHelmValues: false   # pick up ServiceMonitors from other releases
    storageSpec:
      volumeClaimTemplate:
        spec:
          accessModes: ["ReadWriteOnce"]
          resources:
            requests:
              storage: 50Gi

Two points from the chart README matter in production:

  • CRDs are not upgraded automatically. Helm does not update CRDs on helm upgrade, and a CRD change in this chart means a major version bump. Read the upgrade notes and apply the new CRDs before upgrading across a major version.
  • The CRDs are too big for client-side apply. If you deploy this chart through Argo CD, enable ServerSideApply=true on the Application, as the README advises.

Our Kubernetes observability tools post compares this stack with other options.

Example 5: Argo CD in high-availability mode

The Argo CD chart installs a single-replica, non-HA setup by default. Its README gives example values for HA mode, which needs at least three worker nodes because the Redis HA pods must land on separate nodes.

helm repo add argo https://argoproj.github.io/argo-helm
helm repo update
helm install argocd argo/argo-cd -n argocd --create-namespace -f argocd-values.yaml
# argocd-values.yaml (HA with autoscaling, based on the chart README)
global:
  domain: argocd.example.com

redis-ha:
  enabled: true

controller:
  replicas: 1

server:
  autoscaling:
    enabled: true
    minReplicas: 2

repoServer:
  autoscaling:
    enabled: true
    minReplicas: 2

applicationSet:
  replicas: 2

configs:
  params:
    server.insecure: true     # only when TLS terminates at the ingress or gateway

Keys such as server.insecure contain a dot but are a single key under configs.params. On the command line you must escape the dot: --set configs.params."server\.insecure"=true. Using a values file avoids that quoting problem.

Once Argo CD is running, it can deploy all your other Helm charts from Git. See our top GitOps tools for Kubernetes for how Argo CD compares with Flux.

Example 6: HashiCorp Vault with integrated Raft storage

The official Vault chart runs Vault as a StatefulSet. By default it runs in standalone mode. These values switch it to a three-node HA cluster using Vault's integrated Raft storage, with a persistent volume per pod.

helm repo add hashicorp https://helm.releases.hashicorp.com
helm repo update
helm install vault hashicorp/vault -n vault --create-namespace -f vault-values.yaml
# vault-values.yaml
server:
  ha:
    enabled: true
    replicas: 3
    raft:
      enabled: true
      setNodeId: true
  dataStorage:
    enabled: true
    size: 10Gi

ui:
  enabled: true

injector:
  enabled: true      # Vault Agent sidecar injector for application pods

The chart deploys Vault but does not initialise or unseal it. Plan how you will run vault operator init, store the recovery material safely and configure auto-unseal before you rely on this in production. HashiCorp's Vault on Kubernetes documentation covers each step. Our tools to manage Kubernetes secrets safely compares Vault with External Secrets and Sealed Secrets.

Example 7: Jenkins controller with plugins and config as code

The Jenkins chart shows how a chart can manage an application's own configuration, not just its Kubernetes objects.

helm repo add jenkins https://charts.jenkins.io
helm repo update
helm install jenkins jenkins/jenkins -n jenkins --create-namespace -f jenkins-values.yaml
# jenkins-values.yaml
controller:
  admin:
    existingSecret: jenkins-admin          # keys: jenkins-admin-user, jenkins-admin-password
  installPlugins:
    - kubernetes
    - workflow-aggregator
    - git
    - configuration-as-code
  JCasC:
    configScripts:
      welcome-message: |
        jenkins:
          systemMessage: "Managed by Helm and JCasC. Manual changes will be overwritten."

persistence:
  enabled: true
  size: 20Gi

The chart's default plugin list pins exact plugin versions. Pinning versions in your own values as well makes upgrades predictable. The README also suggests splitting large JCasC blocks into separate values files and passing several -f flags at install time.

Example 8: GitLab Runner on Kubernetes

GitLab Runner's chart registers a runner that starts each CI job as a pod. It is a good example of keeping a token out of values files.

kubectl create namespace gitlab-runner
kubectl -n gitlab-runner create secret generic gitlab-runner-token \
  --from-literal=runner-registration-token="" \
  --from-literal=runner-token="REPLACE_WITH_RUNNER_AUTH_TOKEN"

helm repo add gitlab https://charts.gitlab.io
helm repo update
helm install gitlab-runner gitlab/gitlab-runner -n gitlab-runner -f runner-values.yaml
# runner-values.yaml
gitlabUrl: https://gitlab.example.com/
rbac:
  create: true              # lets the runner create job pods
concurrent: 10
runners:
  secret: gitlab-runner-token
  config: |
    [[runners]]
      [runners.kubernetes]
        namespace = "{{ default .Release.Namespace .Values.runners.jobNamespace }}"
        image = "alpine"

The runners.config value is a multi-line string that the chart passes through Helm's tpl function, so Helm expressions inside it are rendered. That is a pattern worth knowing when you write your own charts.

Example 9: PostgreSQL with the CloudNativePG operator

Running a database with a plain StatefulSet chart leaves failover and backups to you. CloudNativePG splits the job in two: one chart installs the operator, and a second chart creates a PostgreSQL Cluster resource that the operator manages.

helm repo add cnpg https://cloudnative-pg.github.io/charts
helm repo update

# 1. the operator (once per cluster)
helm upgrade --install cnpg cnpg/cloudnative-pg -n cnpg-system --create-namespace

# 2. a database cluster
helm upgrade --install orders-db cnpg/cluster -n databases --create-namespace -f pg-values.yaml
# pg-values.yaml
type: postgresql
mode: standalone
cluster:
  instances: 3          # one primary, two replicas
  storage:
    size: 20Gi
  monitoring:
    enabled: true       # creates a PodMonitor for kube-prometheus-stack
backups:
  enabled: false        # configure object storage before turning this on

This operator-plus-resource pattern is common for stateful software on Kubernetes. Our post on Kubernetes operators for database lifecycle automation explains why operators handle failover better than a hand-written chart.

Example 10: An umbrella chart for a microservices app

An umbrella chart has no templates of its own (or very few). It lists other charts as dependencies so you can install a whole application with one release.

# shop/Chart.yaml
apiVersion: v2
name: shop
description: Storefront, orders API and worker
type: application
version: 0.3.0
appVersion: "2.1.0"
dependencies:
  - name: webapp
    version: 0.1.0
    repository: file://../webapp
    alias: storefront
  - name: webapp
    version: 0.1.0
    repository: file://../webapp
    alias: orders-api
  - name: cluster
    version: ">=0.1.0"
    repository: https://cloudnative-pg.github.io/charts
    alias: orders-db
    condition: orders-db.enabled
# shop/values.yaml
global:
  environment: production

storefront:
  replicaCount: 3
  image:
    repository: registry.example.com/shop/storefront
    tag: "2.1.0"

orders-api:
  replicaCount: 2
  image:
    repository: registry.example.com/shop/orders-api
    tag: "2.1.0"

orders-db:
  enabled: true
  cluster:
    instances: 3
helm dependency update ./shop      # downloads dependencies into shop/charts and writes Chart.lock
helm upgrade --install shop ./shop -n shop --create-namespace --wait

The alias field lets you reuse one generic chart for several services. Values for each dependency go under its alias, condition lets an environment switch a dependency off, and anything under global is visible to every subchart. Commit Chart.lock so every environment builds from the same dependency versions. In a real setup, pin the CloudNativePG cluster chart to an exact version instead of a range.

Day-two commands for any chart

helm list -A                                   # every release in every namespace
helm status webapp -n web                      # current state and NOTES
helm get values webapp -n web                  # values you supplied
helm get manifest webapp -n web                # what Helm actually applied
helm history webapp -n web                     # revisions
helm rollback webapp 3 -n web                  # back to revision 3
helm upgrade webapp ./webapp -n web -f values-prod.yaml --rollback-on-failure   # Helm 4 (use --atomic on Helm 3)
helm uninstall webapp -n web

By default helm install waits up to five minutes (--timeout 5m0s) for each Kubernetes operation. Raise it for charts with slow-starting pods, such as databases.

Production checklist for Helm charts

CheckWhy it matters
Pin --version for every chartA new upstream release cannot change production without a reviewed commit
Keep one values file per environment in GitDifferences between dev, staging and prod are visible in a diff
Use existingSecret or an external secrets toolPasswords and tokens stay out of Git and out of helm get values output
Run helm lint and helm template in CITemplate errors fail the pull request, not the deployment
Read upgrade notes before major versionsCRD changes and renamed values are announced there
Set resource requests and limits in valuesMany charts ship with empty resources, which hurts scheduling
Install from OCI by digest where supportedHelm 4 refuses to install a chart whose digest does not match

For more on chart hygiene, read our Helm best practices and the companion list of Helm chart mistakes and how to fix them. Helm is also part of the hands-on labs in our CKAD training.

Frequently asked questions

What is a Helm chart?

A Helm chart is a package of Kubernetes manifest templates plus a values.yaml file of defaults. Helm renders the templates with your values and installs the result as a versioned release that you can upgrade or roll back.

Should I use Helm 3 or Helm 4?

Use Helm 4 for new work. It went GA in November 2025, and Helm 3 receives security fixes only until February 10, 2027. Charts built for Helm 3 still deploy with Helm 4, so most teams only need to update CI flags.

What replaced --atomic in Helm 4?

The flag is now --rollback-on-failure. Helm 4 still accepts --atomic with a deprecation warning, so update scripts before the old name is removed. Similarly, --force became --force-replace.

Where can I find trusted Helm charts?

Search Artifact Hub, then install from the repository or OCI registry that the project itself documents. Prefer charts published by the software's maintainers, such as cert-manager, Argo, HashiCorp and Prometheus Community.

How do I keep secrets out of values.yaml?

Create the Kubernetes Secret separately, or sync it with External Secrets or Vault, and point the chart at it with its existingSecret value. Jenkins, Grafana in kube-prometheus-stack and GitLab Runner all support this.

Why didn't helm upgrade update my CRDs?

Helm installs CRDs from a chart's crds/ directory on first install but does not upgrade them. Charts such as kube-prometheus-stack document a manual CRD step for major versions. cert-manager manages its CRDs as templates when crds.enabled=true.

Is ingress-nginx still a good example chart?

No. The Kubernetes project retired ingress-nginx, with no releases or security fixes after March 2026. Existing installs keep running, but choose a maintained controller, such as Traefik or a Gateway API implementation, for new clusters.

What is the difference between helm install and helm upgrade --install?

helm install fails if the release already exists. helm upgrade --install installs the release if it is missing and upgrades it otherwise, which makes it safe to run repeatedly from CI/CD pipelines.

Official references

What's Your Reaction?

Like Like 0
Dislike Dislike 0
Love Love 0
Funny Funny 0
Angry Angry 0
Sad Sad 0
Wow Wow 0
Mridul I am a passionate technology enthusiast with a strong focus on DevOps, Cloud Computing, and Cybersecurity. Through my blogs at DevOps Training Institute, I aim to simplify complex concepts and share practical insights for learners and professionals. My goal is to empower readers with knowledge, hands-on tips, and industry best practices to stay ahead in the ever-evolving world of DevOps.