Best Practices

Lint, template-render, and version your charts; keep values documented and templates predictable.

A few habits keep charts reliable and easy for others to use.

Validate before shipping

  • helm lint ./chart — catch structural and convention issues.
  • helm template ./chart — render locally and eyeball the YAML.
  • helm install --dry-run --debug — validate against a real cluster's API without applying.

Design guidelines

  • Give every value a sensible default and a comment.
  • Use the standard app.kubernetes.io labels via a shared helper.
  • Prefix helper templates with the chart name to avoid collisions.
  • Bump version on every chart change; use appVersion for the app.
  • Prefer include over template so you can pipe through nindent.
  • Quote strings that could be misread as numbers or booleans.

Example

Example · bash
# A typical pre-release validation pipeline
helm lint ./mychart
helm template ./mychart --debug > /dev/null
helm install my-web ./mychart --dry-run --debug

# Then package and publish
helm package ./mychart
helm push mychart-0.1.0.tgz oci://registry.example.com/charts

When to use it

  • A chart maintainer runs helm lint --strict in the CI pipeline on every pull request to catch missing required fields and non-standard conventions before code review.
  • A developer increments the chart's version field in Chart.yaml on every change so users of the chart repository can track changes and pin to a known-good version.
  • A platform team adds comments above every key in values.yaml documenting the purpose and accepted values, treating the file as the chart's user-facing API documentation.

More examples

Lint before packaging

Runs lint for standard checks, strict lint for warnings-as-errors, and template to catch rendering errors before packaging.

Example · bash
helm lint ./myapp
helm lint ./myapp --strict
helm template my-release ./myapp -f values.yaml > /dev/null

Document values clearly

Shows values.yaml documented with comments explaining each field's purpose and accepted values, making it self-documenting.

Example · yaml
# values.yaml
# replicaCount: number of Pod replicas (min 1, scale >=3 for HA)
replicaCount: 1

# image.pullPolicy: Always | IfNotPresent | Never
image:
  repository: myregistry/myapp
  tag: ""          # Defaults to Chart.appVersion when empty
  pullPolicy: IfNotPresent

Version bump workflow

Shows a complete release workflow: bump version, lint, dry-run apply for Kubernetes validation, then package and push.

Example · bash
# After each chart change:
# 1. Bump version in Chart.yaml (follows semver)
# 2. Lint and template-test
helm lint ./myapp --strict
helm template test-release ./myapp | kubectl apply --dry-run=client -f -
# 3. Package and publish
helm package ./myapp && helm push myapp-*.tgz oci://ghcr.io/myorg/charts

Discussion

  • Be the first to comment on this lesson.