# Chart Best Practices — Helm

Source: https://www.skillbyai.com/en/helm/q-practices

> Write charts that are predictable, portable and easy to operate.

## Conventions that save pain later

A good chart follows a few conventions. Use the **recommended labels** `app.kubernetes.io/name`, `instance`, `version`, `component`, `part-of` and `managed-by`, keeping selectors to the stable subset. Do not hardcode `metadata.namespace` in templates; let `--namespace` decide (or use `.Release.Namespace` consistently). Give every container **resource requests**, probes and a restrictive **securityContext** (`runAsNonRoot`, `readOnlyRootFilesystem`, dropped capabilities), with values to override them. Make optional features opt-in with `enabled` flags and keep **values flat and documented**, with comments above each key; tools such as **helm-docs** turn those comments into a README table. Name values in camelCase, starting lowercase. Avoid giant charts that template every Kubernetes field: expose what users truly need, and offer `extraEnv`, `extraVolumes` or `podAnnotations` escape hatches for the rest.

## A documented, secure-by-default values block

Comments double as documentation; defaults are safe, overrides are possible.

```yaml
# -- Number of pods when autoscaling is disabled
replicaCount: 2

# -- Container security settings (secure defaults)
securityContext:
  runAsNonRoot: true
  readOnlyRootFilesystem: true
  allowPrivilegeEscalation: false
  capabilities:
    drop: ["ALL"]

# -- Liveness and readiness probes
probes:
  readiness: { httpGet: { path: /healthz/ready, port: http }, periodSeconds: 5 }
  liveness:  { httpGet: { path: /healthz/live,  port: http }, periodSeconds: 10 }

# -- Extra environment variables appended to the container
extraEnv: []
```

## Design for the person upgrading

Renaming a value or a resource breaks every user's upgrade. Deprecate old keys gracefully (support both for a release and fail with a helpful `required`/`fail` message later) and document breaking changes in the chart's changelog with a major version bump.

**Quiz:** Which practice keeps a chart portable across namespaces?

- [x] Letting the release namespace decide instead of hardcoding it
- [ ] Hardcoding metadata.namespace: production
- [ ] Putting every value under global
- [ ] Using the template action instead of include

*Answer:* Letting the release namespace decide instead of hardcoding it. Hardcoded namespaces break installs into other namespaces and confuse Helm's release tracking.
