Custom fonts with Helm chart

We would like to add custom fonts to our wopi editor. I understand we need to fill the /opt/cool/systemplate/tmpfonts folder with the fonts.

Can someone please explain how we can do a volume mount to this folder with the Helm chart?

Hii @jaapglasbergen

It sounds like you’re looking to add custom fonts to your WOPI editor by configuring a volume mount in the Helm chart. To help you better, could you share your current values.yaml or any other Helm configuration file you’re using to set up Collabora Online?

This will allow me to provide more specific guidance on how to modify the configuration to include a volume mount for custom fonts.

Although just for example you can mount fonts like this, but this can work or may not work first i need to know your config settings…

collabora:
  extraVolumeMounts:
    - name: custom-fonts
      mountPath: /opt/cool/systemplate/tmpfonts

  extraVolumes:
    - name: custom-fonts
      hostPath:
        path: /path/to/custom/fonts
        type: Directory

Hi Darshan,

It looks like these settings will help me to get the fonts in the editor.

This is how my values.yaml looks like in my test cluster.

collabora:
  aliasgroups:
  - host: http://webapp:8000
  - host: https://test.casereditions.local

  extra_params: --o:ssl.enable=false --o:ssl.termination=true --o:num_prespawn_children=4
  
  server_name: test.casereditions.local
  
  existingSecret:
    enabled: false
    secretName: ""
    usernameKey: "username"
    passwordKey: "password"
  password: adminadmin
  username: admin
  env: []

autoscaling:
  minReplicas: 1

# securityContext:
#   privileged: true
#   capabilities:
#     drop:
#     - ALL
#   readOnlyRootFilesystem: true
#   runAsNonRoot: true
#   runAsUser: 1000

resources: {}
#  limits:
#    cpu: 100m
#    memory: 128Mi
#  requests:
#    cpu: 100m
#    memory: 128Mi

replicaCount: 1

dynamicConfig:

  ingress:
    hosts:
      - host: test.casereditions.local
        paths:
          - path: /
            pathType: ImplementationSpecific
    tls:
      hosts:
        - test.casereditions.local
      secretName: test-casereditions

podLabels:
  networking/data.egress: "true"
  networking/internet.egress: "true"
  networking/internet.ingress: "true"
  networking/service.egress: "true"
  networking/service.gress: "true"
  networking/webapp.egress: "true"
  networking/webapp.ingress: "true"


hi @jaapglasbergen How you are using Collabora Online is it any integration with any app like Nextcloud ?

We are using Collabora Online in our own application. We are building this app with a Django backend and a React frontend.
The editor is used by running it in a iframe within the app.

The Helm chart can typically handle both local paths and remote URLs for font configuration, but it depends on how the volume and configuration are set up in the chart. Here’s how each option works:

1. Using a Local Path

If you want to use a local path on the host machine where Kubernetes nodes are running, you can mount a directory into the container by specifying it in the extraVolumes and extraVolumeMounts configuration. This requires that the Kubernetes nodes have access to the local path you want to use.

For example:

extraVolumes:
  - name: custom-fonts
    hostPath:
      path: /path/on/host/to/fonts
      type: Directory

extraVolumeMounts:
  - name: custom-fonts
    mountPath: /opt/cool/systemplate/tmpfonts

In this setup, the local directory /path/on/host/to/fonts will be mounted inside the container at /opt/cool/systemplate/tmpfonts.

2. Using a Remote URL

If the fonts are hosted on a remote server, you would need to download them as part of the container initialization or use a ConfigMap/Secret if feasible. Helm charts do not directly handle downloading files from remote URLs, so you would typically include a script in the Docker image or an init container that pulls fonts from a remote URL and places them in the appropriate directory.

For example, you could include an init container in your values.yaml:

initContainers:
  - name: fetch-fonts
    image: busybox
    command:
      - wget
      - -P
      - /opt/cool/systemplate/tmpfonts
      - "https://example.com/path/to/fonts/font.ttf"
    volumeMounts:
      - name: custom-fonts
        mountPath: /opt/cool/systemplate/tmpfonts

