mychart/
Chart.yaml # name, version (chart), appVersion (app), dependencies
values.yaml # default values
values.schema.json # (optional) JSON Schema that checks values
charts/ # dependent subcharts
crds/ # Custom Resource Definitions
templates/
deployment.yaml
service.yaml
_helpers.tpl # helpers, renders no manifest
NOTES.txt # printed after install
tests/ # test hooks
.helmignore # files skipped when packaging
flowchart LR V["values.yaml<br/>+ -f / --set"] --> E["Template engine"] T["templates/*.yaml"] --> E C["Chart.yaml"] --> E E --> M["Kubernetes manifests"] M --> K["kube-apiserver"]
# Chart.yaml
apiVersion: v2
name: mychart
version: 0.1.0 # chart version, bump on every chart change
appVersion: "1.27.0" # version of the app inside
Common traps
- Mixing up
version(chart) andappVersion(app): changing the app image should still bump the chartversion. - Putting CRDs in
templates/instead ofcrds/: Helm installscrds/first, so templates that use the CRD do not fail with "no matches for kind". - The helper file is
_helpers.tpl(files starting with_render no manifest).
| Command | Meaning |
|---|---|
helm create mychart |
Scaffold a sample chart |
helm lint mychart |
Check syntax errors and best practices |
helm template myrel ./mychart |
Render manifests to the screen without installing |
helm package mychart |
Package as mychart-0.1.0.tgz |
More Chart.yaml fields
apiVersion: v2
name: mychart
description: Web front end for the shop
type: application # or library
version: 0.3.1
appVersion: "1.27.0"
kubeVersion: ">=1.28.0-0"
keywords: [web, nginx]
maintainers:
- name: Platform Team
email: platform@example.com
A library chart (type: library) holds only reusable template helpers and cannot be installed by itself; application charts depend on it to share labels, probes, or a standard Deployment layout. kubeVersion makes Helm refuse to install on clusters that are too old.
Designing good values
- Group values by component (
web.replicaCount,worker.resources), use camelCase, and document every key with a comment invalues.yaml, because that file is the chart's user interface. - Provide safe defaults: resource requests, probes, a non-root security context.
- Avoid forcing users to edit templates; expose a value instead, or an
extraEnvorextraVolumesescape hatch.
Validating values
A values.schema.json file rejects bad input before anything reaches the cluster:
{
"type": "object",
"required": ["image"],
"properties": {
"replicaCount": { "type": "integer", "minimum": 1 },
"image": { "type": "object", "required": ["repository"] }
}
}
helm install, upgrade, lint, and template all apply the schema.
Testing and publishing
helm lint --stricttreats warnings as errors in CI.- The chart-testing tool (
ct lint,ct install) checks changed charts in a pull request, including whether the version was bumped. - The helm-unittest plugin asserts on rendered output without a cluster.
helm package --signcreates a provenance file so users can verify the chart withhelm verify.
Public charts are indexed on Artifact Hub, where you can compare maintainers, versions, and security reports before choosing one.