Helm Charts Deployment Setup
Helm is a package manager for Kubernetes. Helm Charts are parametrized Kubernetes manifest templates. Enable deploying to different environments with different parameters from a single template set.
Chart Structure
myapp/
├── Chart.yaml
├── values.yaml # default values
├── values.prod.yaml # production overrides
├── values.staging.yaml
└── templates/
├── deployment.yaml
├── service.yaml
├── ingress.yaml
├── hpa.yaml
├── configmap.yaml
├── secret.yaml
└── _helpers.tpl
Chart.yaml
apiVersion: v2
name: myapp
description: My web application
type: application
version: 1.0.0
appVersion: "latest"
dependencies:
- name: redis
version: "18.x.x"
repository: https://charts.bitnami.com/bitnami
condition: redis.enabled
values.yaml
replicaCount: 2
image:
repository: registry.example.com/myapp
tag: "latest"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
targetPort: 8080
ingress:
enabled: true
className: nginx
host: example.com
tls: true
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
autoscaling:
enabled: false
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 70
env:
APP_ENV: production
APP_URL: https://example.com
secrets:
APP_KEY: ""
DB_PASSWORD: ""
redis:
enabled: true
auth: { enabled: false }
templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "myapp.fullname" . }}
labels: {{ include "myapp.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels: {{ include "myapp.selectorLabels" . | nindent 6 }}
template:
metadata:
labels: {{ include "myapp.selectorLabels" . | nindent 8 }}
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 }}
envFrom:
- configMapRef:
name: {{ include "myapp.fullname" . }}
- secretRef:
name: {{ include "myapp.fullname" . }}
resources: {{ toYaml .Values.resources | nindent 12 }}
{{- if .Values.readinessProbe }}
readinessProbe: {{ toYaml .Values.readinessProbe | nindent 12 }}
{{- end }}
values.prod.yaml
replicaCount: 5
image:
tag: "v1.2.3"
ingress:
host: example.com
autoscaling:
enabled: true
maxReplicas: 20
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
Installation and Updates
# Add dependencies
helm dependency update ./myapp
# Dry run - show what will be created
helm install myapp ./myapp \
--namespace myapp \
--values values.yaml \
--values values.prod.yaml \
--set image.tag=v1.2.3 \
--dry-run --debug
# Install
helm install myapp ./myapp \
--namespace myapp --create-namespace \
--values values.prod.yaml \
--set secrets.APP_KEY="$APP_KEY" \
--set secrets.DB_PASSWORD="$DB_PASSWORD"
# Update
helm upgrade myapp ./myapp \
--namespace myapp \
--values values.prod.yaml \
--set image.tag=$NEW_TAG \
--atomic \
--timeout 5m
# Rollback
helm rollback myapp 1 --namespace myapp
# History
helm history myapp --namespace myapp
GitHub Actions
- name: Helm Deploy
run: |
helm upgrade --install myapp ./helm/myapp \
--namespace myapp --create-namespace \
--values helm/myapp/values.prod.yaml \
--set image.tag=${{ github.sha }} \
--set secrets.DB_PASSWORD=${{ secrets.DB_PASSWORD }} \
--atomic --timeout 5m
Timeline
Helm Chart development for typical application: 3–5 days. Helm + ArgoCD GitOps: +2–3 days.







