app-template
Deploy applications using bjw-s/app-template Helm chart - a flexible chart for helmifying container images without dedicated charts. Use when: (1) Deploying container images that lack official Helm charts, (2) Creating HelmRelease manifests for Flux GitOps, (3) Configuring multi-container pods with sidecars, (4) Setting up persistent storage, ingress, services for custom applications, (5) Questions about app-template values structure or patterns, (6) Deploying any custom container to Kubernetes. Triggers: "deploy with app-template", "helmify this image", "create helm release for", "app-template values", "sidecar container", "multi-container pod helm", "deploy container image", "no helm chart available", "custom container deployment", "bjw-s", "app-template chart", "deploy docker image to kubernetes", "container without helm chart", "generic helm chart"
Installation
Suivez les instructions du dépôt pour votre agent. Consultez les fichiers et dépendances avant l’installation.
Voir la source ↗GuidesInstructions
app-template Helm Chart
The bjw-s/app-template chart deploys containerized applications without requiring a dedicated Helm chart. It provides a declarative interface for common Kubernetes resources.
Chart source: oci://ghcr.io/bjw-s-labs/helm/app-template
Schema: https://raw.githubusercontent.com/bjw-s-labs/helm-charts/app-template-4.6.0/charts/other/app-template/values.schema.json
Quick Start
Minimal values.yaml for a single-container deployment:
# yaml-language-server: $schema=https://raw.githubusercontent.com/bjw-s-labs/helm-charts/app-template-4.6.0/charts/other/app-template/values.schema.json
controllers:
main:
containers:
main:
image:
repository: nginx
tag: latest
service:
main:
controller: main
ports:
http:
port: 80
Core Structure
Controllers
Controllers define workload types. Each controller creates one Pod spec.
controllers:
main: # Controller identifier (arbitrary name)
type: deployment # deployment|statefulset|daemonset|cronjob|job
replicas: 1
strategy: Recreate # Recreate|RollingUpdate (deployment)
# Pod-level settings
pod:
securityContext:
fsGroup: 568
fsGroupChangePolicy: OnRootMismatch
containers:
main: # Container identifier
image:
repository: ghcr.io/org/app
tag: v1.0.0
env:
TZ: UTC
CONFIG_PATH: /config
Multiple Controllers
Create separate deployments in one release:
controllers:
web:
containers:
main:
image:
repository: nginx
tag: latest
worker:
type: deployment
replicas: 3
containers:
main:
image:
repository: myapp/worker
tag: v1.0.0
Sidecar Containers
Add sidecars with dependsOn for ordering:
controllers:
main:
containers:
main:
image:
repository: myapp
tag: v1.0.0
sidecar:
dependsOn: main # Start after main container
image:
repository: sidecar-image
tag: latest
args: ["--config", "/config/sidecar.yaml"]
Services
Services expose controller pods. Link via controller field.
service:
main:
controller: main # Links to controllers.main
type: ClusterIP # ClusterIP|LoadBalancer|NodePort
ports:
http:
port: 8080
metrics:
port: 9090
websocket:
controller: main
ports:
ws:
port: 3012
Ingress
ingress:
main:
className: nginx
hosts:
- host: app.example.com
paths:
- path: /
pathType: Prefix
service:
identifier: main # References service.main
port: http # References port name
tls:
- hosts:
- app.example.com
secretName: app-tls
Multiple paths to different services:
ingress:
main:
hosts:
- host: app.example.com
paths:
- path: /
service:
identifier: main
port: http
- path: /ws
service:
identifier: websocket
port: ws
Persistence
PersistentVolumeClaim
persistence:
config:
type: persistentVolumeClaim
accessMode: ReadWriteOnce
size: 1Gi
globalMounts:
- path: /config
Existing PVC
persistence:
config:
existingClaim: my-existing-pvc
globalMounts:
- path: /config
NFS Mount
persistence:
backup:
type: nfs
server: nas.local
path: /volume/backups
globalMounts:
- path: /backup
EmptyDir (Shared Between Containers)
persistence:
shared-data:
type: emptyDir
globalMounts:
- path: /shared
Advanced Mounts (Per-Controller/Container)
persistence:
config:
existingClaim: app-config
advancedMounts:
main: # Controller identifier
main: # Container identifier
- path: /config
sidecar:
- path: /config
readOnly: true
Environment Variables
Direct Values
controllers:
main:
containers:
main:
env:
TZ: UTC
LOG_LEVEL: info
TEMPLATE_VAR: "{{ .Release.Name }}"
From Secrets/ConfigMaps
controllers:
main:
containers:
main:
env:
DATABASE_URL:
valueFrom:
secretKeyRef:
name: db-secret
key: url
envFrom:
- secretRef:
name: app-secrets
- configMapRef:
name: app-config
Security Context
Pod-Level
defaultPodOptions:
securityContext:
runAsUser: 568
runAsGroup: 568
fsGroup: 568
fsGroupChangePolicy: OnRootMismatch
controllers:
main:
containers:
main:
image:
repository: myapp
tag: v1.0.0
Container-Level (Privileged Sidecar)
controllers:
main:
containers:
main:
securityContext:
runAsUser: 568
runAsGroup: 568
vpn:
image:
repository: vpn-client
tag: latest
securityContext:
capabilities:
add:
- NET_ADMIN
Probes
Default probes use TCP on the primary service port. Customize:
controllers:
main:
containers:
main:
probes:
liveness:
enabled: true
custom: true
spec:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 30
readiness:
enabled: true
type: HTTP
spec:
path: /ready
port: 8080
startup:
enabled: false
StatefulSet with VolumeClaimTemplates
controllers:
main:
type: statefulset
statefulset:
volumeClaimTemplates:
- name: data
accessMode: ReadWriteOnce
size: 10Gi
globalMounts:
- path: /data
CronJob
controllers:
backup:
type: cronjob
cronjob:
schedule: "0 2 * * *"
concurrencyPolicy: Forbid
successfulJobsHistory: 3
failedJobsHistory: 1
containers:
main:
image:
repository: backup-tool
tag: v1.0.0
args: ["--backup", "/data"]
ServiceMonitor (Prometheus)
serviceMonitor:
main:
enabled: true
serviceName: main
endpoints:
- port: metrics
scheme: http
path: /metrics
interval: 30s
Flux HelmRelease Integration
For this homelab, app-template deploys via Flux ResourceSet. Add to kubernetes/platform/helm-charts.yaml:
# In resourcesTemplate, the pattern generates HelmRelease automatically
# For app-template specifically, add to inputs:
- name: "my-app"
namespace: "default"
chart:
name: "app-template"
version: "4.6.0"
url: "oci://ghcr.io/bjw-s-labs/helm" # Note: OCI registry
dependsOn: [cilium]
Values go in kubernetes/platform/charts/my-app.yaml.
Common Patterns
See references/patterns.md for:
- VPN sidecar with gluetun
- Code-server sidecar for config editing
- Multi-service applications (websocket + http)
- Init containers for setup tasks
See references/values-reference.md for complete values.yaml documentation.
Exemples
Consultez les exemples du dépôt source.
Voir la source ↗Historique source
- Date d’indexation
- 2026-01-20
- Mise à jour de l’index
- 2026-01-26
- Branch
- main
Les dates concernent ce répertoire. Consultez le dépôt pour l’historique du code.
GitHub ↗chat Comments (0)
Sign in to join the discussion and leave a comment.
No comments yet. Be the first to share your thoughts!