Skip to content

Helm Charts Documentation

Overview

DineTogether uses Helm charts to standardize and simplify application deployments. We provide "golden charts" - pre-configured templates for common application types.

Golden Charts

Golden charts are maintained in the separate dine-together/app-charts repository and provide standardized deployments for:

Available Charts

Chart Name Application Type Default Port Use Case
nextjs-app Next.js/React 3000 Frontend applications
django-app Django/Python 8000 Backend APIs
nodejs-app Node.js/Express 3000 Microservices
static-site Static HTML 80 Documentation, landing pages

Chart Features

All golden charts include: - Deployment with configurable replicas and resources - Service for internal networking - Ingress for external access with SSL - ConfigMaps for configuration - Secrets integration - Health checks (liveness/readiness probes) - Prometheus metrics scraping annotations - HorizontalPodAutoscaler (optional) - PersistentVolumeClaims (optional)

Using Golden Charts

Basic Usage

Create a HelmRelease in the infrastructure repository:

apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: my-app
  namespace: staging
spec:
  interval: 5m
  chart:
    spec:
      chart: nextjs-app  # Choose appropriate chart
      sourceRef:
        kind: GitRepository
        name: app-charts
        namespace: flux-system
      version: "1.0.0"  # Or use "*" for latest
  values:
    # Override default values here
    image:
      repository: ghcr.io/dine-together/my-app
      tag: sha-abc123

Common Values

All golden charts accept these standard values:

# Image configuration
image:
  repository: ghcr.io/dine-together/app-name
  tag: latest
  pullPolicy: IfNotPresent

# Replicas and scaling
replicaCount: 1
autoscaling:
  enabled: false
  minReplicas: 1
  maxReplicas: 10
  targetCPUUtilizationPercentage: 80

# Service configuration
service:
  type: ClusterIP
  port: 3000  # Application-specific default

# Ingress configuration
ingress:
  enabled: true
  className: nginx
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
  hosts:
    - host: app.staging.dinetogether.co.uk
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: app-tls
      hosts:
        - app.staging.dinetogether.co.uk

# Resources
resources:
  requests:
    cpu: 100m
    memory: 256Mi
  limits:
    cpu: 500m
    memory: 512Mi

# Environment variables
env:
  - name: NODE_ENV
    value: production
  - name: API_URL
    value: https://api.staging.dinetogether.co.uk

# Secret references
secretRefs:
  - name: app-secrets

# Health checks
livenessProbe:
  httpGet:
    path: /health
    port: http
  initialDelaySeconds: 30
  periodSeconds: 10

readinessProbe:
  httpGet:
    path: /ready
    port: http
  initialDelaySeconds: 5
  periodSeconds: 5

# Monitoring
metrics:
  enabled: true
  path: /metrics
  port: 3000

Chart-Specific Values

nextjs-app

# Next.js specific
nextConfig:
  basePath: ""
  generateBuildId: true

# Static file serving
staticFiles:
  enabled: true
  path: /public

# API routes
api:
  timeout: 30
  bodyLimit: "1mb"

django-app

# Django specific
django:
  collectstatic: true
  migrate: true
  debug: false
  allowedHosts: "*"

# Database
postgresql:
  enabled: true
  auth:
    database: app
    username: app
    password: changeme  # Use secrets!

# Redis cache
redis:
  enabled: true
  auth:
    enabled: true
    password: changeme  # Use secrets!

# Celery workers
celery:
  enabled: false
  workers: 2
  queues: "default,high_priority"

nodejs-app

# Node.js specific
node:
  env: production
  maxOldSpaceSize: 512

# PM2 configuration (if used)
pm2:
  enabled: false
  instances: 2
  execMode: cluster

Advanced Configurations

Multi-Container Pods

For applications requiring sidecars:

additionalContainers:
  - name: cloudsql-proxy
    image: gcr.io/cloudsql-docker/gce-proxy:latest
    command:
      - "/cloud_sql_proxy"
      - "-instances=project:region:instance=tcp:5432"

Init Containers

For initialization tasks:

initContainers:
  - name: migration
    image: ghcr.io/dine-together/my-app:sha-abc123
    command: ["python", "manage.py", "migrate"]

Volume Mounts

For persistent storage:

persistence:
  enabled: true
  storageClass: standard
  size: 10Gi
  mountPath: /data
  accessMode: ReadWriteOnce

Network Policies

For security:

networkPolicy:
  enabled: true
  ingress:
    - from:
      - namespaceSelector:
          matchLabels:
            name: staging

Creating Custom Charts

If golden charts don't meet your needs, create custom charts:

Chart Structure

my-custom-chart/
├── Chart.yaml
├── values.yaml
├── templates/
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   ├── configmap.yaml
│   ├── secret.yaml
│   ├── hpa.yaml
│   └── _helpers.tpl
└── README.md

Chart.yaml

apiVersion: v2
name: my-custom-chart
description: A custom Helm chart for my application
type: application
version: 1.0.0
appVersion: "1.0"

Templates Best Practices

  1. Use helpers for repeated values:

    {{- define "mychart.fullname" -}}
    {{- printf "%s-%s" .Release.Name .Chart.Name | trunc 63 | trimSuffix "-" -}}
    {{- end }}
    

  2. Make everything configurable:

    replicas: {{ .Values.replicaCount }}
    

  3. Include sensible defaults:

    {{- .Values.service.port | default 3000 }}
    

  4. Add conditions for optional features:

    {{- if .Values.ingress.enabled }}
    # Ingress manifest
    {{- end }}
    

Testing Charts

Local Testing

# Lint chart
helm lint my-chart/

# Dry run
helm install my-app my-chart/ --dry-run --debug

# Template rendering
helm template my-app my-chart/

In-Cluster Testing

# Install
helm install my-app my-chart/ -n staging

# Upgrade
helm upgrade my-app my-chart/ -n staging

# Rollback
helm rollback my-app -n staging

Debugging

Common Issues

Image Pull Errors:

imagePullSecrets:
  - name: ghcr-credentials

Resource Constraints:

resources:
  requests:
    memory: "256Mi"  # Increase if OOMKilled
    cpu: "100m"
  limits:
    memory: "512Mi"
    cpu: "500m"

Probe Failures:

livenessProbe:
  initialDelaySeconds: 60  # Increase for slow-starting apps
  failureThreshold: 3

Debugging Commands

# Get Helm releases
helm list -n staging

# Get release values
helm get values my-app -n staging

# Get release history
helm history my-app -n staging

# Get manifest
helm get manifest my-app -n staging

Best Practices

  1. Version your charts - Use semantic versioning
  2. Document values - Add descriptions in values.yaml
  3. Use secrets properly - Never hardcode sensitive data
  4. Set resource limits - Prevent resource exhaustion
  5. Configure health checks - Ensure proper readiness/liveness
  6. Enable monitoring - Add Prometheus annotations
  7. Test thoroughly - Use staging before production
  8. Keep charts simple - Avoid over-engineering

Migration Guide

From Raw Manifests to Helm

  1. Identify resources - List all K8s resources
  2. Create templates - Convert to Helm templates
  3. Extract values - Make configurable parts into values
  4. Add conditionals - Make optional features toggleable
  5. Test migration - Deploy to staging first

From Docker Compose

Docker Compose concepts map to Helm as follows:

Docker Compose Helm Chart
service Deployment + Service
ports Service.port + Ingress
volumes PersistentVolumeClaim
networks Service networking
environment ConfigMap/Secret
depends_on Init containers

References