Loading...
Loading...
Helm 3 chart development, scaffolding, templating, debugging, OCI registries, post-renderers, and production operations. Use when creating Helm charts, packaging Kubernetes applications, debugging Helm deployments, managing releases, working with chart dependencies, or when the user mentions Helm, helm install, helm upgrade, Chart.yaml, values.yaml, helm template, or OCI registry.
npx skill4agent add kaynetik/skills helmmychart/
Chart.yaml
values.yaml
values.schema.json # optional JSON Schema validation
charts/ # dependencies
crds/ # CRDs (applied before templates)
templates/
NOTES.txt
_helpers.tpl
deployment.yaml
service.yaml
ingress.yaml
configmap.yaml
secret.yaml
hpa.yaml
tests/
test-connection.yaml
.helmignoreapiVersion: v2
name: myapp
description: A production-grade web application
type: application
version: 1.0.0
appVersion: "2.0.1"
kubeVersion: ">=1.30.0"
maintainers:
- name: DevOps Team
email: devops@example.com
dependencies:
- name: postgresql
version: "16.x.x"
repository: "oci://registry-1.docker.io/bitnamicharts"
condition: postgresql.enabledreplicaCount: 3
image:
repository: myregistry.io/myapp
tag: ""
pullPolicy: IfNotPresent
imagePullSecrets: []
serviceAccount:
create: true
annotations: {}
name: ""
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9090"
podSecurityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: [ALL]
service:
type: ClusterIP
port: 80
targetPort: 8080
ingress:
enabled: false
className: nginx
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
hosts:
- host: myapp.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: myapp-tls
hosts: [myapp.example.com]
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
autoscaling:
enabled: false
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 70
nodeSelector: {}
tolerations: []
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values: [myapp]
topologyKey: kubernetes.io/hostname
postgresql:
enabled: false_helpers.tpl{{- define "myapp.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- define "myapp.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{- define "myapp.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- define "myapp.labels" -}}
helm.sh/chart: {{ include "myapp.chart" . }}
{{ include "myapp.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{- define "myapp.selectorLabels" -}}
app.kubernetes.io/name: {{ include "myapp.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{- define "myapp.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "myapp.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
...
{{- end }}annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}env:
{{- range .Values.env }}
- name: {{ .name }}
value: {{ .value | quote }}
{{- end }}image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
replicas: {{ .Values.replicaCount | default 3 }}# 1. Static lint
helm lint ./mychart --strict
# 2. Render templates locally
helm template myapp ./mychart --debug --values values.yaml
# 3. Server-side dry-run (resolves lookup functions against the real API)
helm install myapp ./mychart \
--namespace prod \
--values values.yaml \
--dry-run=server --debug
# 4. Install
helm install myapp ./mychart \
--namespace prod \
--values values.yaml \
--atomic --wait
# 5. Post-deploy tests
helm test myapp --namespace prod --logs--dry-run=server--dry-runlookuphelm get manifest myapp -n prod
helm get values myapp -n prod --all
helm status myapp -n prod --show-resourceshelm upgrade myapp ./mychart -f values.yaml
helm upgrade --install myapp ./mychart
helm upgrade myapp ./mychart --atomic --timeout 5mhelm history myapp -n prod
helm rollback myapp 3 -n prod --cleanup-on-failhelm dependency list ./mychart
helm dependency update ./mychart
helm dependency build ./mycharthelm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm search repo postgresql
helm show values bitnami/postgresqlhelm repo add# Authenticate
helm registry login registry.example.com -u <user>
# Push a packaged chart
helm package ./mychart
helm push mychart-1.0.0.tgz oci://registry.example.com/charts
# Pull
helm pull oci://registry.example.com/charts/mychart --version 1.0.0
# Install directly from OCI
helm install myapp oci://registry.example.com/charts/mychart --version 1.0.0
# Template, show, upgrade all work with oci:// refs
helm show values oci://registry.example.com/charts/mychart --version 1.0.0Chart.yamldependencies:
- name: redis
version: "18.x.x"
repository: "oci://registry-1.docker.io/bitnamicharts"helm install myapp ./mychart --post-renderer ./kustomize-labels.sh
helm upgrade myapp ./mychart --post-renderer ./kustomize-labels.sh
helm template myapp ./mychart --post-renderer ./kustomize-labels.shrenderer1 | renderer2mychart/
values.yaml
values-dev.yaml
values-staging.yaml
values-prod.yamlhelm install myapp ./mychart -f values-prod.yaml -n productionapiVersion: batch/v1
kind: Job
metadata:
name: {{ include "myapp.fullname" . }}-migration
annotations:
"helm.sh/hook": pre-install,pre-upgrade
"helm.sh/hook-weight": "0"
"helm.sh/hook-delete-policy": before-hook-creation
spec:
template:
spec:
restartPolicy: Never
containers:
- name: migration
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
command: ["./migrate.sh"]apiVersion: v1
kind: Pod
metadata:
name: {{ include "myapp.fullname" . }}-test
annotations:
"helm.sh/hook": test
spec:
containers:
- name: curl
image: curlimages/curl:latest
command: ['curl']
args: ['{{ include "myapp.fullname" . }}:{{ .Values.service.port }}/health']
restartPolicy: Never| Symptom | Likely cause | Fix |
|---|---|---|
| Indentation error | Use |
| Missing value | Add |
| Wrong value type | Use |
| Conflicting release | Uninstall conflicting release or adopt resource |
| Wrong image name or missing pull secret | Fix image ref; create |
| CRD not installed | |
| Readiness probe failure or slow start | Increase |
| Hook job failed | Delete failed job; retry with |
--kube-context-nhelm --kube-context=prod-cluster status myapp -n prod
kubectl --context=prod-cluster get pods -n prodhelm template myapp ./mychart --debug 2>&1 | head -100{
"$schema": "https://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["replicaCount", "image"],
"properties": {
"replicaCount": { "type": "integer", "minimum": 1 },
"image": {
"type": "object",
"required": ["repository"],
"properties": {
"repository": { "type": "string" },
"tag": { "type": "string" }
}
}
}
}versionappVersionresourcesvalues.yamlNOTES.txtvalues.schema.jsonchecksum/config--atomic--dry-run=serverlookup.Values.*values.yamlkubectl--context_helpers.tpl--dry-runlookup--dry-run=server