Conclusion

  • Local Paths: You can use hostPath to mount local directories on the Kubernetes nodes.
  • Remote URLs: You might need an init container to download and prepare the fonts.

Check your Helm chart documentation to confirm support for extraVolumes and extraVolumeMounts, or consider modifying it to include this flexibility if it does not exist yet.

Thanks,
Darshan

@jaapglasbergenone more suggestion

Could you please take a look at this documentation: Collabora Online SDK - Configuration. You can use a JSON config to set up font configurations. This is how Nextcloud do there fonts configurations so maybe you can also take some inspiration from this and see how things go ?

Go through the steps and see if it aligns with your app setup.

Thanks Darshan,

I will change my setup with the info you provided.

Hi Darshan,

I changed my values.yaml like this.

collabora:
  aliasgroups:
  - host: http://webapp:8000
  - host: https://test.casereditions.local

  extra_params: --o:ssl.enable=false --o:ssl.termination=true --o:num_prespawn_children=4
  
  server_name: test.casereditions.local
  
  existingSecret:
    enabled: false
    secretName: ""
    usernameKey: "username"
    passwordKey: "password"
  password: adminadmin
  username: admin
  env: []


  extraVolumes:
  - name: wopi-fonts
    hostPath:
      path: /run/desktop/mnt/host/c/k8s-volumes/wopi-fonts
      type: Directory


  extraVolumeMounts:
    - name: wopi-fonts
      mountPath: /opt/cool/systemplate/tmpfonts


autoscaling:
  minReplicas: 1


resources: {}


replicaCount: 1

dynamicConfig:

  ingress:
    hosts:
      - host: test.casereditions.local
        paths:
          - path: /
            pathType: ImplementationSpecific
    tls:
      hosts:
        - test.casereditions.local
      secretName: test-casereditions

podLabels:
  networking/data.egress: "true"
  networking/internet.egress: "true"
  networking/internet.ingress: "true"
  networking/service.egress: "true"
  networking/service.gress: "true"
  networking/webapp.egress: "true"
  networking/webapp.ingress: "true"

Helm is deploying this without a problem. But I don’t see the volume in the pod.

I am using the latest collabora-online Helm chart.

The path on the host is showing the folder with the extra fonts.

/ # ls -l /run/desktop/mnt/host/c/k8s-volumes/wopi-fonts
total 20132
-rwxrwxrwx    1 root     root       2259616 Sep  4 23:11 GothicA1-Black.ttf
-rwxrwxrwx    1 root     root       2285888 Sep  4 23:11 GothicA1-Bold.ttf
-rwxrwxrwx    1 root     root       2279996 Sep  4 23:11 GothicA1-ExtraBold.ttf
-rwxrwxrwx    1 root     root       2297240 Sep  4 23:11 GothicA1-ExtraLight.ttf
-rwxrwxrwx    1 root     root       2296968 Sep  4 23:11 GothicA1-Light.ttf
-rwxrwxrwx    1 root     root       2287684 Sep  4 23:11 GothicA1-Medium.ttf
-rwxrwxrwx    1 root     root       2294192 Sep  4 23:11 GothicA1-Regular.ttf
-rwxrwxrwx    1 root     root       2287416 Sep  4 23:11 GothicA1-SemiBold.ttf
-rwxrwxrwx    1 root     root       2307184 Sep  4 23:11 GothicA1-Thin.ttf
/ #

But in the pod there is nothing under systemplate.

cool@wopi-client-collabora-online-666d54d55f-9dvv6:/$ ls -l /opt/cool/systemplate/
total 36
drwxr-xr-x 2 root root 4096 Oct 11 15:05 dev
drwxr-xr-x 5 root root 4096 Oct 11 15:05 etc
drwxr-xr-x 3 root root 4096 Oct 11 15:05 lib
drwxr-xr-x 2 root root 4096 Oct 11 15:05 lib64
drwxr-xr-x 2 root root 4096 Oct 11 15:05 lo
drwxr-xr-x 2 root root 4096 Oct 11 15:05 opt
drwxr-xr-x 3 root root 4096 Oct 11 15:05 tmp
drwxr-xr-x 4 root root 4096 Oct 11 15:05 usr
drwxr-xr-x 3 root root 4096 Oct 11 15:05 var
cool@wopi-client-collabora-online-666d54d55f-9dvv6:/$

