mirror of
https://github.com/GothenburgBitFactory/taskchampion-sync-server.git
synced 2026-07-16 00:14:44 +00:00
Adding Helm chart
This commit is contained in:
committed by
Dustin J. Mitchell
parent
dd1b87dad5
commit
b98c87798c
5
helm/taskchampion-sync-server/.helmignore
Normal file
5
helm/taskchampion-sync-server/.helmignore
Normal file
@ -0,0 +1,5 @@
|
||||
# Patterns to ignore when building the Helm chart
|
||||
.git
|
||||
.gitignore
|
||||
*.md
|
||||
examples/
|
||||
15
helm/taskchampion-sync-server/Chart.yaml
Normal file
15
helm/taskchampion-sync-server/Chart.yaml
Normal file
@ -0,0 +1,15 @@
|
||||
apiVersion: v2
|
||||
name: taskchampion-sync-server
|
||||
description: A Helm chart for deploying TaskChampion Sync Server on Kubernetes
|
||||
type: application
|
||||
version: 0.1.0
|
||||
appVersion: "0.7.0"
|
||||
keywords:
|
||||
- taskchampion
|
||||
- taskwarrior
|
||||
- sync
|
||||
- task-management
|
||||
home: https://github.com/GothenburgBitFactory/taskchampion-sync-server
|
||||
sources:
|
||||
- https://github.com/GothenburgBitFactory/taskchampion-sync-server
|
||||
maintainers: []
|
||||
61
helm/taskchampion-sync-server/README.md
Normal file
61
helm/taskchampion-sync-server/README.md
Normal file
@ -0,0 +1,61 @@
|
||||
# TaskChampion Sync Server Helm Chart
|
||||
|
||||
Deploy the [TaskChampion Sync Server](https://github.com/GothenburgBitFactory/taskchampion-sync-server) on Kubernetes.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Kubernetes 1.23+
|
||||
- Helm 3+
|
||||
|
||||
## Storage Backends
|
||||
|
||||
Exactly one storage backend must be enabled. The chart will fail validation if both or neither are enabled.
|
||||
|
||||
### SQLite
|
||||
|
||||
```console
|
||||
helm install my-release ./helm/taskchampion-sync-server -f helm/taskchampion-sync-server/examples/sqlite-values.yaml
|
||||
```
|
||||
|
||||
### PostgreSQL
|
||||
|
||||
```console
|
||||
helm install my-release ./helm/taskchampion-sync-server -f helm/taskchampion-sync-server/examples/postgres-values.yaml
|
||||
```
|
||||
|
||||
## Secrets
|
||||
|
||||
The chart expects pre-created secrets referenced by name:
|
||||
|
||||
### Client ID Secret
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: my-client-ids
|
||||
type: Opaque
|
||||
data:
|
||||
client-ids: <base64-encoded comma-separated UUIDs>
|
||||
```
|
||||
|
||||
Reference it via `clientIdSecret: "my-client-ids"`.
|
||||
|
||||
### PostgreSQL Secret
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: my-postgres-creds
|
||||
type: Opaque
|
||||
data:
|
||||
connection: <base64-encoded LibPQ connection URI>
|
||||
password: <base64-encoded password>
|
||||
```
|
||||
|
||||
Reference it via `postgres.existingSecret: "my-postgres-creds"`.
|
||||
|
||||
## Configuration
|
||||
|
||||
See [values.yaml](values.yaml) for all configurable options.
|
||||
31
helm/taskchampion-sync-server/examples/postgres-values.yaml
Normal file
31
helm/taskchampion-sync-server/examples/postgres-values.yaml
Normal file
@ -0,0 +1,31 @@
|
||||
sqlite:
|
||||
enabled: false
|
||||
|
||||
postgres:
|
||||
enabled: true
|
||||
existingSecret: "taskchampion-postgres-creds"
|
||||
database: taskchampion
|
||||
host: postgres-primary
|
||||
username: taskchampion-user
|
||||
|
||||
clientIdSecret: "taskchampion-client-ids"
|
||||
|
||||
env:
|
||||
RUST_LOG: debug
|
||||
LISTEN: "0.0.0.0:8080"
|
||||
CREATE_CLIENTS: "false"
|
||||
|
||||
replicas:
|
||||
enabled: true
|
||||
count: 3
|
||||
|
||||
image:
|
||||
pullSecrets:
|
||||
- my-registry-secret
|
||||
|
||||
httpRoute:
|
||||
enabled: true
|
||||
gateway: "my-gateway"
|
||||
host: "taskchampion.example.com"
|
||||
path: "/"
|
||||
port: 8080
|
||||
22
helm/taskchampion-sync-server/examples/sqlite-values.yaml
Normal file
22
helm/taskchampion-sync-server/examples/sqlite-values.yaml
Normal file
@ -0,0 +1,22 @@
|
||||
sqlite:
|
||||
enabled: true
|
||||
existingPV: ""
|
||||
emptyDir:
|
||||
sizeLimit: 1Gi
|
||||
persistence:
|
||||
enabled: false
|
||||
|
||||
postgres:
|
||||
enabled: false
|
||||
|
||||
clientIdSecret: "taskchampion-client-ids"
|
||||
|
||||
env:
|
||||
RUST_LOG: info
|
||||
LISTEN: "0.0.0.0:8080"
|
||||
CREATE_CLIENTS: "false"
|
||||
|
||||
ingress:
|
||||
enabled: true
|
||||
hosts:
|
||||
- taskchampion.example.com
|
||||
41
helm/taskchampion-sync-server/templates/_helpers.tpl
Normal file
41
helm/taskchampion-sync-server/templates/_helpers.tpl
Normal file
@ -0,0 +1,41 @@
|
||||
{{- /*
|
||||
taskchampion-sync-server helpers
|
||||
*/ -}}
|
||||
|
||||
{{- define "taskchampion-sync-server.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "taskchampion-sync-server.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "taskchampion-sync-server.labels" -}}
|
||||
helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
app.kubernetes.io/name: {{ include "taskchampion-sync-server.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "taskchampion-sync-server.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "taskchampion-sync-server.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "taskchampion-sync-server.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "taskchampion-sync-server.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
100
helm/taskchampion-sync-server/templates/deployment.yaml
Normal file
100
helm/taskchampion-sync-server/templates/deployment.yaml
Normal file
@ -0,0 +1,100 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "taskchampion-sync-server.fullname" . }}
|
||||
labels:
|
||||
{{- include "taskchampion-sync-server.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if and (eq .Values.postgres.enabled true) .Values.replicas.enabled }}
|
||||
replicas: {{ .Values.replicas.count }}
|
||||
{{- else }}
|
||||
replicas: 1
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "taskchampion-sync-server.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "taskchampion-sync-server.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.image.pullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- range . }}
|
||||
- name: {{ . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: taskchampion-sync-server
|
||||
{{- if eq .Values.postgres.enabled true }}
|
||||
image: "{{ .Values.image.repository }}-postgres:{{ .Values.image.tag }}"
|
||||
{{- else }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
|
||||
{{- end }}
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
env:
|
||||
{{- range $name, $value := .Values.env }}
|
||||
- name: {{ $name }}
|
||||
value: {{ $value | quote }}
|
||||
{{- end }}
|
||||
{{- if .Values.clientIdSecret }}
|
||||
- name: CLIENT_ID
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.clientIdSecret }}
|
||||
key: client-ids
|
||||
{{- end }}
|
||||
{{- if eq .Values.sqlite.enabled true }}
|
||||
- name: DATA_DIR
|
||||
value: {{ .Values.sqlite.dataDir }}
|
||||
{{- end }}
|
||||
{{- if eq .Values.postgres.enabled true }}
|
||||
- name: CONNECTION
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ required "postgres.existingSecret is required when postgres is enabled" .Values.postgres.existingSecret }}
|
||||
key: connection
|
||||
optional: true
|
||||
- name: PGPASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.postgres.existingSecret }}
|
||||
key: password
|
||||
optional: true
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.service.targetPort }}
|
||||
protocol: TCP
|
||||
{{- with .Values.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if eq .Values.sqlite.enabled true }}
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: {{ .Values.sqlite.dataDir }}
|
||||
{{- end }}
|
||||
{{- if eq .Values.sqlite.enabled true }}
|
||||
volumes:
|
||||
{{- if .Values.sqlite.existingPV }}
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Values.sqlite.existingPV }}
|
||||
{{- else if .Values.sqlite.persistence.enabled }}
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ include "taskchampion-sync-server.fullname" . }}-pvc
|
||||
{{- else }}
|
||||
- name: data
|
||||
emptyDir:
|
||||
{{- if .Values.sqlite.emptyDir.sizeLimit }}
|
||||
sizeLimit: {{ .Values.sqlite.emptyDir.sizeLimit }}
|
||||
{{- end }}
|
||||
{{- if .Values.sqlite.emptyDir.medium }}
|
||||
medium: {{ .Values.sqlite.emptyDir.medium }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
23
helm/taskchampion-sync-server/templates/httproute.yaml
Normal file
23
helm/taskchampion-sync-server/templates/httproute.yaml
Normal file
@ -0,0 +1,23 @@
|
||||
{{- if .Values.httpRoute.enabled }}
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: {{ include "taskchampion-sync-server.fullname" . }}
|
||||
labels:
|
||||
{{- include "taskchampion-sync-server.labels" . | nindent 4 }}
|
||||
spec:
|
||||
parentRefs:
|
||||
- name: {{ .Values.httpRoute.gateway }}
|
||||
{{- if .Values.httpRoute.host }}
|
||||
hostnames:
|
||||
- {{ .Values.httpRoute.host }}
|
||||
{{- end }}
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: {{ .Values.httpRoute.path }}
|
||||
backendRefs:
|
||||
- name: {{ include "taskchampion-sync-server.fullname" . }}
|
||||
port: {{ .Values.httpRoute.port }}
|
||||
{{- end }}
|
||||
33
helm/taskchampion-sync-server/templates/ingress.yaml
Normal file
33
helm/taskchampion-sync-server/templates/ingress.yaml
Normal file
@ -0,0 +1,33 @@
|
||||
{{- if .Values.ingress.enabled }}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ include "taskchampion-sync-server.fullname" . }}
|
||||
labels:
|
||||
{{- include "taskchampion-sync-server.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .Values.ingress.className }}
|
||||
ingressClassName: {{ .Values.ingress.className }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.tls }}
|
||||
tls:
|
||||
{{- toYaml .Values.ingress.tls | nindent 4 }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.ingress.hosts }}
|
||||
- host: {{ . | quote }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "taskchampion-sync-server.fullname" $ }}
|
||||
port:
|
||||
number: {{ $.Values.service.port }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
17
helm/taskchampion-sync-server/templates/pvc.yaml
Normal file
17
helm/taskchampion-sync-server/templates/pvc.yaml
Normal file
@ -0,0 +1,17 @@
|
||||
{{- if and (eq .Values.sqlite.enabled true) .Values.sqlite.persistence.enabled (not .Values.sqlite.existingPV) }}
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ include "taskchampion-sync-server.fullname" . }}-pvc
|
||||
labels:
|
||||
{{- include "taskchampion-sync-server.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes:
|
||||
- {{ .Values.sqlite.persistence.accessMode }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.sqlite.persistence.size }}
|
||||
{{- if .Values.sqlite.persistence.storageClass }}
|
||||
storageClassName: {{ .Values.sqlite.persistence.storageClass }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
15
helm/taskchampion-sync-server/templates/service.yaml
Normal file
15
helm/taskchampion-sync-server/templates/service.yaml
Normal file
@ -0,0 +1,15 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "taskchampion-sync-server.fullname" . }}
|
||||
labels:
|
||||
{{- include "taskchampion-sync-server.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.service.port }}
|
||||
targetPort: {{ .Values.service.targetPort }}
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
{{- include "taskchampion-sync-server.selectorLabels" . | nindent 4 }}
|
||||
@ -0,0 +1,7 @@
|
||||
{{- if and (eq .Values.sqlite.enabled false) (eq .Values.postgres.enabled false) -}}
|
||||
{{- fail "ERROR: Exactly one storage backend must be enabled. Either sqlite.enabled or postgres.enabled must be true." -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- if and (eq .Values.sqlite.enabled true) (eq .Values.postgres.enabled true) -}}
|
||||
{{- fail "ERROR: Only one storage backend can be enabled. Both sqlite.enabled and postgres.enabled cannot be true at the same time." -}}
|
||||
{{- end -}}
|
||||
84
helm/taskchampion-sync-server/values.yaml
Normal file
84
helm/taskchampion-sync-server/values.yaml
Normal file
@ -0,0 +1,84 @@
|
||||
# Image configuration
|
||||
image:
|
||||
repository: ghcr.io/gothenburgbitfactory/taskchampion-sync-server
|
||||
tag: "0.7.0"
|
||||
pullPolicy: IfNotPresent
|
||||
pullSecrets: []
|
||||
|
||||
# Existing secret containing client IDs (comma-separated UUIDs)
|
||||
# Expected key: client-ids
|
||||
clientIdSecret: ""
|
||||
|
||||
# Environment variables passed directly to the container
|
||||
# NOTE: DATA_DIR and CONNECTION are set automatically based on backend
|
||||
env:
|
||||
RUST_LOG: info
|
||||
LISTEN: "0.0.0.0:8080"
|
||||
CREATE_CLIENTS: "false"
|
||||
|
||||
# Service configuration
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
|
||||
# Ingress configuration
|
||||
ingress:
|
||||
enabled: false
|
||||
className: ""
|
||||
annotations: {}
|
||||
hosts: []
|
||||
tls: []
|
||||
|
||||
# HTTPRoute configuration (Kubernetes Gateway API)
|
||||
httpRoute:
|
||||
enabled: false
|
||||
gateway: ""
|
||||
host: ""
|
||||
path: "/"
|
||||
port: 8080
|
||||
|
||||
# Resource limits and requests
|
||||
resources: {}
|
||||
# limits:
|
||||
# memory: 128Mi
|
||||
# cpu: 100m
|
||||
# requests:
|
||||
# memory: 64Mi
|
||||
# cpu: 50m
|
||||
|
||||
# Replica configuration (only applies when postgres is enabled)
|
||||
replicas:
|
||||
enabled: false
|
||||
count: 1
|
||||
|
||||
# Security context for the pod
|
||||
securityContext:
|
||||
runAsUser: 1092
|
||||
runAsGroup: 100
|
||||
fsGroup: 100
|
||||
|
||||
# SQLite backend configuration (mutually exclusive with postgres)
|
||||
sqlite:
|
||||
enabled: false
|
||||
dataDir: /var/lib/taskchampion-sync-server/data
|
||||
existingPV: ""
|
||||
emptyDir:
|
||||
sizeLimit: ""
|
||||
medium: ""
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 1Gi
|
||||
accessMode: ReadWriteOnce
|
||||
storageClass: ""
|
||||
existingClaim: ""
|
||||
|
||||
# PostgreSQL backend configuration (mutually exclusive with sqlite)
|
||||
postgres:
|
||||
enabled: false
|
||||
existingSecret: ""
|
||||
database: taskchampion
|
||||
host: postgres
|
||||
port: 5432
|
||||
username: user
|
||||
password: ""
|
||||
Reference in New Issue
Block a user