feat: add Helm chart for Kubernetes deployment — thanks @another-novelty
* feat: Add basic helm chart * Delete chart/my-values.yaml
This commit is contained in:
committed by
Andrei Brebene
parent
a973a1b4f8
commit
d4899a8dee
5
chart/Chart.yaml
Normal file
5
chart/Chart.yaml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
apiVersion: v2
|
||||||
|
name: trek
|
||||||
|
version: 0.1.0
|
||||||
|
description: Minimal Helm chart for TREK app
|
||||||
|
appVersion: "latest"
|
||||||
33
chart/README.md
Normal file
33
chart/README.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# TREK Helm Chart
|
||||||
|
|
||||||
|
This is a minimal Helm chart for deploying the TREK app.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
- Deploys the TREK container
|
||||||
|
- Exposes port 3000 via Service
|
||||||
|
- Optional persistent storage for `/app/data` and `/app/uploads`
|
||||||
|
- Configurable environment variables and secrets
|
||||||
|
- Optional generic Ingress support
|
||||||
|
- Health checks on `/api/health`
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```sh
|
||||||
|
helm install trek ./chart \
|
||||||
|
--set secretEnv.JWT_SECRET=your_jwt_secret \
|
||||||
|
--set ingress.enabled=true \
|
||||||
|
--set ingress.hosts[0].host=yourdomain.com
|
||||||
|
```
|
||||||
|
|
||||||
|
See `values.yaml` for more options.
|
||||||
|
|
||||||
|
## Files
|
||||||
|
- `Chart.yaml` — chart metadata
|
||||||
|
- `values.yaml` — configuration values
|
||||||
|
- `templates/` — Kubernetes manifests
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
- Ingress is off by default. Enable and configure hosts for your domain.
|
||||||
|
- PVCs require a default StorageClass or specify one as needed.
|
||||||
|
- JWT_SECRET must be set for production use.
|
||||||
|
- If using ingress, you must manually keep `env.ALLOWED_ORIGINS` and `ingress.hosts` in sync to ensure CORS works correctly. The chart does not sync these automatically.
|
||||||
13
chart/templates/NOTES.txt
Normal file
13
chart/templates/NOTES.txt
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
1. JWT_SECRET handling:
|
||||||
|
- By default, the chart creates a secret with the value from `values.yaml: secretEnv.JWT_SECRET`.
|
||||||
|
- To generate a random JWT_SECRET at install, set `generateJwtSecret: true`.
|
||||||
|
- To use an existing Kubernetes secret, set `existingSecret` to the secret name. The secret must have a key matching `existingSecretKey` (defaults to `JWT_SECRET`).
|
||||||
|
|
||||||
|
2. Example usage:
|
||||||
|
- Set a custom secret: `--set secretEnv.JWT_SECRET=your_secret`
|
||||||
|
- Generate a random secret: `--set generateJwtSecret=true`
|
||||||
|
- Use an existing secret: `--set existingSecret=my-k8s-secret`
|
||||||
|
- Use a custom key in the existing secret: `--set existingSecret=my-k8s-secret --set existingSecretKey=MY_KEY`
|
||||||
|
|
||||||
|
3. Only one method should be used at a time. If both `generateJwtSecret` and `existingSecret` are set, `existingSecret` takes precedence.
|
||||||
|
If using `existingSecret`, ensure the referenced secret and key exist in the target namespace.
|
||||||
18
chart/templates/_helpers.tpl
Normal file
18
chart/templates/_helpers.tpl
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{{/*
|
||||||
|
Expand the name of the chart.
|
||||||
|
*/}}
|
||||||
|
{{- define "trek.name" -}}
|
||||||
|
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
|
||||||
|
{{- end -}}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Create a default fully qualified app name.
|
||||||
|
*/}}
|
||||||
|
{{- define "trek.fullname" -}}
|
||||||
|
{{- if .Values.fullnameOverride -}}
|
||||||
|
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- $name := default .Chart.Name .Values.nameOverride -}}
|
||||||
|
{{- printf "%s" $name | trunc 63 | trimSuffix "-" -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
12
chart/templates/configmap.yaml
Normal file
12
chart/templates/configmap.yaml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: {{ include "trek.fullname" . }}-config
|
||||||
|
labels:
|
||||||
|
app: {{ include "trek.name" . }}
|
||||||
|
data:
|
||||||
|
NODE_ENV: {{ .Values.env.NODE_ENV | quote }}
|
||||||
|
PORT: {{ .Values.env.PORT | quote }}
|
||||||
|
{{- if .Values.env.ALLOWED_ORIGINS }}
|
||||||
|
ALLOWED_ORIGINS: {{ .Values.env.ALLOWED_ORIGINS | quote }}
|
||||||
|
{{- end }}
|
||||||
61
chart/templates/deployment.yaml
Normal file
61
chart/templates/deployment.yaml
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: {{ include "trek.fullname" . }}
|
||||||
|
labels:
|
||||||
|
app: {{ include "trek.name" . }}
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: {{ include "trek.name" . }}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: {{ include "trek.name" . }}
|
||||||
|
spec:
|
||||||
|
{{- if .Values.imagePullSecrets }}
|
||||||
|
imagePullSecrets:
|
||||||
|
{{- range .Values.imagePullSecrets }}
|
||||||
|
- name: {{ .name }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
containers:
|
||||||
|
- name: trek
|
||||||
|
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
|
||||||
|
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||||
|
ports:
|
||||||
|
- containerPort: 3000
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: {{ include "trek.fullname" . }}-config
|
||||||
|
env:
|
||||||
|
- name: JWT_SECRET
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: {{ default (printf "%s-secret" (include "trek.fullname" .)) .Values.existingSecret }}
|
||||||
|
key: {{ .Values.existingSecretKey | default "JWT_SECRET" }}
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /app/data
|
||||||
|
- name: uploads
|
||||||
|
mountPath: /app/uploads
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /api/health
|
||||||
|
port: 3000
|
||||||
|
initialDelaySeconds: 15
|
||||||
|
periodSeconds: 30
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /api/health
|
||||||
|
port: 3000
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 10
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: {{ include "trek.fullname" . }}-data
|
||||||
|
- name: uploads
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: {{ include "trek.fullname" . }}-uploads
|
||||||
32
chart/templates/ingress.yaml
Normal file
32
chart/templates/ingress.yaml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
{{- if .Values.ingress.enabled }}
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: {{ include "trek.fullname" . }}
|
||||||
|
labels:
|
||||||
|
app: {{ include "trek.name" . }}
|
||||||
|
{{- with .Values.ingress.annotations }}
|
||||||
|
annotations:
|
||||||
|
{{- toYaml . | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
spec:
|
||||||
|
{{- if .Values.ingress.tls }}
|
||||||
|
tls:
|
||||||
|
{{- toYaml .Values.ingress.tls | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
rules:
|
||||||
|
{{- range .Values.ingress.hosts }}
|
||||||
|
- host: {{ .host }}
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
{{- range .paths }}
|
||||||
|
- path: {{ . }}
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: {{ include "trek.fullname" $ }}
|
||||||
|
port:
|
||||||
|
number: {{ $.Values.service.port }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
25
chart/templates/pvc.yaml
Normal file
25
chart/templates/pvc.yaml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: {{ include "trek.fullname" . }}-data
|
||||||
|
labels:
|
||||||
|
app: {{ include "trek.name" . }}
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: {{ .Values.persistence.data.size }}
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: {{ include "trek.fullname" . }}-uploads
|
||||||
|
labels:
|
||||||
|
app: {{ include "trek.name" . }}
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: {{ .Values.persistence.uploads.size }}
|
||||||
23
chart/templates/secret.yaml
Normal file
23
chart/templates/secret.yaml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{{- if and (not .Values.existingSecret) (not .Values.generateJwtSecret) }}
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: {{ include "trek.fullname" . }}-secret
|
||||||
|
labels:
|
||||||
|
app: {{ include "trek.name" . }}
|
||||||
|
type: Opaque
|
||||||
|
data:
|
||||||
|
{{ .Values.existingSecretKey | default "JWT_SECRET" }}: {{ .Values.secretEnv.JWT_SECRET | b64enc | quote }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{- if and (not .Values.existingSecret) (.Values.generateJwtSecret) }}
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: {{ include "trek.fullname" . }}-secret
|
||||||
|
labels:
|
||||||
|
app: {{ include "trek.name" . }}
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
{{ .Values.existingSecretKey | default "JWT_SECRET" }}: {{ randAlphaNum 32 }}
|
||||||
|
{{- end }}
|
||||||
15
chart/templates/service.yaml
Normal file
15
chart/templates/service.yaml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: {{ include "trek.fullname" . }}
|
||||||
|
labels:
|
||||||
|
app: {{ include "trek.name" . }}
|
||||||
|
spec:
|
||||||
|
type: {{ .Values.service.type }}
|
||||||
|
ports:
|
||||||
|
- port: {{ .Values.service.port }}
|
||||||
|
targetPort: 3000
|
||||||
|
protocol: TCP
|
||||||
|
name: http
|
||||||
|
selector:
|
||||||
|
app: {{ include "trek.name" . }}
|
||||||
53
chart/values.yaml
Normal file
53
chart/values.yaml
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
|
||||||
|
image:
|
||||||
|
repository: mauriceboe/trek
|
||||||
|
tag: latest
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
|
||||||
|
# Optional image pull secrets for private registries
|
||||||
|
imagePullSecrets: []
|
||||||
|
# - name: my-registry-secret
|
||||||
|
|
||||||
|
service:
|
||||||
|
type: ClusterIP
|
||||||
|
port: 3000
|
||||||
|
|
||||||
|
env:
|
||||||
|
NODE_ENV: production
|
||||||
|
PORT: 3000
|
||||||
|
# ALLOWED_ORIGINS: ""
|
||||||
|
# NOTE: If using ingress, ensure env.ALLOWED_ORIGINS matches the domains in ingress.hosts for proper CORS configuration.
|
||||||
|
|
||||||
|
|
||||||
|
# JWT secret configuration
|
||||||
|
secretEnv:
|
||||||
|
# If set, use this value for JWT_SECRET (base64-encoded in secret.yaml)
|
||||||
|
JWT_SECRET: ""
|
||||||
|
|
||||||
|
# If true, a random JWT_SECRET will be generated during install (overrides secretEnv.JWT_SECRET)
|
||||||
|
generateJwtSecret: false
|
||||||
|
|
||||||
|
# If set, use an existing Kubernetes secret for JWT_SECRET
|
||||||
|
existingSecret: ""
|
||||||
|
existingSecretKey: JWT_SECRET
|
||||||
|
|
||||||
|
persistence:
|
||||||
|
enabled: true
|
||||||
|
data:
|
||||||
|
size: 1Gi
|
||||||
|
uploads:
|
||||||
|
size: 1Gi
|
||||||
|
|
||||||
|
resources: {}
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
enabled: false
|
||||||
|
annotations: {}
|
||||||
|
hosts:
|
||||||
|
- host: chart-example.local
|
||||||
|
paths:
|
||||||
|
- /
|
||||||
|
tls: []
|
||||||
|
# - secretName: chart-example-tls
|
||||||
|
# hosts:
|
||||||
|
# - chart-example.local
|
||||||
Reference in New Issue
Block a user