enhance donetick helm chart with missing features and repository standards…

This commit is contained in:
Richard Tomik
2025-09-21 18:31:04 +02:00
parent 509492560e
commit 741401a79d
6 changed files with 440 additions and 18 deletions

View File

@ -2,8 +2,8 @@ apiVersion: v2
name: donetick
description: Donetick helm chart for Kubernetes
type: application
version: 1.0.1
appVersion: "v0.1.38"
version: 1.0.2
appVersion: "v0.1.60"
maintainers:
- name: Richard Tomik
email: no@m.com

View File

@ -27,12 +27,184 @@ $ helm install donetick donetick-chart/donetick
> **Tip**: List all releases using `helm list`
## Configuration Examples
### Basic Installation with SQLite (Default)
```bash
helm install donetick donetick-chart/donetick
```
### Installation with External PostgreSQL
Create a values file for PostgreSQL configuration:
```yaml
# values-postgres.yaml
config:
database:
type: "postgres"
host: "postgresql.database.svc.cluster.local"
port: 5432
user: "donetick"
password: "your-secure-password"
name: "donetick"
migration: true
# Update JWT secret for production
jwt:
secret: "your-secure-jwt-secret-at-least-32-characters-long"
# Configure server settings
server:
cors_allow_origins:
- "https://your-domain.com"
- "http://localhost:5173"
# Enable features as needed
features:
notifications: true
realtime: true
oauth: false
# Enable ingress for external access
ingress:
enabled: true
className: "nginx"
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
hosts:
- host: donetick.your-domain.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: donetick-tls
hosts:
- donetick.your-domain.com
# Configure persistence
persistence:
enabled: true
storageClass: "fast-ssd"
size: "5Gi"
```
Install with PostgreSQL configuration:
```bash
helm install donetick donetick-chart/donetick -f values-postgres.yaml
```
### Production Installation with External Secrets
For production deployments, use Kubernetes secrets for sensitive data:
```yaml
# values-production.yaml
config:
database:
type: "postgres"
host: "postgresql.database.svc.cluster.local"
port: 5432
user: "donetick"
name: "donetick"
# Use existing secret for database credentials
existingSecret: "donetick-db-secret"
passwordKey: "postgresql-password"
# Use existing secret for JWT
jwt:
existingSecret: "donetick-jwt-secret"
secretKey: "jwt-secret"
session_time: "168h"
max_refresh: "168h"
# OAuth2 configuration with secrets
oauth2:
existingSecret: "donetick-oauth-secret"
clientIdKey: "client-id"
clientSecretKey: "client-secret"
auth_url: "https://your-oauth-provider.com/auth"
token_url: "https://your-oauth-provider.com/token"
user_info_url: "https://your-oauth-provider.com/userinfo"
redirect_url: "https://donetick.your-domain.com/auth/callback"
# Production server settings
server:
cors_allow_origins:
- "https://donetick.your-domain.com"
rate_limit: 100
rate_period: "60s"
# Enable production features
features:
notifications: true
realtime: true
oauth: true
# Security context for production
podSecurityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
# Resource limits for production
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
# Ingress with TLS
ingress:
enabled: true
className: "nginx"
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
hosts:
- host: donetick.your-domain.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: donetick-tls
hosts:
- donetick.your-domain.com
```
Create the required secrets:
```bash
# Database secret
kubectl create secret generic donetick-db-secret \
--from-literal=postgresql-password='your-secure-db-password'
# JWT secret
kubectl create secret generic donetick-jwt-secret \
--from-literal=jwt-secret='your-very-secure-jwt-secret-at-least-32-characters-long'
# OAuth secret (if using OAuth)
kubectl create secret generic donetick-oauth-secret \
--from-literal=client-id='your-oauth-client-id' \
--from-literal=client-secret='your-oauth-client-secret'
```
Install with production configuration:
```bash
helm install donetick donetick-chart/donetick -f values-production.yaml
```
## Uninstalling the Chart
To uninstall/delete the `donetick` deployment:
```bash
$ helm uninstall donetick
helm uninstall donetick
```
## Parameters
@ -49,7 +221,7 @@ $ helm uninstall donetick
| Name | Description | Value |
|-------------------------|--------------------------------------------------------------------------------------|--------------------|
| `image.repository` | Donetick image repository | `donetick/donetick` |
| `image.tag` | Donetick image tag | `latest` |
| `image.tag` | Donetick image tag | `v0.1.60` |
| `image.pullPolicy` | Donetick image pull policy | `IfNotPresent` |
| `imagePullSecrets` | Global Docker registry secret names as an array | `[]` |
@ -90,7 +262,12 @@ $ helm uninstall donetick
| `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) | `""` |
### Pod Configuration
| Name | Description | Value |
|----------------------------|------------------------------------------------------|-------------|
| `podAnnotations` | Additional annotations for pods | `{}` |
### Ingress parameters
@ -108,7 +285,174 @@ $ helm uninstall donetick
| Name | Description | Value |
|-------------------------------|------------------------------------------------------|---------------|
| `persistence.enabled` | Enable persistence using PVC | `true` |
| `persistence.storageClass` | PVC Storage Class | `"longhorn"` |
| `persistence.enabled` | Enable persistence using PVC | `false` |
| `persistence.storageClass` | PVC Storage Class | `""` |
| `persistence.accessMode` | PVC Access Mode | `ReadWriteOnce` |
| `persistence.size` |
| `persistence.size` | PVC Size | `1Gi` |
### Health Checks
| Name | Description | Value |
|----------------------------------------|------------------------------------------------------|---------------|
| `probes.startup.enabled` | Enable startup probe | `true` |
| `probes.startup.initialDelaySeconds` | Initial delay for startup probe | `10` |
| `probes.startup.periodSeconds` | Period for startup probe | `10` |
| `probes.startup.failureThreshold` | Failure threshold for startup probe | `30` |
| `probes.liveness.enabled` | Enable liveness probe | `true` |
| `probes.liveness.initialDelaySeconds` | Initial delay for liveness probe | `30` |
| `probes.liveness.periodSeconds` | Period for liveness probe | `10` |
| `probes.readiness.enabled` | Enable readiness probe | `true` |
| `probes.readiness.initialDelaySeconds` | Initial delay for readiness probe | `5` |
| `probes.readiness.periodSeconds` | Period for readiness probe | `5` |
### Application Configuration
| Name | Description | Value |
|----------------------------------------|------------------------------------------------------|---------------|
| `config.name` | Application name | `selfhosted` |
| `config.is_done_tick_dot_com` | Enable donetick.com features | `false` |
| `config.is_user_creation_disabled` | Disable user registration | `false` |
### Real-time Configuration
| Name | Description | Value |
|----------------------------------------|------------------------------------------------------|---------------|
| `config.realtime.max_connections` | Maximum WebSocket connections | `100` |
| `config.realtime.ping_interval` | WebSocket ping interval | `30s` |
| `config.realtime.pong_wait` | WebSocket pong wait timeout | `60s` |
| `config.realtime.write_wait` | WebSocket write timeout | `10s` |
| `config.realtime.max_message_size` | Maximum WebSocket message size | `512` |
### Database Configuration
| Name | Description | Value |
|----------------------------------------|------------------------------------------------------|---------------|
| `config.database.type` | Database type (sqlite or postgres) | `sqlite` |
| `config.database.migration` | Enable database migrations | `true` |
| `config.database.host` | PostgreSQL host (when type=postgres) | `""` |
| `config.database.port` | PostgreSQL port (when type=postgres) | `5432` |
| `config.database.user` | PostgreSQL user (when type=postgres) | `""` |
| `config.database.password` | PostgreSQL password (when type=postgres) | `""` |
| `config.database.name` | PostgreSQL database name (when type=postgres) | `""` |
### JWT Configuration
| Name | Description | Value |
|----------------------------------------|------------------------------------------------------|---------------|
| `config.jwt.secret` | JWT signing secret | `changeme-this-secret-should-be-at-least-32-characters-long` |
| `config.jwt.session_time` | JWT session duration | `168h` |
| `config.jwt.max_refresh` | JWT maximum refresh duration | `168h` |
### Server Configuration
| Name | Description | Value |
|----------------------------------------|------------------------------------------------------|---------------|
| `config.server.port` | Server port | `2021` |
| `config.server.read_timeout` | Server read timeout | `10s` |
| `config.server.write_timeout` | Server write timeout | `10s` |
| `config.server.rate_period` | Rate limiting period | `60s` |
| `config.server.rate_limit` | Rate limiting requests per period | `300` |
| `config.server.serve_frontend` | Serve frontend files | `true` |
### Feature Flags
| Name | Description | Value |
|----------------------------------------|------------------------------------------------------|---------------|
| `config.features.notifications` | Enable notifications | `true` |
| `config.features.realtime` | Enable real-time features | `true` |
| `config.features.oauth` | Enable OAuth authentication | `false` |
## Database Setup
### PostgreSQL Requirements
When using PostgreSQL, ensure you have:
1. **Database Created**: Create a database for Donetick
```sql
CREATE DATABASE donetick;
CREATE USER donetick WITH PASSWORD 'your-secure-password';
GRANT ALL PRIVILEGES ON DATABASE donetick TO donetick;
```
2. **Network Access**: Ensure Donetick can reach your PostgreSQL instance
3. **Proper Credentials**: Configure database credentials in values or secrets
### Database Migration
Donetick automatically runs database migrations on startup when `config.database.migration: true`. For production:
1. **Review Migrations**: Check what migrations will be applied
2. **Backup Database**: Always backup before running migrations
3. **Monitor Startup**: Watch pod logs during initial deployment
## Troubleshooting
### Common Issues
#### 1. Real-time Configuration Panic
**Error**: `Invalid real-time configuration: maxConnections must be positive, got 0`
**Solution**: Ensure the real-time configuration is properly set:
```yaml
config:
realtime:
max_connections: 100 # Must be > 0
```
#### 2. Database Connection Issues
**Error**: Database connection failures
**Solutions**:
- Verify PostgreSQL is running and accessible
- Check database credentials in secrets
- Ensure database name exists
- Verify network policies allow connection
#### 3. JWT Secret Issues
**Error**: JWT authentication failures
**Solution**: Ensure JWT secret is at least 32 characters:
```yaml
config:
jwt:
secret: "your-very-secure-jwt-secret-at-least-32-characters-long"
```
#### 4. CORS Issues
**Error**: Cross-origin request blocked
**Solution**: Configure CORS origins:
```yaml
config:
server:
cors_allow_origins:
- "https://your-domain.com"
- "http://localhost:5173"
```
### Debugging
Check application logs:
```bash
kubectl logs deployment/donetick -f
```
Check configuration:
```bash
kubectl get configmap donetick-configmap -o yaml
```
Verify secrets:
```bash
kubectl get secret donetick-secrets -o yaml
```
## Contributing
Please feel free to contribute by opening issues or pull requests at:
https://github.com/rtomik/helm-charts
## License
This Helm chart is licensed under the MIT License.

View File

@ -75,3 +75,19 @@ data:
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 }}
realtime:
max_connections: {{ .Values.config.realtime.max_connections }}
ping_interval: {{ .Values.config.realtime.ping_interval | quote }}
pong_wait: {{ .Values.config.realtime.pong_wait | quote }}
write_wait: {{ .Values.config.realtime.write_wait | quote }}
max_message_size: {{ .Values.config.realtime.max_message_size }}
logging:
level: {{ .Values.config.logging.level | quote }}
format: {{ .Values.config.logging.format | quote }}
storage:
type: {{ .Values.config.storage.type | quote }}
path: {{ .Values.config.storage.path | quote }}
features:
notifications: {{ .Values.config.features.notifications }}
realtime: {{ .Values.config.features.realtime }}
oauth: {{ .Values.config.features.oauth }}

View File

@ -50,6 +50,17 @@ spec:
- name: http
containerPort: {{ .Values.config.server.port }}
protocol: TCP
{{- if .Values.probes.startup.enabled }}
startupProbe:
httpGet:
path: {{ .Values.probes.startup.path }}
port: http
initialDelaySeconds: {{ .Values.probes.startup.initialDelaySeconds }}
periodSeconds: {{ .Values.probes.startup.periodSeconds }}
timeoutSeconds: {{ .Values.probes.startup.timeoutSeconds }}
failureThreshold: {{ .Values.probes.startup.failureThreshold }}
successThreshold: {{ .Values.probes.startup.successThreshold }}
{{- end }}
{{- if .Values.probes.liveness.enabled }}
livenessProbe:
httpGet:
@ -148,9 +159,14 @@ spec:
- name: config
configMap:
name: {{ include "donetick.fullname" . }}-configmap
{{- if .Values.persistence.enabled }}
- name: data
persistentVolumeClaim:
claimName: {{ include "donetick.fullname" . }}-data
{{- else }}
- name: data
emptyDir: {}
{{- end }}
{{- if not .Values.containerSecurityContext.readOnlyRootFilesystem }}
- name: tmp
emptyDir: {}

View File

@ -4,6 +4,10 @@ metadata:
name: {{ include "donetick.fullname" . }}
labels:
{{- include "donetick.labels" . | nindent 4 }}
{{- with .Values.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.service.type }}
ports:

View File

@ -5,9 +5,11 @@ fullnameOverride: ""
## Image settings
image:
repository: donetick/donetick
tag: "v0.1.38"
tag: "v0.1.60"
pullPolicy: IfNotPresent
imagePullSecrets: []
## Deployment settings
replicaCount: 1
revisionHistoryLimit: 3
@ -34,10 +36,14 @@ nodeSelector: {}
tolerations: []
affinity: {}
## Pod annotations
podAnnotations: {}
## Service settings
service:
type: ClusterIP
port: 2021
annotations: {}
## Ingress settings
ingress:
@ -85,16 +91,28 @@ extraVolumeMounts: []
extraVolumes: []
## Resource limits and requests
# resources:
# limits:
# cpu: 500m
# memory: 512Mi
# requests:
# cpu: 100m
# memory: 128Mi
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 500m
# memory: 512Mi
# requests:
# cpu: 100m
# memory: 128Mi
## Application health checks
probes:
startup:
enabled: true
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 30
successThreshold: 1
path: /health
liveness:
enabled: true
initialDelaySeconds: 30
@ -208,3 +226,27 @@ config:
user_info_url: ""
redirect_url: ""
name: ""
# Real-time configuration
realtime:
max_connections: 100
ping_interval: "30s"
pong_wait: "60s"
write_wait: "10s"
max_message_size: 512
# Logging configuration
logging:
level: "info"
format: "json"
# Storage configuration
storage:
type: "local"
path: "/donetick-data/uploads"
# Feature flags
features:
notifications: true
realtime: true
oauth: false