helm-workload
A general-purpose Kubernetes workload Helm chart with batteries included. Deploy any container as a Deployment or StatefulSet with optional addon sidecars.
Installation
From OCI Registry
From Source
$ cd helm-workload
$ helm install my-release .
With Helmfile (recommended)
releases:
- name: my-app
namespace: my-namespace
chart: oci://ghcr.io/temikus/helm-charts/workload
version: 1.8.0
values:
- image:
repository: nginx
tag: stable
ports:
- name: http
port: 80
service:
enabled: true
port: 80
Features
Deployment & StatefulSet
Auto-selects workload type based on your persistence configuration. Supports rollout strategies for both.
Service & Ingress
Flexible port-to-service mapping with multi-port support. Extra services for UDP/mixed protocols via extraServices.
Persistence
PVC-backed storage with configurable access modes, storage class, and mount paths. StatefulSet VolumeClaimTemplates supported.
Autoscaling
HPA with CPU and memory targets using the autoscaling/v2 API.
NetworkPolicy
Restrict ingress traffic with auto-generated port rules or fully custom ingress specifications.
Addon Sidecars
VPN (Gluetun), PostgreSQL, Cloudflare Tunnel, and init containers — all opt-in via values.
Configuration
All configuration is done through values.yaml. Run helm show values oci://ghcr.io/temikus/helm-charts/workload for the full reference.
| Parameter | Description | Default |
|---|---|---|
image.repository | Container image repository | nginx |
image.tag | Container image tag | latest |
replicaCount | Number of replicas | 1 |
ports | List of container/service port definitions | [] |
persistence.enabled | Enable persistent storage | false |
ingress.enabled | Enable Ingress resource | false |
autoscaling.enabled | Enable HPA (autoscaling/v2) | false |
hostNetwork.enabled | Enable host networking | false |
strategy | Rollout strategy for Deployment or StatefulSet | {} |
networkPolicy.enabled | Create a NetworkPolicy restricting ingress | false |
extraServices | Additional multi-port Service resources | [] |
extraContainers | Additional sidecar containers | [] |
extraVolumes | Additional volumes to mount | [] |
Rollout Strategy
The strategy value maps to spec.strategy on Deployments and spec.updateStrategy on StatefulSets.
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
NetworkPolicy
Restrict ingress traffic with auto-generated port rules or explicit ingress specifications.
networkPolicy:
enabled: true
# Auto-allow ingress on all .Values.ports (default)
allowPortsIngress: true
# Or explicit rules:
ingress:
- ports:
- port: 80
protocol: TCP
from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: monitoring
Extra Services
Create additional Service resources alongside port-derived services, useful for UDP discovery or mixed-protocol setups.
extraServices:
- name: device-mgmt
type: LoadBalancer
ports:
- name: discovery
port: 29810
protocol: UDP
- name: manager
port: 29811
Addons
Addon sidecars are injected into the pod alongside your main container. All are disabled by default and configured under addons.*.
Init Container
Run an init container before the main application starts.
addons:
init:
enabled: true
image:
repository: busybox
tag: latest
command: ["sh", "-c", "echo initializing"]
VPN (Gluetun)
Adds a Gluetun VPN sidecar with OpenVPN or WireGuard support and multiple provider configurations.
addons:
vpn:
enabled: true
provider:
name: mullvad
type: wireguard
wireguard:
privateKey: "" # or use existingSecret
config:
timezone: UTC
serverSelection:
countries: Sweden
PostgreSQL
Deploys a separate PostgreSQL Deployment + Service. Applications connect via {fullname}-postgres:5432.
addons:
postgres:
enabled: true
auth:
username: myapp
password: secret # or use existingSecret
database: myapp_db
persistence:
enabled: true
size: 8Gi
Cloudflare Tunnel
Exposes your service through a Cloudflare Tunnel using cloudflare-operator. Supports optional path filtering via an nginx sidecar proxy and NetworkPolicy for defense-in-depth.
addons:
cloudflareTunnel:
enabled: true
fqdn: myapp.example.com
protocol: http
targetPort: 8080
tunnelRef:
kind: ClusterTunnel
name: my-cluster-tunnel
# Optional path filtering
pathFilter:
enabled: true
paths: ["/webhook", "/api"]
# Optional network policy
networkPolicy:
enabled: true
Examples
Simple container
image:
repository: quay.io/curl/curl
tag: latest
command: ["sleep", "infinity"]
Web application with Ingress and persistence
image:
repository: homebridge/homebridge
tag: "2024-01-08"
ports:
- name: http
port: 8581
service:
enabled: true
port: 8581
persistence:
enabled: true
type: statefulset
storageClassName: longhorn-retained
mountPath: /homebridge
accessModes: [ReadWriteOnce]
size: 5Gi
ingress:
enabled: true
hosts:
- host: homebridge.example.com
paths:
- path: /
pathType: ImplementationSpecific
tls:
- secretName: homebridge-tls
hosts: [homebridge.example.com]
Development
Prerequisites
- Helm 3.x
- helm-unittest plugin
- just (optional, for task automation)
Commands
$ just test # Run unit tests
$ just test -u # Update test snapshots
$ just build # Package the chart
Contributing
See CONTRIBUTING.md for guidelines on making changes, testing, and submitting pull requests.