improved helm chart

This commit is contained in:
Richard Tomik
2025-03-23 17:05:04 +01:00
parent 3d4cf1ae34
commit 3c21d77641
9 changed files with 515 additions and 58 deletions

View File

@ -3,4 +3,14 @@ name: donetick
description: A Helm chart for Donetick application
type: application
version: 0.1.0
appVersion: "latest"
appVersion: "latest"
maintainers:
- name: Richard Tomik
email: no@m.com
keywords:
- productivity
- task-management
- donetick
home: https://github.com/rtomik/helm-charts
sources:
- https://github.com/donetick/donetick

50
charts/donetick/NOTES.txt Normal file
View File

@ -0,0 +1,50 @@
1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
{{- range $host := .Values.ingress.hosts }}
{{- range .paths }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
{{- end }}
{{- end }}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "donetick.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "donetick.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "donetick.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "donetick.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
{{- end }}
2. Application is accessible at port {{ .Values.service.port }}
3. Donetick application is configured with:
- Database: {{ .Values.config.database.type }}
- User creation: {{ if .Values.config.is_user_creation_disabled }}disabled{{ else }}enabled{{ end }}
{{- if .Values.persistence.enabled }}
4. Data is persisted using PVC: {{ include "donetick.fullname" . }}-data
{{- else }}
4. WARNING: No persistence enabled. Data will be lost when pods are restarted.
{{- end }}
{{- if or .Values.config.jwt.existingSecret .Values.config.oauth2.existingSecret }}
5. Using external secrets for sensitive information:
{{- if .Values.config.jwt.existingSecret }}
- JWT secret from: {{ .Values.config.jwt.existingSecret }}
{{- end }}
{{- if .Values.config.oauth2.existingSecret }}
- OAuth2 credentials from: {{ .Values.config.oauth2.existingSecret }}
{{- end }}
{{- else }}
5. SECURITY NOTE: For production use, it's recommended to store sensitive data in Kubernetes Secrets.
- Set config.jwt.existingSecret to use an external secret for JWT
- Set config.oauth2.existingSecret to use an external secret for OAuth2 credentials
{{- end }}
For more information about using this Helm chart, please refer to the README.md file.

110
charts/donetick/readme.md Normal file
View File

@ -0,0 +1,110 @@
# Donetick Helm Chart
A Helm chart for deploying the Donetick task management application on Kubernetes.
## Introduction
This chart deploys [Donetick](https://github.com/donetick/donetick) on a Kubernetes cluster using the Helm package manager.
## Prerequisites
- Kubernetes 1.19+
- Helm 3.0+
- PV provisioner support in the underlying infrastructure (if persistence is needed)
## Installing the Chart
To install the chart with the release name `my-donetick`:
```bash
$ helm repo add donetick-chart https://rtomik.github.io/helm-charts
$ helm install my-donetick donetick-chart/donetick
```
> **Tip**: List all releases using `helm list`
## Uninstalling the Chart
To uninstall/delete the `my-donetick` deployment:
```bash
$ helm delete my-donetick
```
## Parameters
### Global parameters
| Name | Description | Value |
|------------------------|-------------------------------------------------------------------------------------|-------|
| `nameOverride` | String to partially override the release name | `""` |
| `fullnameOverride` | String to fully override the release name | `""` |
### Image parameters
| Name | Description | Value |
|-------------------------|--------------------------------------------------------------------------------------|--------------------|
| `image.repository` | Donetick image repository | `donetick/donetick` |
| `image.tag` | Donetick image tag | `latest` |
| `image.pullPolicy` | Donetick image pull policy | `IfNotPresent` |
| `imagePullSecrets` | Global Docker registry secret names as an array | `[]` |
### Secret Management
| Name | Description | Value |
|----------------------------------------|--------------------------------------------------------------------|---------------------|
| `config.jwt.existingSecret` | Name of existing secret for JWT token | `""` |
| `config.jwt.secretKey` | Key in the existing secret for JWT token | `"jwtSecret"` |
| `config.oauth2.existingSecret` | Name of existing secret for OAuth2 credentials | `""` |
| `config.oauth2.clientIdKey` | Key in the existing secret for OAuth2 client ID | `"client-id"` |
| `config.oauth2.clientSecretKey` | Key in the existing secret for OAuth2 client secret | `"client-secret"` |
| `config.database.existingSecret` | Name of existing secret for database credentials | `""` |
| `config.database.hostKey` | Key in the existing secret for database host | `"db-host"` |
| `config.database.portKey` | Key in the existing secret for database port | `"db-port"` |
| `config.database.userKey` | Key in the existing secret for database user | `"db-user"` |
| `config.database.passwordKey` | Key in the existing secret for database password | `"db-password"` |
| `config.database.nameKey` | Key in the existing secret for database name | `"db-name"` |
### Deployment parameters
| Name | Description | Value |
|--------------------------------------|--------------------------------------------------------------------------|-----------|
| `replicaCount` | Number of Donetick replicas | `1` |
| `revisionHistoryLimit` | Number of revisions to retain for rollback | `3` |
| `podSecurityContext.runAsNonRoot` | Run containers as non-root user | `true` |
| `podSecurityContext.runAsUser` | User ID for the container | `1000` |
| `podSecurityContext.fsGroup` | Group ID for the container filesystem | `1000` |
| `containerSecurityContext` | Security context for the container | See values.yaml |
| `nodeSelector` | Node labels for pod assignment | `{}` |
| `tolerations` | Tolerations for pod assignment | `[]` |
| `affinity` | Affinity for pod assignment | `{}` |
### Service parameters
| Name | Description | Value |
|----------------------------|------------------------------------------------------|-------------|
| `service.type` | Kubernetes Service type | `ClusterIP` |
| `service.port` | Service HTTP port | `2021` |
| `service.annotations` | Additional annotations for Service | `{}` |
| `service.nodePort` | Service HTTP node port (when applicable) | `""` |
### Ingress parameters
| Name | Description | Value |
|----------------------------|------------------------------------------------------|----------------------|
| `ingress.enabled` | Enable ingress record generation | `true` |
| `ingress.className` | IngressClass name | `"traefik"` |
| `ingress.annotations` | Additional annotations for the Ingress resource | See values.yaml |
| `ingress.hosts` | Array of host and path objects | See values.yaml |
| `ingress.tlsSecretName` | Global TLS secret name for all hosts | `""` |
| `ingress.tls` | TLS configuration | See values.yaml |
| `ingress.tls[].secretName` | Host-specific TLS secret name (overrides global) | `""` |
### Persistence parameters
| Name | Description | Value |
|-------------------------------|------------------------------------------------------|---------------|
| `persistence.enabled` | Enable persistence using PVC | `true` |
| `persistence.storageClass` | PVC Storage Class | `"longhorn"` |
| `persistence.accessMode` | PVC Access Mode | `ReadWriteOnce` |
| `persistence.size` |

View File

@ -16,41 +16,61 @@ data:
database:
type: {{ .Values.config.database.type | default "sqlite" | quote }}
migration: {{ .Values.config.database.migration }}
host: {{ .Values.config.database.host | default "secret" | quote }}
port: {{ .Values.config.database.port | default 5432 }}
user: {{ .Values.config.database.user | default "secret" | quote }}
password: {{ .Values.config.database.password | default "secret" | quote }}
name: {{ .Values.config.database.name | default "secret" | quote }}
{{- if .Values.config.database.migration_skip }}
migration_skip: {{ .Values.config.database.migration_skip }}
{{- end }}
{{- if .Values.config.database.migration_retry }}
migration_retry: {{ .Values.config.database.migration_retry }}
{{- end }}
{{- if eq .Values.config.database.type "postgres" }}
{{- if not .Values.config.database.existingSecret }}
host: {{ .Values.config.database.host | quote }}
port: {{ .Values.config.database.port }}
user: {{ .Values.config.database.user | quote }}
password: {{ .Values.config.database.password | quote }}
name: {{ .Values.config.database.name | quote }}
{{- else }}
# Database credentials will be injected via environment variables from Secret
{{- end }}
{{- end }}
jwt:
{{- if .Values.config.jwt.existingSecret }}
# Secret will be injected from Secret
{{- else }}
secret: {{ .Values.config.jwt.secret | quote }}
session_time: {{ .Values.config.jwt.session_time | default "168h" | quote }}
max_refresh: {{ .Values.config.jwt.max_refresh | default "168h" | quote }}
{{- end }}
session_time: {{ .Values.config.jwt.session_time | quote }}
max_refresh: {{ .Values.config.jwt.max_refresh | quote }}
server:
port: {{ .Values.config.server.port | default 2021 }}
read_timeout: {{ .Values.config.server.read_timeout | default "10s" | quote }}
write_timeout: {{ .Values.config.server.write_timeout | default "10s" | quote }}
rate_period: {{ .Values.config.server.rate_period | default "60s" | quote }}
rate_limit: {{ .Values.config.server.rate_limit | default 300 }}
port: {{ .Values.config.server.port }}
read_timeout: {{ .Values.config.server.read_timeout | quote }}
write_timeout: {{ .Values.config.server.write_timeout | quote }}
rate_period: {{ .Values.config.server.rate_period | quote }}
rate_limit: {{ .Values.config.server.rate_limit }}
cors_allow_origins:
{{- range .Values.config.server.cors_allow_origins }}
- {{ . | quote }}
{{- end }}
serve_frontend: {{ .Values.config.server.serve_frontend | default true }}
serve_frontend: {{ .Values.config.server.serve_frontend }}
scheduler_jobs:
due_job: {{ .Values.config.scheduler_jobs.due_job | default "30m" | quote }}
overdue_job: {{ .Values.config.scheduler_jobs.overdue_job | default "3h" | quote }}
pre_due_job: {{ .Values.config.scheduler_jobs.pre_due_job | default "3h" | quote }}
due_job: {{ .Values.config.scheduler_jobs.due_job | quote }}
overdue_job: {{ .Values.config.scheduler_jobs.overdue_job | quote }}
pre_due_job: {{ .Values.config.scheduler_jobs.pre_due_job | quote }}
email:
host: {{ .Values.config.email.host | quote }}
port: {{ .Values.config.email.port | quote }}
key: {{ .Values.config.email.key | quote }}
email: {{ .Values.config.email.email | quote }}
appHost: {{ .Values.config.email.appHost | quote }}
host: {{ .Values.config.email.host | default "" | quote }}
port: {{ .Values.config.email.port | default "" | quote }}
key: {{ .Values.config.email.key | default "" | quote }}
email: {{ .Values.config.email.email | default "" | quote }}
appHost: {{ .Values.config.email.appHost | default "" | quote }}
oauth2:
client_id: {{ .Values.config.oauth2.client_id | quote }}
client_secret: {{ .Values.config.oauth2.client_secret | quote }}
auth_url: {{ .Values.config.oauth2.auth_url | quote }}
token_url: {{ .Values.config.oauth2.token_url | quote }}
user_info_url: {{ .Values.config.oauth2.user_info_url | quote }}
redirect_url: {{ .Values.config.oauth2.redirect_url | quote }}
name: {{ .Values.config.oauth2.name | quote }}
{{- if .Values.config.oauth2.existingSecret }}
# Client ID and Secret will be injected from Secret
{{- else }}
client_id: {{ .Values.config.oauth2.client_id | default "" | quote }}
client_secret: {{ .Values.config.oauth2.client_secret | default "" | quote }}
{{- end }}
auth_url: {{ .Values.config.oauth2.auth_url | default "" | quote }}
token_url: {{ .Values.config.oauth2.token_url | default "" | quote }}
user_info_url: {{ .Values.config.oauth2.user_info_url | default "" | quote }}
redirect_url: {{ .Values.config.oauth2.redirect_url | default "" | quote }}
name: {{ .Values.config.oauth2.name | default "" | quote }}

View File

@ -4,35 +4,144 @@ metadata:
name: {{ include "donetick.fullname" . }}
labels:
{{- include "donetick.labels" . | nindent 4 }}
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
spec:
replicas: {{ .Values.replicaCount }}
revisionHistoryLimit: {{ .Values.revisionHistoryLimit }}
selector:
matchLabels:
{{- include "donetick.selectorLabels" . | nindent 6 }}
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
template:
metadata:
labels:
{{- include "donetick.selectorLabels" . | nindent 8 }}
annotations:
{{- with .Values.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.containerSecurityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
command: ["/donetick"]
{{- if .Values.startupArgs }}
args:
{{- range .Values.startupArgs }}
- {{ . | quote }}
{{- end }}
{{- end }}
ports:
- name: http
containerPort: 2021
containerPort: {{ .Values.config.server.port }}
protocol: TCP
{{- if .Values.probes.liveness.enabled }}
livenessProbe:
httpGet:
path: {{ .Values.probes.liveness.path }}
port: http
initialDelaySeconds: {{ .Values.probes.liveness.initialDelaySeconds }}
periodSeconds: {{ .Values.probes.liveness.periodSeconds }}
timeoutSeconds: {{ .Values.probes.liveness.timeoutSeconds }}
failureThreshold: {{ .Values.probes.liveness.failureThreshold }}
successThreshold: {{ .Values.probes.liveness.successThreshold }}
{{- end }}
{{- if .Values.probes.readiness.enabled }}
readinessProbe:
httpGet:
path: {{ .Values.probes.readiness.path }}
port: http
initialDelaySeconds: {{ .Values.probes.readiness.initialDelaySeconds }}
periodSeconds: {{ .Values.probes.readiness.periodSeconds }}
timeoutSeconds: {{ .Values.probes.readiness.timeoutSeconds }}
failureThreshold: {{ .Values.probes.readiness.failureThreshold }}
successThreshold: {{ .Values.probes.readiness.successThreshold }}
{{- end }}
env:
{{- range .Values.env }}
- name: {{ .name }}
value: {{ .value | quote }}
{{- end }}
{{- if or .Values.config.jwt.existingSecret .Values.config.oauth2.existingSecret .Values.config.database.existingSecret }}
# Secret-based environment variables
{{- if .Values.config.jwt.existingSecret }}
- name: DT_JWT_SECRET
valueFrom:
secretKeyRef:
name: {{ .Values.config.jwt.existingSecret }}
key: {{ .Values.config.jwt.secretKey }}
{{- end }}
{{- if .Values.config.oauth2.existingSecret }}
- name: DT_OAUTH2_CLIENT_ID
valueFrom:
secretKeyRef:
name: {{ .Values.config.oauth2.existingSecret }}
key: {{ .Values.config.oauth2.clientIdKey }}
- name: DT_OAUTH2_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: {{ .Values.config.oauth2.existingSecret }}
key: {{ .Values.config.oauth2.clientSecretKey }}
{{- end }}
{{- if and .Values.config.database.existingSecret (eq .Values.config.database.type "postgres") }}
- name: DT_DB_HOST
valueFrom:
secretKeyRef:
name: {{ .Values.config.database.existingSecret }}
key: {{ .Values.config.database.hostKey }}
- name: DT_DB_PORT
valueFrom:
secretKeyRef:
name: {{ .Values.config.database.existingSecret }}
key: {{ .Values.config.database.portKey }}
- name: DT_DB_USER
valueFrom:
secretKeyRef:
name: {{ .Values.config.database.existingSecret }}
key: {{ .Values.config.database.userKey }}
- name: DT_DB_PASSWORD
valueFrom:
secretKeyRef:
name: {{ .Values.config.database.existingSecret }}
key: {{ .Values.config.database.passwordKey }}
- name: DT_DB_NAME
valueFrom:
secretKeyRef:
name: {{ .Values.config.database.existingSecret }}
key: {{ .Values.config.database.nameKey }}
{{- end }}
{{- end }}
{{- with .Values.extraEnv }}
{{- toYaml . | nindent 12 }}
{{- end }}
volumeMounts:
- name: config
mountPath: /config
mountPath: /config
readOnly: true
- name: data
mountPath: /donetick-data
{{- if not .Values.containerSecurityContext.readOnlyRootFilesystem }}
- name: tmp
mountPath: /tmp
{{- end }}
{{- with .Values.extraVolumeMounts }}
{{- toYaml . | nindent 12 }}
{{- end }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumes:
@ -41,4 +150,23 @@ spec:
name: {{ include "donetick.fullname" . }}-configmap
- name: data
persistentVolumeClaim:
claimName: {{ include "donetick.fullname" . }}-data
claimName: {{ include "donetick.fullname" . }}-data
{{- if not .Values.containerSecurityContext.readOnlyRootFilesystem }}
- name: tmp
emptyDir: {}
{{- end }}
{{- with .Values.extraVolumes }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}

View File

@ -20,6 +20,9 @@ spec:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
{{- if .secretName }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
{{- end }}
rules:

View File

@ -5,6 +5,10 @@ metadata:
name: {{ include "donetick.fullname" . }}-data
labels:
{{- include "donetick.labels" . | nindent 4 }}
{{- with .Values.persistence.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
accessModes:
- {{ .Values.persistence.accessMode | quote }}

View File

@ -0,0 +1,22 @@
{{- if or (not .Values.config.jwt.existingSecret) (and (not .Values.config.oauth2.existingSecret) (or .Values.config.oauth2.client_id .Values.config.oauth2.client_secret)) (and (eq .Values.config.database.type "postgres") (not .Values.config.database.existingSecret)) }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "donetick.fullname" . }}-secrets
labels:
{{- include "donetick.labels" . | nindent 4 }}
type: Opaque
data:
{{- if not .Values.config.jwt.existingSecret }}
{{ .Values.config.jwt.secretKey }}: {{ .Values.config.jwt.secret | b64enc }}
{{- end }}
{{- if and (eq .Values.config.database.type "postgres") (not .Values.config.database.existingSecret) }}
{{ .Values.config.database.passwordKey }}: {{ .Values.config.database.password | b64enc }}
{{- end }}
{{- if and (not .Values.config.oauth2.existingSecret) .Values.config.oauth2.client_id }}
{{ .Values.config.oauth2.clientIdKey }}: {{ .Values.config.oauth2.client_id | b64enc }}
{{- end }}
{{- if and (not .Values.config.oauth2.existingSecret) .Values.config.oauth2.client_secret }}
{{ .Values.config.oauth2.clientSecretKey }}: {{ .Values.config.oauth2.client_secret | b64enc }}
{{- end }}
{{- end }}

View File

@ -1,43 +1,90 @@
## Global settings
nameOverride: ""
fullnameOverride: ""
## Image settings
image:
repository: donetick/donetick
tag: latest
pullPolicy: IfNotPresent
nameOverride: ""
fullnameOverride: ""
## Deployment settings
replicaCount: 1
revisionHistoryLimit: 3
# Optional startup arguments
startupArgs: []
# - "--skip-migrations" # Uncomment to skip database migrations on startup
# Pod security settings
podSecurityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
containerSecurityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
## Pod scheduling
nodeSelector: {}
tolerations: []
affinity: {}
## Service settings
service:
type: ClusterIP
port: 2021
## Ingress settings
ingress:
enabled: true
className: "traefik"
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
hosts:
- host: donetick.example.com
- host: donetick.tomik.lat
paths:
- path: /
pathType: Prefix
tls:
- hosts:
- donetick.example.com
- donetick.tomik.lat
# Optional: specify the name of an existing TLS secret
# secretName: "existing-tls-secret"
## Persistence settings
persistence:
enabled: true
storageClass: "longhorn"
accessMode: ReadWriteOnce
size: 1Gi
annotations: {}
## Environment variables
env:
- name: DT_ENV
value: selfhosted
- name: DT_SQLITE_PATH
value: /donetick-data/donetick.db
value: /donetick-data/donetick.db
# Extra environment variables (for advanced use cases)
extraEnv: []
# - name: DT_LOG_LEVEL
# value: "debug"
# - name: DT_SKIP_MIGRATIONS
# value: "true"
# Extra volume mounts
extraVolumeMounts: []
# Extra volumes
extraVolumes: []
## Resource limits and requests
resources:
limits:
cpu: 500m
@ -46,27 +93,78 @@ resources:
cpu: 100m
memory: 128Mi
## Application health checks
probes:
liveness:
enabled: true
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 6
successThreshold: 1
path: /health
readiness:
enabled: true
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
successThreshold: 1
path: /health
## Autoscaling configuration
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 5
targetCPUUtilizationPercentage: 80
targetMemoryUtilizationPercentage: 80
## Application configuration
config:
name: "selfhosted"
is_done_tick_dot_com: false
is_user_creation_disabled: false
# Notification settings
telegram:
token: ""
pushover:
token: ""
# Database configuration
database:
type: "sqlite"
migration: true
# these are only required for postgres
host: "secret"
# Migration options
migration_skip: false # Set to true to skip database migrations
migration_retry: 3 # Number of retries for failed migrations
# These are only required for postgres - direct configuration
host: ""
port: 5432
user: "secret"
password: "secret"
name: "secret"
user: ""
password: ""
name: ""
# Secret configuration for database credentials
existingSecret: "" # Name of existing Kubernetes secret
hostKey: "db-host" # Key in the secret for database host
portKey: "db-port" # Key in the secret for database port
userKey: "db-user" # Key in the secret for database user
passwordKey: "db-password" # Key in the secret for database password
nameKey: "db-name" # Key in the secret for database name
# Security settings
# For production, use a generated secret and store in a Kubernetes Secret
jwt:
secret: "secret"
existingSecret: "" # Set this to use an existing secret
secretKey: "jwtSecret" # The key in the secret where JWT secret is stored
secret: "changeme-this-secret-should-be-at-least-32-characters-long" # Only used if existingSecret is not set
session_time: 168h
max_refresh: 168h
# Server configuration
server:
port: 2021
read_timeout: 10s
@ -76,25 +174,37 @@ config:
cors_allow_origins:
- "http://localhost:5173"
- "http://localhost:7926"
# the below are required for the android app to work
# The below are required for the android app to work
- "https://localhost"
- "capacitor://localhost"
serve_frontend: true
# Scheduler configuration
scheduler_jobs:
due_job: 30m
overdue_job: 3h
pre_due_job: 3h
# Email settings
email:
host:
port:
key:
email:
appHost:
host: ""
port: ""
key: ""
email: ""
appHost: ""
# OAuth2 configuration
oauth2:
client_id:
client_secret:
auth_url:
token_url:
user_info_url:
redirect_url:
name:
# Direct configuration
client_id: ""
client_secret: ""
# Secret configuration - alternative to direct configuration
existingSecret: "" # Name of existing Kubernetes secret
clientIdKey: "client-id" # Key in the secret for client ID
clientSecretKey: "client-secret" # Key in the secret for client secret
# Other OAuth2 settings
auth_url: ""
token_url: ""
user_info_url: ""
redirect_url: ""
name: ""