diff --git a/helm/cr.yaml b/helm/cr.yaml new file mode 100644 index 000000000..f895ab8d6 --- /dev/null +++ b/helm/cr.yaml @@ -0,0 +1 @@ +release-name-template: "helm-{{ .Name }}-{{ .Version }}" \ No newline at end of file diff --git a/helm/ct.yaml b/helm/ct.yaml new file mode 100644 index 000000000..02d6dbc4d --- /dev/null +++ b/helm/ct.yaml @@ -0,0 +1,5 @@ +chart-repos: + - bitnami=https://charts.bitnami.com/bitnami +chart-dirs: + - helm +validate-maintainers: false diff --git a/helm/dendrite/Chart.yaml b/helm/dendrite/Chart.yaml new file mode 100644 index 000000000..f206f42e6 --- /dev/null +++ b/helm/dendrite/Chart.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +name: dendrite +version: "0.10.8" +appVersion: "0.10.8" +description: Dendrite Matrix Homeserver +type: application +keywords: + - matrix + - chat + - homeserver + - dendrite +home: https://github.com/matrix-org/dendrite +sources: + - https://github.com/matrix-org/dendrite +dependencies: +- name: postgresql + version: 11.6.21 + repository: https://charts.bitnami.com/bitnami + condition: postgresql.enabled diff --git a/helm/dendrite/README.md b/helm/dendrite/README.md new file mode 100644 index 000000000..cb0383e72 --- /dev/null +++ b/helm/dendrite/README.md @@ -0,0 +1,123 @@ +# dendrite + +![Version: 0.10.8](https://img.shields.io/badge/Version-0.10.8-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.10.8](https://img.shields.io/badge/AppVersion-0.10.8-informational?style=flat-square) +Dendrite Matrix Homeserver + +Status: **NOT PRODUCTION READY** + +## About + +This is a first try for a Helm Chart for the [Matrix](https://matrix.org) Homeserver [Dendrite](https://github.com/matrix-org/dendrite) + +This chart creates a polylith, where every component is in its own deployment and requires a Postgres server aswell as a NATS JetStream server. + +## Manual database creation + +(You can skip this, if you're deploying the PostgreSQL dependency) + +You'll need to create the following databases before starting Dendrite (see [install.md](https://github.com/matrix-org/dendrite/blob/master/docs/INSTALL.md#configuration)): + +```postgres +create database dendrite_federationapi; +create database dendrite_mediaapi; +create database dendrite_roomserver; +create database dendrite_userapi_accounts; +create database dendrite_keyserver; +create database dendrite_syncapi; +``` + +or + +```bash +for i in mediaapi syncapi roomserver federationapi keyserver userapi_accounts; do + sudo -u postgres createdb -O dendrite dendrite_$i +done +``` + +## Usage with appservices + +Create a folder `appservices` and place your configurations in there. The configurations will be read and placed in a secret `dendrite-appservices-conf`. + +## Source Code + +* + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| clientapi.registration.disabled | bool | `true` | Disable registration | +| clientapi.registration.enable_registration_captcha | bool | `false` | enable reCAPTCHA registration | +| clientapi.registration.recaptcha_bypass_secret | string | `""` | reCAPTCHA bypass secret | +| clientapi.registration.recaptcha_private_key | string | `""` | reCAPTCHA private key | +| clientapi.registration.recaptcha_public_key | string | `""` | reCAPTCHA public key | +| clientapi.registration.recaptcha_siteverify_api | string | `""` | | +| clientapi.registration.shared_secret | string | `""` | If set, allows registration by anyone who knows the shared secret, regardless of whether registration is otherwise disabled. | +| configuration.cache.max_age | string | `"1h"` | The maximum amount of time that a cache entry can live for in memory before it will be evicted and/or refreshed from the database. Lower values result in easier admission of new cache entries but may also increase database load in comparison to higher values, so adjust conservatively. Higher values may make it harder for new items to make it into the cache, e.g. if new rooms suddenly become popular. | +| configuration.cache.max_size_estimated | string | `"1gb"` | The estimated maximum size for the global cache in bytes, or in terabytes, gigabytes, megabytes or kilobytes when the appropriate 'tb', 'gb', 'mb' or 'kb' suffix is specified. Note that this is not a hard limit, nor is it a memory limit for the entire process. A cache that is too small may ultimately provide little or no benefit. | +| configuration.database.conn_max_lifetime | int | `-1` | Default database maximum lifetime | +| configuration.database.host | string | `""` | Default database host | +| configuration.database.max_idle_conns | int | `2` | Default database maximum idle connections | +| configuration.database.max_open_conns | int | `100` | Default database maximum open connections | +| configuration.database.password | string | `""` | Default database password | +| configuration.database.user | string | `""` | Default database user | +| configuration.disable_federation | bool | `false` | Disable federation. Dendrite will not be able to make any outbound HTTP requests to other servers and the federation API will not be exposed. | +| configuration.dns_cache.cache_lifetime | string | `"10m"` | Duration for how long DNS cache items should be considered valid ([see time.ParseDuration](https://pkg.go.dev/time#ParseDuration) for more) | +| configuration.dns_cache.cache_size | int | `256` | Maximum number of entries to hold in the DNS cache | +| configuration.dns_cache.enabled | bool | `false` | Whether or not the DNS cache is enabled. | +| configuration.key_validity_period | string | `"168h0m0s"` | | +| configuration.logging | list | [default dendrite config values](https://github.com/matrix-org/dendrite/blob/master/dendrite-config.yaml) | Default logging configuration | +| configuration.metrics.basic_auth.password | string | `"metrics"` | HTTP basic authentication password | +| configuration.metrics.basic_auth.user | string | `"metrics"` | HTTP basic authentication username | +| configuration.metrics.enabled | bool | `false` | Whether or not Prometheus metrics are enabled. | +| configuration.mscs | list | `[]` | Configuration for experimental MSC's. (Valid values are: msc2836 and msc2946) | +| configuration.profiling.enabled | bool | `false` | Enable pprof | +| configuration.profiling.port | int | `65432` | pprof port, if enabled | +| configuration.rate_limiting.cooloff_ms | int | `500` | Cooloff time in milliseconds | +| configuration.rate_limiting.enabled | bool | `true` | Enable rate limiting | +| configuration.rate_limiting.threshold | int | `5` | After how many requests a rate limit should be activated | +| configuration.servername | string | `""` | Servername for this Dendrite deployment | +| configuration.signing_key.create | bool | `true` | Create a new signing key, if not exists | +| configuration.signing_key.existingSecret | string | `""` | Use an existing secret | +| configuration.tracing | object | disabled | Default tracing configuration | +| configuration.trusted_third_party_id_servers | list | `["matrix.org","vector.im"]` | Lists of domains that the server will trust as identity servers to verify third party identifiers such as phone numbers and email addresses. | +| configuration.turn.turn_password | string | `""` | The TURN password | +| configuration.turn.turn_shared_secret | string | `""` | | +| configuration.turn.turn_uris | list | `[]` | | +| configuration.turn.turn_user_lifetime | string | `""` | | +| configuration.turn.turn_username | string | `""` | The TURN username | +| configuration.well_known_client_name | string | `nil` | The server name to delegate client-server communications to, with optional port e.g. localhost:443 | +| configuration.well_known_server_name | string | `""` | The server name to delegate server-server communications to, with optional port e.g. localhost:443 | +| federationapi.disable_tls_validation | bool | `false` | Disable TLS validation | +| federationapi.prefer_direct_fetch | bool | `false` | | +| federationapi.send_max_retries | int | `16` | | +| image.name | string | `"ghcr.io/matrix-org/dendrite-monolith:v0.10.8"` | Docker repository/image to use | +| image.pullPolicy | string | `"IfNotPresent"` | Kubernetes pullPolicy | +| ingress.annotations | object | `{}` | | +| ingress.enabled | bool | `false` | Create an ingress for a monolith deployment | +| ingress.hosts | list | `[]` | | +| ingress.tls | list | `[]` | | +| mediaapi.dynamic_thumbnails | bool | `false` | | +| mediaapi.max_file_size_bytes | string | `"10485760"` | The max file size for uploaded media files | +| mediaapi.max_thumbnail_generators | int | `10` | The maximum number of simultaneous thumbnail generators to run. | +| mediaapi.thumbnail_sizes | list | [default dendrite config values](https://github.com/matrix-org/dendrite/blob/master/dendrite-config.yaml) | A list of thumbnail sizes to be generated for media content. | +| persistence.jetstream.capacity | string | `"5Gi"` | | +| persistence.jetstream.existingClaim | string | `""` | | +| persistence.media.capacity | string | `"10Gi"` | | +| persistence.media.existingClaim | string | `""` | | +| persistence.search.capacity | string | `"5Gi"` | | +| persistence.search.existingClaim | string | `""` | | +| persistence.storageClass | string | `"local-path"` | | +| postgresql.auth.database | string | `"dendrite"` | | +| postgresql.auth.password | string | `"changeme"` | | +| postgresql.auth.username | string | `"dendrite"` | | +| postgresql.enabled | bool | See value.yaml | Enable and configure postgres as the database for dendrite. | +| postgresql.image.repository | string | `"bitnami/postgresql"` | | +| postgresql.image.tag | string | `"14.4.0"` | | +| postgresql.initdbScripts."create_db.sh" | string | creates the required databases | Create databases when first creating a PostgreSQL Server | +| postgresql.persistence.enabled | bool | `false` | | +| resources | object | sets some sane default values | Default resource requests/limits. This can be set individually for each component, see mediaapi | +| syncapi.real_ip_header | string | `"X-Real-IP"` | This option controls which HTTP header to inspect to find the real remote IP address of the client. This is likely required if Dendrite is running behind a reverse proxy server. | +| syncapi.search | object | `{"enabled":false,"language":"en"}` | Configuration for the full-text search engine. | +| syncapi.search.enabled | bool | `false` | Whether or not search is enabled. | +| syncapi.search.language | string | `"en"` | The language most likely to be used on the server - used when indexing, to ensure the returned results match expectations. A full list of possible languages can be found at https://github.com/blevesearch/bleve/tree/master/analysis/lang | diff --git a/helm/dendrite/README.md.gotmpl b/helm/dendrite/README.md.gotmpl new file mode 100644 index 000000000..7c32f7b02 --- /dev/null +++ b/helm/dendrite/README.md.gotmpl @@ -0,0 +1,13 @@ +{{ template "chart.header" . }} +{{ template "chart.deprecationWarning" . }} +{{ template "chart.badgesSection" . }} +{{ template "chart.description" . }} +{{ template "chart.state" . }} +{{ template "chart.about" . }} +{{ template "chart.dbCreation" . }} +{{ template "chart.appservices" . }} +{{ template "chart.maintainersSection" . }} +{{ template "chart.sourcesSection" . }} +{{ template "chart.requirementsSection" . }} +{{ template "chart.valuesSection" . }} +{{ template "helm-docs.versionFooter" . }} \ No newline at end of file diff --git a/helm/dendrite/ci/ct-gen-key.yaml b/helm/dendrite/ci/ct-gen-key.yaml new file mode 100644 index 000000000..9aec71669 --- /dev/null +++ b/helm/dendrite/ci/ct-gen-key.yaml @@ -0,0 +1,6 @@ +postgresql: + enabled: true + +configuration: + signing_key: + create: true \ No newline at end of file diff --git a/helm/dendrite/ci/ct-postgres.yaml b/helm/dendrite/ci/ct-postgres.yaml new file mode 100644 index 000000000..e1a98cd30 --- /dev/null +++ b/helm/dendrite/ci/ct-postgres.yaml @@ -0,0 +1,2 @@ +postgresql: + enabled: true \ No newline at end of file diff --git a/helm/dendrite/templates/_helpers.tpl b/helm/dendrite/templates/_helpers.tpl new file mode 100644 index 000000000..ccbca3e7b --- /dev/null +++ b/helm/dendrite/templates/_helpers.tpl @@ -0,0 +1,19 @@ +{{- define "validate.config" }} +{{- if not .Values.configuration.signing_key.create -}} +{{- fail "You must create a signing key for configuration.signing_key. (see https://github.com/matrix-org/dendrite/blob/master/docs/INSTALL.md#server-key-generation)" -}} +{{- end -}} +{{- if not (or .Values.configuration.database.host .Values.postgresql.enabled) -}} +{{- fail "Database server must be set." -}} +{{- end -}} +{{- if not (or .Values.configuration.database.user .Values.postgresql.enabled) -}} +{{- fail "Database user must be set." -}} +{{- end -}} +{{- if not (or .Values.configuration.database.password .Values.postgresql.enabled) -}} +{{- fail "Database password must be set." -}} +{{- end -}} +{{- end -}} + +{{- define "image.name" -}} +image: {{ .name }} +imagePullPolicy: {{ .pullPolicy }} +{{- end -}} \ No newline at end of file diff --git a/helm/dendrite/templates/deployment.yaml b/helm/dendrite/templates/deployment.yaml new file mode 100644 index 000000000..c1d458b2f --- /dev/null +++ b/helm/dendrite/templates/deployment.yaml @@ -0,0 +1,64 @@ +{{ template "validate.config" . }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: {{ $.Release.Namespace }} + name: {{ $.Chart.Name }} + labels: + app: {{ $.Chart.Name }} +spec: + selector: + matchLabels: + app: {{ $.Chart.Name }} + replicas: 1 + template: + metadata: + labels: + app: {{ $.Chart.Name }} + spec: + volumes: + - name: {{ $.Chart.Name }}-conf-vol + secret: + secretName: {{ $.Chart.Name }}-conf + - name: {{ $.Chart.Name }}-signing-key + secret: + secretName: {{ default "dendrite-signing-key" $.Values.configuration.signing_key.existingSecret | quote }} + {{- if (gt (len ($.Files.Glob "appservices/*")) 0) }} + - name: {{ $.Chart.Name }}-appservices + secret: + secretName: {{ $.Chart.Name }}-appservices-conf + {{- end }} + - name: dendrite-jetstream + persistentVolumeClaim: + claimName: {{ default "dendrite-jetstream-pvc" $.Values.persistence.jetstream.existingClaim | quote }} + - name: dendrite-media + persistentVolumeClaim: + claimName: {{ default "dendrite-media-pvc" $.Values.persistence.media.existingClaim | quote }} + - name: dendrite-search + persistentVolumeClaim: + claimName: {{ default "dendrite-serach-pvc" $.Values.persistence.search.existingClaim | quote }} + containers: + - name: {{ $.Chart.Name }} + {{- include "image.name" $.Values.image | nindent 8 }} + args: + - '--config' + - '/etc/dendrite/dendrite.yaml' + resources: + {{- toYaml $.Values.resources | nindent 10 }} + volumeMounts: + - mountPath: /etc/dendrite/ + name: {{ $.Chart.Name }}-conf-vol + - mountPath: /etc/dendrite/secrets/ + name: {{ $.Chart.Name }}-signing-key + {{- if (gt (len ($.Files.Glob "appservices/*")) 0) }} + - mountPath: /etc/dendrite/appservices + name: {{ $.Chart.Name }}-appservices + readOnly: true + {{ end }} + - mountPath: /data/media_store + name: dendrite-media + - mountPath: /data/jetstream + name: dendrite-jetstream + - mountPath: /data/search + name: dendrite-search \ No newline at end of file diff --git a/helm/dendrite/templates/ingress.yaml b/helm/dendrite/templates/ingress.yaml new file mode 100644 index 000000000..9e9899ad6 --- /dev/null +++ b/helm/dendrite/templates/ingress.yaml @@ -0,0 +1,62 @@ +{{- if .Values.ingress.enabled -}} +{{ $component := "monolith" }} +{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} + {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }} + {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}} + {{- end }} +{{- end }} +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + namespace: {{ $.Release.Namespace }} + name: {{ $component }} + labels: + app: {{ $.Chart.Name }} + component: {{ $component }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} + ingressClassName: {{ .Values.ingress.className }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} + pathType: {{ .pathType }} + {{- end }} + backend: + {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} + service: + name: {{ $component }} + port: + number: 8008 + {{- else }} + serviceName: {{ $component }} + servicePort: 8008 + {{- end }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/dendrite/templates/jobs.yaml b/helm/dendrite/templates/jobs.yaml new file mode 100644 index 000000000..61f447d5c --- /dev/null +++ b/helm/dendrite/templates/jobs.yaml @@ -0,0 +1,95 @@ +{{ if and .Values.configuration.signing_key.create (not .Values.configuration.signing_key.existingSecret ) }} +{{ $name := "dendrite-signing-key" }} +{{ $secretName := "dendrite-signing-key" }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ $name }} + labels: + app.kubernetes.io/component: signingkey-job +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ $name }} + labels: + app.kubernetes.io/component: signingkey-job +rules: + - apiGroups: + - "" + resources: + - secrets + resourceNames: + - {{ $secretName }} + verbs: + - get + - update + - patch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ $name }} + labels: + app.kubernetes.io/component: signingkey-job +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ $name }} +subjects: + - kind: ServiceAccount + name: {{ $name }} + namespace: {{ .Release.Namespace }} +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: generate-signing-key +spec: + template: + spec: + restartPolicy: "Never" + serviceAccount: dendrite-signing-key + containers: + - name: upload-key + image: bitnami/kubectl + command: + - sh + - -c + - | + # check if key already exists + key=$(kubectl get secret {{ $secretName }} -o jsonpath="{.data['signing\.key']}" 2> /dev/null) + [ $? -ne 0 ] && echo "Failed to get existing secret" && exit 1 + [ -n "$key" ] && echo "Key already created, exiting." && exit 0 + # wait for signing key + while [ ! -f /etc/dendrite/signing-key.pem ]; do + echo "Waiting for signing key.." + sleep 5; + done + # update secret + kubectl patch secret {{ $secretName }} -p "{\"data\":{\"signing.key\":\"$(base64 /etc/dendrite/signing-key.pem | tr -d '\n')\"}}" + [ $? -ne 0 ] && echo "Failed to update secret." + echo "Signing key successfully created." + volumeMounts: + - mountPath: /etc/dendrite/ + name: signing-key + readOnly: true + - name: generate-key + {{- include "image.name" $.Values.image | nindent 8 }} + command: + - sh + - -c + - | + /usr/bin/generate-keys -private-key /etc/dendrite/signing-key.pem + chown 1001:1001 /etc/dendrite/signing-key.pem + volumeMounts: + - mountPath: /etc/dendrite/ + name: signing-key + volumes: + - name: signing-key + emptyDir: {} + parallelism: 1 + completions: 1 + backoffLimit: 1 +{{ end }} \ No newline at end of file diff --git a/helm/dendrite/templates/pvc.yaml b/helm/dendrite/templates/pvc.yaml new file mode 100644 index 000000000..df73a4f83 --- /dev/null +++ b/helm/dendrite/templates/pvc.yaml @@ -0,0 +1,96 @@ +{{ if not .Values.persistence.media.existingClaim }} +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + annotations: + helm.sh/resource-policy: keep + name: dendrite-media +spec: + capacity: + storage: {{ .Values.persistence.media.capacity }} + volumeMode: Filesystem + accessModes: + - ReadWriteOnce + storageClassName: {{ .Values.persistence.storageClass }} +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + annotations: + helm.sh/resource-policy: keep + name: dendrite-media-pvc + labels: + app: dendrite +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.persistence.media.capacity }} + storageClassName: {{ .Values.persistence.storageClass }} +{{ end }} +{{ if not .Values.persistence.jetstream.existingClaim }} +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + annotations: + helm.sh/resource-policy: keep + name: dendrite-jetstream +spec: + capacity: + storage: {{ .Values.persistence.jetstream.capacity }} + volumeMode: Filesystem + accessModes: + - ReadWriteOnce + storageClassName: {{ .Values.persistence.storageClass }} +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + annotations: + helm.sh/resource-policy: keep + name: dendrite-jetstream-pvc + labels: + app: dendrite +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.persistence.jetstream.capacity }} + storageClassName: {{ .Values.persistence.storageClass }} +{{ end }} +{{ if not .Values.persistence.search.existingClaim }} +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + annotations: + helm.sh/resource-policy: keep + name: dendrite-search +spec: + capacity: + storage: {{ .Values.persistence.search.capacity }} + volumeMode: Filesystem + accessModes: + - ReadWriteOnce + storageClassName: {{ .Values.persistence.storageClass }} +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + annotations: + helm.sh/resource-policy: keep + name: dendrite-search-pvc + labels: + app: dendrite +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.persistence.search.capacity }} + storageClassName: {{ .Values.persistence.storageClass }} +{{ end }} \ No newline at end of file diff --git a/helm/dendrite/templates/secrets.yaml b/helm/dendrite/templates/secrets.yaml new file mode 100644 index 000000000..db4f0f5a0 --- /dev/null +++ b/helm/dendrite/templates/secrets.yaml @@ -0,0 +1,115 @@ +{{ if (gt (len (.Files.Glob "appservices/*")) 0) }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Chart.Name }}-appservices-conf + namespace: {{ .Release.Namespace }} +type: Opaque +data: +{{ (.Files.Glob "appservices/*").AsSecrets | indent 2 }} +{{ end }} +{{ if and .Values.configuration.signing_key.create (not .Values.configuration.signing_key.existingSecret) }} +--- +apiVersion: v1 +kind: Secret +metadata: + annotations: + helm.sh/resource-policy: keep + name: {{ .Chart.Name }}-signing-key + namespace: {{ .Release.Namespace }} +type: Opaque +{{ end }} + +{{- $connectionString := print "postgresql://" .Values.configuration.database.user ":" .Values.configuration.database.password "@" .Values.configuration.database.host }} +{{- if .Values.postgresql.enabled }} +{{- $connectionString = print "postgresql://" .Values.postgresql.auth.username ":" .Values.postgresql.auth.password "@" .Chart.Name -}} +{{ end }} +--- +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: {{ .Chart.Name }}-conf + namespace: {{ .Release.Namespace }} +stringData: + dendrite.yaml: | + version: 2 + global: + private_key: /etc/dendrite/secrets/signing.key + key_id: ed25519:auto + key_validity_period: {{ .Values.configuration.key_validity_period | quote }} + database: + connection_string: {{ $connectionString }}?sslmode=disable + max_open_conns: {{ default 90 .Values.configuration.database.max_open_conns }} + max_idle_conns: {{ default 5 .Values.configuration.database.max_idle_conns }} + conn_max_lifetime: {{ default -1 .Values.configuration.database.conn_max_lifetime }} + cache: + max_size_estimated: {{ default "1gb" .Values.configuration.cache.max_size_estimated | quote }} + max_age: {{ default "1h" .Values.configuration.cache.max_age }} + well_known_server_name: {{ default "" .Values.configuration.well_known_server_name | quote }} + well_known_client_name: {{ default "" .Values.configuration.well_known_client_name | quote }} + trusted_third_party_id_servers: + {{- toYaml .Values.configuration.trusted_third_party_id_servers | nindent 8 }} + disable_federation: {{ .Values.configuration.disable_federation }} + jetstream: + in_memory: false + storage_path: /data/jetstream + metrics: + {{- toYaml .Values.configuration.metrics | nindent 8 }} + dns_cache: + {{- toYaml .Values.configuration.dns_cache | nindent 8 }} + mscs: + mscs: + {{- toYaml .Values.configuration.mscs | nindent 8 }} + app_service_api: + config_files: + {{- range $x, $y := .Files.Glob "appservices/*" }} + - /etc/dendrite/appservices/{{ base $x }} + {{ end }} + client_api: + {{- with .Values.clientapi }} + registration_disabled: {{ .registration.disabled }} + registration_shared_secret: {{ .registration.shared_secret | quote }} + enable_registration_captcha: {{ .registration.enable_registration_captcha }} + recaptcha_public_key: {{ .registration.recaptcha_public_key | quote }} + recaptcha_private_key: {{ .registration.recaptcha_private_key | quote}} + recaptcha_bypass_secret: {{ .registration.recaptcha_bypass_secret | quote}} + recaptcha_siteverify_api: {{ .registration.recaptcha_siteverify_api | quote}} + {{ end }} + turn: + {{- toYaml .Values.configuration.turn | nindent 8 }} + rate_limiting: + {{- toYaml .Values.configuration.rate_limiting | nindent 8 }} + federation_api: + #federation_certificates: [] + send_max_retries: {{ default 16 .Values.federationapi.send_max_retries }} + disable_tls_validation: {{ default false .Values.federationapi.disable_tls_validation }} + key_perspectives: + - server_name: matrix.org + keys: + - key_id: ed25519:auto + public_key: Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw + - key_id: ed25519:a_RXGa + public_key: l8Hft5qXKn1vfHrg3p4+W8gELQVo8N13JkluMfmn2sQ + prefer_direct_fetch: {{ .Values.federationapi.prefer_direct_fetch }} + media_api: + base_path: /data/media_store + max_file_size_bytes: {{ int (default "10485760" .Values.mediaapi.max_file_size_bytes) }} + dynamic_thumbnails: {{ .Values.mediaapi.dynamic_thumbnails }} + max_thumbnail_generators: {{ .Values.mediaapi.max_thumbnail_generators }} + thumbnail_sizes: + {{- toYaml .Values.mediaapi.thumbnail_sizes | nindent 8 }} + room_server: + sync_api: + real_ip_header: {{ .Values.syncapi.real_ip_header }} + search: + enabled: {{ default false .Values.syncapi.search.enabled }} + index_path: /data/search + language: {{ default "en" .Values.syncapi.search.language }} + tracing: + {{- toYaml .Values.configuration.tracing | nindent 6 }} + logging: + {{- if .Values.configuration.logging }} + {{- toYaml .Values.configuration.logging | nindent 4 }} + {{ end }} diff --git a/helm/dendrite/templates/service.yaml b/helm/dendrite/templates/service.yaml new file mode 100644 index 000000000..2ce037a62 --- /dev/null +++ b/helm/dendrite/templates/service.yaml @@ -0,0 +1,18 @@ +{{ template "validate.config" . }} + +--- +apiVersion: v1 +kind: Service +metadata: + namespace: {{ $.Release.Namespace }} + name: dendrite + labels: + app: {{ $.Chart.Name }} +spec: + selector: + app: {{ $.Chart.Name }} + ports: + - name: http + protocol: TCP + port: 8008 + targetPort: 8008 \ No newline at end of file diff --git a/helm/dendrite/values.yaml b/helm/dendrite/values.yaml new file mode 100644 index 000000000..6d8c57a7b --- /dev/null +++ b/helm/dendrite/values.yaml @@ -0,0 +1,261 @@ +image: + # -- Docker repository/image to use + name: "ghcr.io/matrix-org/dendrite-monolith:v0.10.8" + # -- Kubernetes pullPolicy + pullPolicy: IfNotPresent + +configuration: + # -- Servername for this Dendrite deployment + servername: "" + + # -- The server name to delegate server-server communications to, with optional port + # e.g. localhost:443 + well_known_server_name: "" + + # -- The server name to delegate client-server communications to, with optional port + # e.g. localhost:443 + well_known_client_name: + + # -- Lists of domains that the server will trust as identity servers to verify third + # party identifiers such as phone numbers and email addresses. + trusted_third_party_id_servers: + - matrix.org + - vector.im + + # -- Disable federation. Dendrite will not be able to make any outbound HTTP requests + # to other servers and the federation API will not be exposed. + disable_federation: false + + # signing key to use + signing_key: + # -- Create a new signing key, if not exists + create: true + # -- Use an existing secret + existingSecret: "" + + key_validity_period: 168h0m0s + + + database: + # -- Default database host + host: "" + # -- Default database user + user: "" + # -- Default database password + password: "" + + # -- Default database maximum open connections + max_open_conns: 100 + # -- Default database maximum idle connections + max_idle_conns: 2 + # -- Default database maximum lifetime + conn_max_lifetime: -1 + + cache: + # -- The estimated maximum size for the global cache in bytes, or in terabytes, + # gigabytes, megabytes or kilobytes when the appropriate 'tb', 'gb', 'mb' or + # 'kb' suffix is specified. Note that this is not a hard limit, nor is it a + # memory limit for the entire process. A cache that is too small may ultimately + # provide little or no benefit. + max_size_estimated: 1gb + # -- The maximum amount of time that a cache entry can live for in memory before + # it will be evicted and/or refreshed from the database. Lower values result in + # easier admission of new cache entries but may also increase database load in + # comparison to higher values, so adjust conservatively. Higher values may make + # it harder for new items to make it into the cache, e.g. if new rooms suddenly + # become popular. + max_age: 1h + + # prometheus metrics + metrics: + # -- Whether or not Prometheus metrics are enabled. + enabled: false + # HTTP basic authentication to protect access to monitoring. + basic_auth: + # -- HTTP basic authentication username + user: "metrics" + # -- HTTP basic authentication password + password: metrics + + # TURN server information that this homeserver should send to clients. + turn: + turn_user_lifetime: "" + turn_uris: [] + turn_shared_secret: "" + # -- The TURN username + turn_username: "" + # -- The TURN password + turn_password: "" + + rate_limiting: + # -- Enable rate limiting + enabled: true + # -- After how many requests a rate limit should be activated + threshold: 5 + # -- Cooloff time in milliseconds + cooloff_ms: 500 + + dns_cache: + # -- Whether or not the DNS cache is enabled. + enabled: false + # -- Maximum number of entries to hold in the DNS cache + cache_size: 256 + # -- Duration for how long DNS cache items should be considered valid ([see time.ParseDuration](https://pkg.go.dev/time#ParseDuration) for more) + cache_lifetime: "10m" + + # -- Default logging configuration + # @default -- [default dendrite config values](https://github.com/matrix-org/dendrite/blob/master/dendrite-config.yaml) + logging: + - type: std + level: info + + # -- Default tracing configuration + # @default -- disabled + tracing: + enabled: false + jaeger: + serviceName: "" + disabled: false + rpc_metrics: false + tags: [] + sampler: null + reporter: null + headers: null + baggage_restrictions: null + throttler: null + + profiling: + # -- Enable pprof + enabled: false + # -- pprof port, if enabled + port: 65432 + + # -- Configuration for experimental MSC's. (Valid values are: msc2836 and msc2946) + mscs: [] + # A list of enabled MSC's + # Currently valid values are: + # - msc2836 (Threading, see https://github.com/matrix-org/matrix-doc/pull/2836) + # - msc2946 (Spaces Summary, see https://github.com/matrix-org/matrix-doc/pull/2946) + +# -- Default resource requests/limits. +# This can be set individually for each component, see mediaapi +# @default -- sets some sane default values +resources: + requests: + cpu: "80m" + memory: "64Mi" + + limits: + cpu: "240m" + memory: "256Mi" + +persistence: + storageClass: local-path + jetstream: + existingClaim: "" + capacity: "5Gi" + media: + existingClaim: "" + capacity: "10Gi" + search: + existingClaim: "" + capacity: "5Gi" + +clientapi: + registration: + # -- Disable registration + disabled: true + + # -- If set, allows registration by anyone who knows the shared secret, regardless of + # whether registration is otherwise disabled. + shared_secret: "" + + # -- enable reCAPTCHA registration + enable_registration_captcha: false + # -- reCAPTCHA public key + recaptcha_public_key: "" + # -- reCAPTCHA private key + recaptcha_private_key: "" + # -- reCAPTCHA bypass secret + recaptcha_bypass_secret: "" + recaptcha_siteverify_api: "" + +federationapi: + send_max_retries: 16 + # -- Disable TLS validation + disable_tls_validation: false + prefer_direct_fetch: false + + +mediaapi: + # -- The max file size for uploaded media files + max_file_size_bytes: "10485760" + # Whether to dynamically generate thumbnails if needed. + dynamic_thumbnails: false + # -- The maximum number of simultaneous thumbnail generators to run. + max_thumbnail_generators: 10 + # -- A list of thumbnail sizes to be generated for media content. + # @default -- [default dendrite config values](https://github.com/matrix-org/dendrite/blob/master/dendrite-config.yaml) + thumbnail_sizes: + - width: 32 + height: 32 + method: crop + - width: 96 + height: 96 + method: crop + - width: 640 + height: 480 + method: scale + #resources: + # requests: + # cpu: "160m" + # memory: "128Mi" + # limits: + # cpu: "480m" + # memory: "512Mi" + +syncapi: + # -- This option controls which HTTP header to inspect to find the real remote IP + # address of the client. This is likely required if Dendrite is running behind + # a reverse proxy server. + real_ip_header: X-Real-IP + # -- Configuration for the full-text search engine. + search: + # -- Whether or not search is enabled. + enabled: false + # -- The language most likely to be used on the server - used when indexing, to + # ensure the returned results match expectations. A full list of possible languages + # can be found at https://github.com/blevesearch/bleve/tree/master/analysis/lang + language: "en" + +postgresql: + # -- Enable and configure postgres as the database for dendrite. + # @default -- See value.yaml + enabled: false + image: + repository: bitnami/postgresql + tag: "14.4.0" + auth: + username: dendrite + password: changeme + database: dendrite + + initdbScripts: + # -- Create databases when first creating a PostgreSQL Server + # @default -- creates the required databases + create_db.sh: | + #!/bin/sh + for db in userapi_accounts userapi_devices mediaapi syncapi roomserver keyserver federationapi mscs; do + createdb -U dendrite -O dendrite dendrite_$db + done + + persistence: + enabled: false + +ingress: + # -- Create an ingress for a monolith deployment + enabled: false + + annotations: {} + hosts: [] + tls: []