Helm Chart Development from Scratch
Build production-ready Helm charts with templates, values, helpers, hooks, tests, and CI validation. Complete guide from chart create to publishing.
π‘ Quick Answer: Build production-ready Helm charts with templates, values, helpers, hooks, tests, and CI validation. Complete guide from chart create to publishing.
The Problem
You need to package your Kubernetes application as a reusable, configurable Helm chart. This covers everything from helm create to publishing on a chart repository.
The Solution
Step 1: Create Chart Scaffold
helm create my-app
cd my-app
# Structure:
# Chart.yaml β metadata
# values.yaml β default configuration
# templates/ β Kubernetes manifests with Go templates
# templates/_helpers.tpl β reusable template functions
# templates/NOTES.txt β post-install message
# charts/ β dependenciesStep 2: Define Values Schema
# values.yaml
replicaCount: 2
image:
repository: myregistry.example.com/my-app
tag: "" # Defaults to chart appVersion
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
targetPort: 8080
ingress:
enabled: false
className: nginx
host: my-app.example.com
tls:
enabled: true
secretName: my-app-tls
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
autoscaling:
enabled: false
minReplicas: 2
maxReplicas: 10
targetCPUUtilization: 80
postgresql:
enabled: true
auth:
database: myapp
username: myappStep 3: Write Templates with Helpers
# templates/_helpers.tpl
{{- define "my-app.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- define "my-app.labels" -}}
helm.sh/chart: {{ include "my-app.chart" . }}
app.kubernetes.io/name: {{ include "my-app.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "my-app.name" . }}
labels:
{{- include "my-app.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
app.kubernetes.io/name: {{ include "my-app.name" . }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ include "my-app.name" . }}
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: {{ .Values.service.targetPort }}
{{- with .Values.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
livenessProbe:
httpGet:
path: /healthz
port: {{ .Values.service.targetPort }}
readinessProbe:
httpGet:
path: /ready
port: {{ .Values.service.targetPort }}Step 4: Add Tests
# templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "my-app.name" . }}-test"
annotations:
"helm.sh/hook": test
spec:
containers:
- name: wget
image: busybox
command: ['wget']
args: ['{{ include "my-app.name" . }}:{{ .Values.service.port }}/healthz']
restartPolicy: Never# Validate chart
helm lint my-app/
helm template my-app my-app/ --debug
# Test install
helm install my-app-test my-app/ --dry-run
# Run tests
helm test my-app-testStep 5: Package and Publish
# Package
helm package my-app/
# Push to OCI registry
helm push my-app-0.1.0.tgz oci://myregistry.example.com/charts
# Or push to ChartMuseum
curl --data-binary "@my-app-0.1.0.tgz" https://charts.example.com/api/chartsgraph TD
A[helm create] --> B[Edit values.yaml]
B --> C[Write templates]
C --> D[Add _helpers.tpl]
D --> E[helm lint]
E --> F[helm template --debug]
F --> G[helm install --dry-run]
G --> H[helm test]
H --> I[helm package]
I --> J[helm push to registry]Best Practices
- Start small and iterate β donβt over-engineer on day one
- Monitor and measure β you canβt improve what you donβt measure
- Automate repetitive tasks β reduce human error and toil
- Document your decisions β future you will thank present you
Key Takeaways
- This is essential knowledge for production Kubernetes operations
- Start with the simplest approach that solves your problem
- Monitor the impact of every change you make
- Share knowledge across your team with internal runbooks

Recommended
Kubernetes Recipes β The Complete Book100+ production-ready patterns with detailed explanations, best practices, and copy-paste YAML. Everything in one place.
Get the Book βLearn by Doing
CopyPasteLearn β Hands-on Cloud & DevOps CoursesMaster Kubernetes, Ansible, Terraform, and MLOps with interactive, copy-paste-run lessons. Start free.
Browse Courses βπ Deepen Your Skills β Hands-on Courses
Courses by CopyPasteLearn.com β Learn IT by Doing
