Skip to content
docktionary

Kubernetes

Helm

A package manager for Kubernetes. Instead of hand-editing a pile of YAML for every environment, Helm templates it and tracks each install as a versioned release.

The anatomy of a chart

text
docktionary-chart/
  Chart.yaml          # name, version, description
  values.yaml          # default configuration
  templates/
    deployment.yaml
    service.yaml
    ingress.yaml
    _helpers.tpl        # reusable template snippets

The Helm chart builder generates a working starting point for this exact shape (minus _helpers.tpl, skipped for a single-Deployment chart simple enough not to need it) from a form instead of a blank file.

Templating with values

values.yaml
replicaCount: 3
image:
  repository: docktionary/app
  tag: "1.4.0"
service:
  port: 80
resources:
  requests:
    cpu: 100m
    memory: 128Mi
templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app: {{ .Release.Name }}
  template:
    metadata:
      labels:
        app: {{ .Release.Name }}
    spec:
      containers:
        - name: app
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          resources:
            {{- toYaml .Values.resources | nindent 12 }}

{{ .Release.Name }} and {{ .Values.* }} are filled in at install time, from values.yaml and any --set flags, letting one chart describe dev, staging, and production with different values files instead of different copies of the YAML.

Installing and upgrading

terminal
helm install docktionary ./docktionary-chart \
  --values values-production.yaml

helm upgrade docktionary ./docktionary-chart \
  --set image.tag=1.5.0

helm list
helm status docktionary
helm rollback docktionary 1    # back to revision 1
helm uninstall docktionary

Previewing before you apply

Always render a chart before trusting it against a real cluster — it shows you exactly what would be applied, without touching anything.

terminal
helm template ./docktionary-chart --values values-production.yaml
helm install --dry-run --debug docktionary ./docktionary-chart

Public charts

You won't write a chart from scratch for most third-party software — search a repository first:

terminal
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm search repo postgresql
helm install my-db bitnami/postgresql --set auth.postgresPassword=secret

Chart dependencies

A chart can declare other charts as dependencies in Chart.yaml — the standard way to pull in a database or cache chart as a piece of your application's chart instead of installing it separately.

Chart.yaml
apiVersion: v2
name: docktionary-app
version: 1.0.0
dependencies:
  - name: postgresql
    version: "15.x"
    repository: https://charts.bitnami.com/bitnami
    condition: postgresql.enabled
terminal
helm dependency update ./docktionary-chart   # fetches dependencies into charts/
helm install docktionary ./docktionary-chart --set postgresql.enabled=true

Hooks

A hook is a manifest tagged to run at a specific point in a release's lifecycle — common for a one-off database migration that has to run after the new version is deployed but before it starts serving traffic.

templates/migrate-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: {{ .Release.Name }}-migrate
  annotations:
    "helm.sh/hook": post-upgrade
    "helm.sh/hook-weight": "0"
    "helm.sh/hook-delete-policy": hook-succeeded
spec:
  template:
    spec:
      restartPolicy: Never
      containers:
        - name: migrate
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          command: ["npm", "run", "migrate"]

post-upgrade (alongside pre-install, post-install, pre-upgrade, and others) controls when it runs; hook-weight orders multiple hooks at the same point; hook-delete-policy cleans the Job up automatically once it succeeds, so it doesn't pile up across releases.