Kubernetes Deployment with Helm
Deploy GOTRS on Kubernetes for production-grade scalability, high availability, and enterprise features.
Prerequisites
- Kubernetes 1.25+
- Helm 3.12+
- Ingress controller (nginx-ingress recommended)
- PV provisioner support in the cluster
kubectlconfigured for your cluster
Quick Start
Install from OCI Registry
The chart is published to GitHub Container Registry with tags that mirror container image tags:
# Create namespace
kubectl create namespace gotrs
# Install latest release
helm install gotrs oci://ghcr.io/gotrs-io/charts/gotrs \
--namespace gotrs \
--version latest
# Install specific version (deploys matching container images)
helm install gotrs oci://ghcr.io/gotrs-io/charts/gotrs \
--namespace gotrs \
--version v0.6.0
Tag Mirroring: The chart’s appVersion matches the tag, so --version v0.6.0 automatically deploys :v0.6.0 container images.
Install from Cloned Repository
# Clone the repository
git clone https://github.com/gotrs-io/gotrs-ce.git
cd gotrs-ce
# Update Helm dependencies
helm dependency update charts/gotrs
# Install with default values (MySQL)
helm install gotrs ./charts/gotrs --namespace gotrs --create-namespace
# Install with PostgreSQL
helm install gotrs ./charts/gotrs \
--namespace gotrs \
--create-namespace \
-f charts/gotrs/values-postgresql.yaml
Production Configuration
Ingress with TLS
# values-production.yaml
ingress:
enabled: true
className: nginx
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
hosts:
- host: gotrs.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: gotrs-tls
hosts:
- gotrs.example.com
External Database (RDS, Cloud SQL, etc.)
For production, use a managed database service:
# values-production.yaml
database:
type: mysql # or postgresql
external:
enabled: true
host: "your-rds-endpoint.amazonaws.com"
port: "3306"
database: "gotrs"
existingSecret: "gotrs-db-credentials" # Secret with keys: username, password
Create the secret:
kubectl create secret generic gotrs-db-credentials \
--namespace gotrs \
--from-literal=username=gotrs \
--from-literal=password=your-secure-password
External Valkey/Redis (ElastiCache, etc.)
# values-production.yaml
valkey:
enabled: false
externalValkey:
enabled: true
host: "your-elasticache-endpoint"
port: 6379
existingSecret: "gotrs-valkey-credentials"
Autoscaling
# values-production.yaml
backend:
replicaCount: 3
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
targetCPUUtilizationPercentage: 70
targetMemoryUtilizationPercentage: 80
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "2"
memory: "2Gi"
Complete Production Example
helm install gotrs oci://ghcr.io/gotrs-io/charts/gotrs \
--namespace gotrs \
--create-namespace \
--version latest \
-f values-production.yaml \
--set secrets.appSecretKey=$(openssl rand -hex 32)
Cloud Provider Integration
AWS EKS with IRSA
serviceAccount:
annotations:
eks.amazonaws.com/role-arn: "arn:aws:iam::123456789:role/gotrs"
backend:
serviceAnnotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
GKE with Workload Identity
serviceAccount:
annotations:
iam.gke.io/gcp-service-account: "gotrs@project.iam.gserviceaccount.com"
Azure AKS
serviceAccount:
annotations:
azure.workload.identity/client-id: "your-client-id"
backend:
podLabels:
azure.workload.identity/use: "true"
Observability
Prometheus Metrics
backend:
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9090"
prometheus.io/path: "/metrics"
Istio Service Mesh
backend:
podAnnotations:
sidecar.istio.io/inject: "true"
podLabels:
app: gotrs
version: v1
Database Selection
MySQL/MariaDB (Default)
database:
type: mysql
mysql:
rootPassword: "" # Use existingSecret in production
existingSecret: "gotrs-mysql-secret"
storage:
size: 20Gi
config:
maxConnections: 200
innodbBufferPoolSize: "1G"
PostgreSQL
database:
type: postgresql
postgresql:
existingSecret: "gotrs-postgres-secret"
storage:
size: 20Gi
config:
maxConnections: 200
sharedBuffers: "1GB"
Extra Resources
Define arbitrary Kubernetes resources with Helm templating:
extraResources:
# PodDisruptionBudget for high availability
- apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: "{{ .Release.Name }}-backend-pdb"
spec:
minAvailable: 2
selector:
matchLabels:
app.kubernetes.io/name: gotrs
app.kubernetes.io/component: backend
# Scheduled cleanup job
- apiVersion: batch/v1
kind: CronJob
metadata:
name: "{{ .Release.Name }}-cleanup"
spec:
schedule: "0 2 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: cleanup
image: "{{ .Values.backend.image.repository }}:{{ .Values.backend.image.tag | default .Chart.AppVersion }}"
command: ["/app/gotrs", "cleanup"]
restartPolicy: OnFailure
Upgrading
# Update to latest version
helm upgrade gotrs oci://ghcr.io/gotrs-io/charts/gotrs \
--namespace gotrs \
--version latest \
-f values-production.yaml
# Or from local chart
helm upgrade gotrs ./charts/gotrs --namespace gotrs -f values-production.yaml
Uninstalling
helm uninstall gotrs --namespace gotrs
Note: PVCs are retained by default. To remove all data:
kubectl delete pvc -l app.kubernetes.io/instance=gotrs -n gotrs
Troubleshooting
Check Pod Status
kubectl get pods -n gotrs -l app.kubernetes.io/instance=gotrs
kubectl describe pod <pod-name> -n gotrs
kubectl logs <pod-name> -n gotrs
Database Connection Issues
# Check database pod logs
kubectl logs -n gotrs -l app.kubernetes.io/component=database
# Test connectivity from backend
kubectl exec -it -n gotrs <backend-pod> -- nc -zv <db-service> 3306
Valkey Connection Issues
# Check valkey pods
kubectl get pods -n gotrs -l app.kubernetes.io/name=valkey
# Test connectivity
kubectl exec -it -n gotrs <backend-pod> -- nc -zv <valkey-service> 6379
View Helm Release Info
helm status gotrs -n gotrs
helm get values gotrs -n gotrs
helm history gotrs -n gotrs
Configuration Reference
| Parameter | Description | Default |
|---|---|---|
backend.replicaCount | Number of backend replicas | 2 |
backend.autoscaling.enabled | Enable HPA | false |
database.type | Database type: mysql or postgresql | mysql |
database.external.enabled | Use external database | false |
valkey.enabled | Deploy Valkey subchart | true |
ingress.enabled | Enable ingress | false |
config.logLevel | Application log level | info |
See the full values.yaml for all configuration options.
Next Steps
- Admin Guide - Configure GOTRS after installation
- API Documentation - Integrate with external systems
- Migration Guide - Migrate from OTRS