Can you see what I am doing wrong?

I did some further research in this matter and I think the deployment.yaml has no code to handle the extraVolumes and extraVolumeMounts.

Am I correct in my conclusion?

@jaapglasbergen I’ve also done some research on this, and so far, I haven’t found a way to mount the font path. I’m consulting with others about possible solutions, and I’ll share any findings here soon.

Thanks,
Darshan

@darshan I made some changes to the deployment.yaml file and it is now mounting the proper folder to the /opt/cool/systemplate/tmpfonts folder.
I hope you guys can add this to the Helm chart.

deployment.yaml

{{- if eq .Values.deployment.kind "Deployment" -}}
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "collabora-online.fullname" . }}
  labels:
    {{- include "collabora-online.labels" . | nindent 4 }}
spec:
  minReadySeconds: {{ .Values.deployment.minReadySeconds }}
  {{- if not .Values.autoscaling.enabled }}
  replicas: {{ .Values.replicaCount }}
  {{- end }}
  strategy:
    type: {{ .Values.deployment.type }}
    {{- if eq .Values.deployment.type "RollingUpdate"}}
    rollingUpdate:
      maxSurge: {{ .Values.deployment.maxSurge }}
      maxUnavailable: {{ .Values.deployment.maxUnavailable }}
    {{- end}}
  selector:
    matchLabels:
      {{- include "collabora-online.selectorLabels" . | nindent 6 }}
      type: main
  template:
    metadata:
      annotations:
        {{- with .Values.podAnnotations }}
        {{- toYaml . | nindent 8 }}
        {{- end }}
        confighash: config-{{ .Values.collabora | toYaml | sha256sum | trunc 32 }}
        cluster-autoscaler.kubernetes.io/safe-to-evict: "true"
      labels:
        {{- include "collabora-online.selectorLabels" . | nindent 8 }}
        type: main
        {{- with .Values.podLabels }}
        {{- toYaml . | nindent 8 }}
        {{- end }}
    spec:
      {{- with .Values.deployment.hostAliases }}
      hostAliases:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }}
      {{- with .Values.imagePullSecrets }}
      imagePullSecrets:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      serviceAccountName: {{ include "collabora-online.serviceAccountName" . }}
      securityContext:
        {{- toYaml .Values.podSecurityContext | nindent 8 }}
      containers:
        - name: {{ .Chart.Name }}
          securityContext:
            {{- toYaml .Values.securityContext | nindent 12 }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: http
              containerPort: {{ .Values.deployment.containerPort }}
              protocol: TCP
          {{- if .Values.probes.startup.enabled }}
          startupProbe:
            httpGet:
              path: /
              port: {{ .Values.deployment.containerPort }}
              scheme: HTTP
            failureThreshold: {{ .Values.probes.startup.failureThreshold }}
            periodSeconds: {{ .Values.probes.startup.periodSeconds }}
          {{- end }}
          {{- if .Values.probes.liveness.enabled }}
          livenessProbe:
            httpGet:
              path: /
              port: {{ .Values.deployment.containerPort }}
              scheme: HTTP
            initialDelaySeconds: {{ .Values.probes.liveness.initialDelaySeconds }}
            periodSeconds: {{ .Values.probes.liveness.periodSeconds }}
            timeoutSeconds: {{ .Values.probes.liveness.timeoutSeconds }}
            successThreshold: {{ .Values.probes.liveness.successThreshold }}
            failureThreshold: {{ .Values.probes.liveness.failureThreshold }}
          {{- end }}
          {{- if .Values.probes.readiness.enabled }}
          readinessProbe:
            httpGet:
              path: /
              port: {{ .Values.deployment.containerPort }}
              scheme: HTTP
            initialDelaySeconds: {{ .Values.probes.readiness.initialDelaySeconds }}
            periodSeconds: {{ .Values.probes.readiness.periodSeconds }}
            timeoutSeconds: {{ .Values.probes.readiness.timeoutSeconds }}
            successThreshold: {{ .Values.probes.readiness.successThreshold }}
            failureThreshold: {{ .Values.probes.readiness.failureThreshold }}
          {{- end }}

          envFrom:
            - configMapRef:
                name: {{ include "collabora-online.fullname" . }}
          env:
            - name: username
              valueFrom:
                secretKeyRef:
                  {{- if (.Values.collabora.existingSecret).enabled }}
                  name: {{ .Values.collabora.existingSecret.secretName | quote }}
                  key: {{ .Values.collabora.existingSecret.usernameKey | quote }}
                  {{- else }}
                  name: {{ include "collabora-online.fullname" . }}
                  key: username
                  {{- end }}
            - name: password
              valueFrom:
                secretKeyRef:
                  {{- if (.Values.collabora.existingSecret).enabled }}
                  name: {{ .Values.collabora.existingSecret.secretName | quote }}
                  key: {{ .Values.collabora.existingSecret.passwordKey | quote }}
                  {{- else }}
                  name: {{ include "collabora-online.fullname" . }}
                  key: password
                  {{- end }}
            {{- with .Values.collabora.env }}
            {{ toYaml . | nindent 12 }}
            {{- end }}
          resources:
            {{- toYaml .Values.resources | nindent 12 }}
          volumeMounts:
            - name: tmp
              mountPath: /tmp
{{- if .Values.collabora.extraVolumeMounts }}
{{ toYaml .Values.collabora.extraVolumeMounts | indent 12 }}
{{- 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 }}
      volumes:
        - name: tmp
          emptyDir: {}
{{- if .Values.collabora.extraVolumes }}
{{ toYaml .Values.collabora.extraVolumes | indent 8 }}
{{- end }}
{{- end }}

values.yaml

---
# Default values for newchart.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

image:
  repository: collabora/code
  pullPolicy: IfNotPresent
  # Overrides the image tag whose default is the chart appVersion.
  tag: ""

imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
terminationGracePeriodSeconds: 60

serviceAccount:
  # Specifies whether a service account should be created
  create: false
  # Annotations to add to the service account
  annotations: {}
  # The name of the service account to use.
  # If not set and create is true, a name is generated using the fullname template
  name: ""

collabora:
  # example to add aliasgroups
  # - host: "<protocol>://<host-name>:<port>"
  #   aliases: ["<protocol>://<its-first-alias>:<port>, <protocol>://<its-second-alias>:<port>"]
  aliasgroups: []

  extra_params: --o:ssl.enable=false

  # External hostname:port of the server running coolwsd.
  # If empty, it's derived from the request (please set it if this doesn't work).
  # May be specified when behind a reverse-proxy or when the hostname is not reachable directly.
  server_name: null

  existingSecret:
    enabled: false
    secretName: ""
    usernameKey: "username"
    passwordKey: "password"
  password: examplepass
  username: admin
  env: []

  extraVolumes:
  - name: wopi-fonts
    hostPath:
      path: /run/desktop/mnt/host/c/k8s-volumes/wopi-fonts
      type: Directory

  extraVolumeMounts:
  - name: wopi-fonts
    mountPath: /opt/cool/systemplate/tmpfonts

prometheus:
  servicemonitor:
    enabled: false
    labels: {}
  rules:
    enabled: false
    additionalLabels: {}
    defaults:
      enabled: true
      docs:
        duplicated: 0
        pod:
          critical: 10
          warning: 8
          info: 5
        sum:
          critical: 500
          warning: 200
          info: 50
      errorServiceUnavailable:
        critical: 50
        warning: 2
        info: 0
      errorUnauthorizedRequest:
        observationInterval: "60m"
        eventCounter: 8
      errorStorageConnections:
        critical: 50
        warning: 2
        info: 0
      viewers:
        pod:
          critical: 100
          warning: 80
          info: 60
        doc:
          critical: 50
          warning: 40
          info: 30
        sum:
          critical: 15000
          warning: 12000
          info: 5000
    additionalRules: []

grafana:
  dashboards:
    enabled: false
    labels:
      grafana_dashboard: "1"
    annotations: {}

# Logging
# This HelmChart could also deploy Flow for the [Logging-Operator](https://kube-logging.github.io/docs/)
# Configuration is optimzed for deliever to elasticsearch
logging:
  # -- Deploy Flow for logging-operator
  enabled: false
  # -- Enable record filter for record_modify to the [ElasticCommonSchema](https://www.elastic.co/guide/en/ecs/current/index.html)
  ecs: false
  # -- if an filter (here or global) for dedot is active - for disable set `null`
  dedot:
  # -- Add other filters to Flow
  additionalFilters: []
  # -- Flows localOutputRefs for use of Outputs
  localOutputRefs: []
  # -- Flows globalOutputRefs for use of ClusterOutputs
  globalOutputRefs:
    - "default"

podAnnotations: {}

podLabels: {}

podSecurityContext: {}
#  fsGroup: 2000

securityContext: {}
#  readOnlyRootFilesystem: false
#  privileged: true
#  capabilities:
#    drop:
#    - ALL
#  readOnlyRootFilesystem: true
#  runAsNonRoot: true
#  runAsUser: 1000

service:
  type: ClusterIP
  port: 9980
  annotations: {}

deployment:
  # Use StatefulSet or Deployment
  kind: Deployment
  containerPort: 9980
  type: RollingUpdate
  minReadySeconds: 0
  maxUnavailable: 0
  maxSurge: 1
  # info on how to use hostAliases: https://kubernetes.io/docs/tasks/network/customize-hosts-file-for-pods/
  # note: different from aliasgroups
  hostAliases: null

probes:
  startup:
    enabled: true
    failureThreshold: 30
    periodSeconds: 3

  readiness:
    enabled: true
    initialDelaySeconds: 0
    periodSeconds: 10
    timeoutSeconds: 30
    successThreshold: 1
    failureThreshold: 2
  liveness:
    enabled: true
    initialDelaySeconds: 0
    periodSeconds: 10
    timeoutSeconds: 30
    successThreshold: 1
    failureThreshold: 4

ingress:
  enabled: false
  className: ""
  annotations: {}
  # # nginx
  #  nginx.ingress.kubernetes.io/upstream-hash-by: "$arg_WOPISrc"
  # # block admin urls from outside
  #  nginx.ingress.kubernetes.io/server-snippet: |
  #    location /cool/getMetrics { deny all; return 403; }
  #    location /cool/adminws/ { deny all; return 403; }
  #    location /browser/dist/admin/admin.html { deny all; return 403; }
  #
  # # HAProxy
  #  haproxy.org/timeout-tunnel: "3600s"
  #  haproxy.org/backend-config-snippet: |
  #    mode http
  #    balance leastconn
  #    stick-table type string len 2048 size 1k store conn_cur
  #    http-request set-var(txn.wopisrcconns) url_param(WOPISrc),table_conn_cur()
  #    http-request track-sc1 url_param(WOPISrc)
  #    stick match url_param(WOPISrc) if { var(txn.wopisrcconns) -m int gt 0 }
  #    stick store-request url_param(WOPISrc)
  #
  # # HAProxy - Community: https://haproxy-ingress.github.io/
  #  haproxy-ingress.github.io/timeout-tunnel: 3600s
  #  haproxy-ingress.github.io/balance-algorithm: url_param WOPISrc check_post
  #  haproxy-ingress.github.io/config-backend:
  #    hash-type consistent
  # # block admin urls from outside
  #    acl admin_url path_beg /cool/getMetrics
  #    acl admin_url path_beg /cool/adminws/
  #    acl admin_url path_beg /browser/dist/admin/admin.html
  #    http-request deny if admin_url
  #
  hosts:
    - host: chart-example.local
      paths:
        - path: /
          pathType: ImplementationSpecific
  tls: []
  #  - secretName: chart-example-tls
  #    hosts:
  #      - chart-example.local

# 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:'.
resources: {}
#  limits:
#    cpu: 100m
#    memory: 128Mi
#  requests:
#    cpu: 100m
#    memory: 128Mi

replicaCount: 1

autoscaling:
  enabled: true
  minReplicas: 2
  maxReplicas: 100
  targetCPUUtilizationPercentage: 70
  targetMemoryUtilizationPercentage: 50
  scaleDownDisabled: false

dynamicConfig:
  enabled: false
  logging:
    enabled: false
    ecs: false
    dedot:
    additionalFilters: []
    localOutputRefs: []
    globalOutputRefs:
      - "default"

  image:
    repository: nginx
    tag: 1.25
    pullPolicy: IfNotPresent

  replicaCount: 1
  podAnnotations: []
  podSecurityContext: {}
  securityContext: {}

  # configVolumeType: configMap # configMap or pvc

  existingConfigMap:
    enabled: false
    name: ""

  upload:
    enabled: false
    image:
      repository: "twostoryrobot/simple-file-upload"
      digest: 547fc4360b31d8604b7a26202914e87cd13609cc938fd83f412c77eb44aa1cc4
    key: TESTKEY
    pvc:
      size: 1Gi
      accessMode: "ReadWriteOnce"
      # storageClassName: ""
    service:
      port: 8090
    ingress:
      enabled: false
      className: ""
      annotations: {}
      hosts:
        - host: chart-example.local
          paths:
            - path: /
              pathType: ImplementationSpecific
      tls: []
      #  - secretName: chart-example-tls
      #    hosts:
      #      - chart-example.local

    logging:
      enabled: false
      ecs: false
      dedot:
      additionalFilters: []
      localOutputRefs: []
      globalOutputRefs:
        - "default"

  containerPort: 80

  probes:
    startup:
      enabled: true
      failureThreshold: 30
      periodSeconds: 2
    readiness:
      enabled: true
      initialDelaySeconds: 0
      periodSeconds: 10
      timeoutSeconds: 30
      successThreshold: 1
      failureThreshold: 2
    liveness:
      enabled: true
      initialDelaySeconds: 0
      periodSeconds: 10
      timeoutSeconds: 30
      successThreshold: 1
      failureThreshold: 4

  env: []
  resources: {}
  nodeSelector: {}
  tolerations: []
  affinity: {}

  service:
    port: 8080

  ingress:
    enabled: false
    className: ""
    annotations: {}
    hosts:
      - host: chart-example.local
        paths:
          - path: /
            pathType: ImplementationSpecific
    tls: []
    #  - secretName: chart-example-tls
    #    hosts:
    #      - chart-example.local

  configuration: |
    {}

trusted_certs_install:
  enabled: false
  trusted_certs: []

nodeSelector: {}

tolerations: []

affinity: {}

1 Like

hii @jaapglasbergen i just check your deployment.yaml file.

What is reason behind removing this part ?

           {{- if .Values.collabora.proofKeysSecretRef }}
            - name: wopi-proof
              mountPath: /etc/coolwsd/proof_key
              subPath: proof_key
            - name: wopi-proof
              mountPath: /etc/coolwsd/proof_key.pub
              subPath: proof_key.pub
            {{- end }}

Also is it possible to mount local folder using helm chart ? Have you tried it ? Does the custom fonts are working now ?

I think the proofKeySecretRef was lost in the copy/paste. I didn’t remove it on purpose.
The change is only adding the 2 blocks for extraVolumes and extraVolumeMounts.

{{- if .Values.collabora.extraVolumeMounts }}
{{ toYaml .Values.collabora.extraVolumeMounts | indent 12 }}
{{- end }}

{{- if .Values.collabora.extraVolumes }}
{{ toYaml .Values.collabora.extraVolumes | indent 8 }}
{{- end }}

I mounted a local path with hostPath and this works fine. I run a local cluster on my workstation and mounted a folder from my C drive in the pod.

Unfortunately the custom fonts don’t work. If I link the fonts in /opt/cool/systemplate/tmpfonts the fonts are not visible in the fonts dropdown.

I also linked them in /usr/local/share/fonts/truetype/ and then I do see the fonts in the dropdown. However, if I select one of the fonts the cursor disappears from the editor. If I then click on a place in the editor the default font is selected again.
If I select a piece of text and then select the font from the dropdown the piece of text disappears.

@jaapglasbergen i think it’s a feature that is missing, Can you help me to file a GH issue ? Collabora Online Github

Thanks,
Darshan