Getting started

This documentation lets you create an openDesk evaluation instance on your Kubernetes cluster.

Thanks for looking into the openDesk Getting Started guide. This document covers essential configuration steps to deploy openDesk onto your Kubernetes infrastructure.

Requirements

Detailed system requirements are covered on the requirements page.

Customize environment

Before deploying openDesk, you must configure the deployment to fit your environment. To keep your deployment up to date, we recommend customizing in dev, test, or prod and not in default environment files.

All configuration options and their default values can be found in files at helmfile/environments/default/

For the following guide, we will use dev as environment where variables can be set in helmfile/environments/dev/values.yaml.gotmpl.

DNS

The deployment is designed to deploy each application/service under a dedicated subdomain. For your convenience, we recommend creating a *.domain.tld A/AAAA-Record for your cluster Ingress Controller; otherwise, you must create an A/AAAA-Record for each subdomain.

Record nameTypeValueAdditional information
domain.tldAIPv4 address of your Ingress Controller
domain.tldAAAAIPv6 address of your Ingress ControllerOptional
*.domain.tldAIPv4 address of your Ingress Controller
*.domain.tldAAAAIPv6 address of your Ingress ControllerOptional
mail.domain.tldAIPv4 address of your postfix NodePort/LoadBalancerOptional, mail should directly be delivered to openDesk’s Postfix
mail.domain.tldAAAAIPv6 address of your postfix NodePort/LoadBalancerOptional, mail should directly be delivered to openDesk’s Postfix
domain.tldMX10 mail.domain.tld
domain.tldTXTv=spf1 +a +mx +a:mail.domain.tld ~allOptional, use proper MTA record if present
_dmarc.domain.tldTXTv=DMARC1; p=quarantineOptional
default._domainkey.domain.tldTXTv=DKIM1; k=rsa; h=sha256; ...Optional, DKIM settings
_caldavs._tcp.domain.tldSRV10 1 443 dav.domain.tld.Optional, CalDav auto discovery
_caldav._tcp.domain.tldSRV10 1 80 dav.domain.tld.Optional, CalDav auto discovery
_carddavs._tcp.domain.tldSRV10 1 443 dav.domain.tld.Optional, CardDav auto discovery
_carddav._tcp.domain.tldSRV10 1 80 dav.domain.tld.Optional, CardDav auto discovery

Domain

As example base domain for your deployment we use domain.tld in this document.

A list of all subdomains can be found in helmfile/environments/default/global.yaml.gotmpl.

All subdomains can be customized. For example, Nextcloud can be changed to files.domain.tld in dev environment:

global:
  hosts:
    nextcloud: "files"

The domain has to be set either via dev environment:

global:
  domain: "domain.tld"

or alternatively via environment variable:

export DOMAIN=domain.tld
Warning

Due to a limitation caused by a bug in the SSSD subcomponent, there is an upper bound on the total domain length used by openDesk. To avoid issues, we recommend keeping the openDesk base domain length below 94 characters.

Apps

Depending on your ideal openDesk deployment, you may wish to disable or enable certain apps. All available apps and their default values are located in helmfile/environments/default/opendesk_main.yaml.gotmpl.

ComponentNameDefaultDescription
Certificatesapps.certificates.enabledtrueTLS certificates
ClamAV (Distributed)apps.clamavDistributed.enabledfalseAntivirus engine
ClamAV (Simple)apps.clamavSimple.enabledtrueAntivirus engine
Collaboraapps.collabora.enabledtrueWeboffice
CryptPadapps.cryptpad.enabledtrueWeboffice
dkimpyapps.dkimpy.enabledfalsePostfix milter for DKIM
Dovecotapps.dovecot.enabledtrueMail backend
Elementapps.element.enabledtrueSecure communications platform
Homeapps.home.enabledtrueBase domain portal redirect
Jitsiapps.jitsi.enabledtrueVideoconferencing
MariaDBapps.mariadb.enabledtrueDatabase
Memcachedapps.memcached.enabledtrueCache Database
MinIOapps.minio.enabledtrueObject Storage
Nextcloudapps.nextcloud.enabledtrueFile share
Nubusapps.nubus.enabledtrueIdentity Management & Portal
OpenProjectapps.openproject.enabledtrueProject management
OX App Suiteapps.oxAppSuite.enabledtrueGroupware
Postfixapps.postfix.enabledtrueMTA
PostgreSQLapps.postgresql.enabledtrueDatabase
Redisapps.redis.enabledtrueCache Database
XWikiapps.xwiki.enabledtrueKnowledge management

For example, Jitsi can be disabled like this:

apps:
  jitsi:
    enabled: false

Private registries

By default, Helm charts and container images are fetched from OCI registries. These registries can be found in most cases in the openDesk/component section on openCode.

For untouched upstream artifacts that do not belong to a functional component’s core, we use upstream registries like Docker Hub.

Doing a test deployment will be fine with this setup. In case you want to deploy multiple times a day and fetch from the same IP address, you might run into rate limits at Docker Hub. In that case, and in case you prefer the use of a private image registry, you can configure these in your target environment by setting

  • global.imageRegistry for a private image registry and
  • global.helmRegistry for a private Helm chart registry.
global:
  imageRegistry: "my_private_registry.domain.tld"

alternatively, you can use an environment variable:

export PRIVATE_IMAGE_REGISTRY_URL=my_private_registry.domain.tld

or for more granular control over repository overrides per registry (rewrites):

repositories:
  image:
    dockerHub: "my_private_registry.domain.tld/docker.io/"
    registryOpencodeDe: "my_private_registry.domain.tld/registry.opencode.de/"

If authentication is required, you can reference imagePullSecrets as follows:

global:
  imagePullSecrets:
    - "external-registry"

Cluster capabilities

Service

Some apps, like Jitsi and Dovecot, require HTTP and external TCP connections. These apps create a Kubernetes service object. You can configure whether NodePort (for on-premises), LoadBalancer (for cloud), or ClusterIP (to disable) should be used:

cluster:
  service:
    type: "NodePort"

Networking

If your cluster does not have the default cluster.local domain configured, you need to provide the domain via:

cluster:
  networking:
    domain: "acme.internal"

If your cluster does not have the default 10.0.0.0/8 CIDR configured, you need to provide the CIDR via the following:

cluster:
  networking:
    cidr:
      - "127.0.0.0/8"

If your load balancer / reverse proxy IPs are not already included in the above cidr you need to explicitly configure their related IPs or IP ranges:

cluster:
  networking:
    incomingCIDR:
      - "172.16.0.0/12"

Ingress

The default value for the ingressClassName in openDesk is set to haproxy. This prevents fallback to the cluster’s default ingress class, since the Helm charts used by openDesk components are not consistently aligned in how they handle a missing or empty ingressClassName. In case you are using a non-standard ingressClassName for your Ingress controller you have to configure it as follows:

ingress:
  ingressClassName: "haproxy"
Note

Currently, the only Ingress controllers supported are haproxy-ingress.github.io and the deprecated ingress-nginx. See requirements.md for more details.

Container runtime

Some apps require specific configurations for the container runtime. You can set your container runtime like cri-o, containerd or docker by using the following attribute:

cluster:
  container:
    engine: "containerd"

Volumes

The StorageClass must be set using the following attribute:

persistence:
  storageClassNames:
    RWX: "my-read-write-many-class"
    RWO: "my-read-write-once-class"

RWX is optional and requires that your cluster has a ReadWriteMany volume provisioner. If you can make use of it, it largely benefits the distribution and scaling of apps. By default, only ReadWriteOnce is enabled. To enable ReadWriteMany you can use the following attribute:

cluster:
  persistence:
    readWriteMany: true

Customize deployment

While openDesk configures the applications with meaningful defaults, you can check functional.md if you want to change these defaults to better match your use case.

Connectivity

Ports

Note

If you use NodePort for service exposure, you must check your deployment for the actual ports and ensure they are opened where necessary.

Web-based user interface

To use the openDesk functionality with its web-based user interface, you need to expose the following ports publicly:

ComponentDescriptionPortType
openDeskKubernetes Ingress80TCP
openDeskKubernetes Ingress443TCP
Jitsi Video BridgeICE Port for video data10000UDP

Mail clients

To connect with mail clients like Thunderbird, the following ports need to be publicly exposed:

ComponentDescriptionPortType
DovecotIMAPS993TCP
POP3S995TCP
PostfixSMTP25TCP
SMTPS587TCP

Mail/SMTP configuration

Enabling DKIM signing for outgoing emails helps reduce the risk of messages being marked as spam and improves recipient trust. openDesk includes dkimpy-milter as a Postfix milter for signing emails. You can configure the following attributes:

apps:
  dkimpy:
    enabled: true
smtp:
  dkim:
    key:
      value: "HzZs08QF1O7UiAkcM9T3U7rePPECtSFvWZIvyKqdg8E="
    selector: "default"
    useED25519: true # when false, RSA is used

A common scenario for outgoing mail is to send it through a smarthost or mail relay, which often handles DKIM signing as well.

If you prefer to use a smarthost, you can configure it as follows:

smtp:
  host: "smarthost.domain.tld"
  username: "smarthost-auth-username"
  password: "secret"

It is strongly recommended to configure a milter host for spam filtering (e.g. Rspamd) to get SPF and DKIM validation for incoming mails in place. Otherwise external senders could spoof internal sender addresses.

smtp:
  spamMilter:
    host: "rspamd.domain.internal"
    port: "11332"

TURN configuration

Some components (Jitsi, Element) use a TURN server for direct communication. You can configure your own TURN server with these options:

turn:
  transport: "udp" # or tcp
  credentials: "secret"
  server:
    host: "turn.domain.tld"
    port: "3478"
  tls:
    host: "turns.domain.tld"
    port: "5349"

Certificate issuer

As mentioned in requirements, you can provide your own valid certificate. A TLS type secret named opendesk-certificates-tls must be present in the application namespace. For deployment, you can turn off Certificate resource creation with:

apps:
  certificates:
    enabled: false

If you want to leverage cert-manager.io to handle certificates, like Let's encrypt, you need to provide the configured cluster issuer:

certificate:
  issuerRef:
    name: "letsencrypt-prod"

Additionally, it is possible to request wildcard certificates with:

certificate:
  wildcard: true

Password seed

All secrets are generated from a master password via Master Password (algorithm). To prevent others from using your openDesk instance, you must set your individual master password via:

export MASTER_PASSWORD="your_individual_master_password"
Important

Currently a documented upstream bug causes a failure when passwords/secrets beginning with certain numbers are using for the Nubus subcomponent NATS. With openDesk 1.6.0 an update-aware workaround was implemented that prefixes the affected secrets in the openDesk included secrets.yaml.gotmpl that derives all secrets from the previously mentioned MASTER_PASSWORD. If you are using externally provided passwords/secrets make sure that none of the ones listed below are starting with a number:

  • secrets.nubus.provisioning.api.natsPassword
  • secrets.nubus.provisioning.dispatcherNatsPassword
  • secrets.nubus.provisioning.prefillNatsPassword
  • secrets.nubus.provisioning.udmListenerNatsPassword
  • secrets.nubus.provisioning.udmTransformerNatsPassword
  • secrets.nats.natsAdminPassword

Install

After setting your environment-specific values in dev environment, you can start deployment by:

helmfile apply -e dev -n <NAMESPACE> [-l <label>] [--suppress-diff]

Arguments:

  • -e <env>: Environment name out of default, dev, test, prod
  • -n <namespace>: Kubernetes namespace
  • -l <label>: Label selector
  • --suppress-diff: Disable diff printing

Install single app

You can also install or upgrade only a single app like Collabora, either by using a label selector:

helmfile apply -e dev -n <NAMESPACE> -l component=collabora

or by switching to the apps’ directory (faster) and install or upgrade from there directly:

cd helmfile/apps/collabora
helmfile apply -e dev -n <NAMESPACE>

Install single release/chart

Instead of iterating through all services, you can also deploy a single release like mariadb by executing the following:

helmfile apply -e dev -n <NAMESPACE> -l name=mariadb

Using from external repository

Referring to ./helmfile_generic.yaml.gotmpl from an external directory or repository is possible. The helmfile.yaml.gotmpl that refers to ./helmfile_generic.yaml.gotmpl may define custom environments. These custom environments may overwrite specific configuration values. These configuration values are:

  • global.domain
  • global.helmRegistry
  • global.master_password

Access deployment

Login

When all apps are successfully deployed, and their Pod status is Running or Succeeded, you can navigate to

https://domain.tld

which will redirect you to the actual URL of the openDesk portal:

https://portal.domain.tld

By default the portal will send you to openDesk’s login screen.

Credentials

openDesk deploys with the standard user account Administrator, the password for which can be retrieved as follows:

# Set your namespace
NAMESPACE=<your_namespace>
 
# Get password for IAM "Administrator" account
kubectl -n ${NAMESPACE} get secret ums-nubus-credentials -o jsonpath='{.data.administrator_password}' | base64 -d

Using the aforementioned account, you can either create new accounts manually or make use of the openDesk User Importer script or container.

In the following snippet, after defining the values of the first three lines and executing the command, you get two accounts, default and default-admin:

ADMINISTRATOR_PASSWORD=<your_administrator_password_see_above>
DOMAIN=<your_domain>
DEFAULT_USERS_PASSWORD=<password_for_the_created_default_accounts>
docker run --rm registry.opencode.de/bmi/opendesk/components/platform-development/images/user-import:3.0.0 \
  ./user_import_udm_rest_api.py \
    --import_domain ${DOMAIN} \
    --udm_api_password ${ADMINISTRATOR_PASSWORD} \
    --set_default_password ${DEFAULT_USERS_PASSWORD} \
    --import_filename template.ods \
    --create_admin_accounts True

Uninstall

You can uninstall the deployment by executing the following:

helmfile destroy -n <NAMESPACE>
Note

Not all Jobs, PersistentVolumeClaims, or Certificates are deleted; you have to delete them manually

‘Sledgehammer destroy’ - for fast development turn-around times (at your own risk):

NAMESPACE=your-namespace
 
# Uninstall all Helm charts
for OPENDESK_RELEASE in $(helm ls -n ${NAMESPACE} -aq); do
  helm uninstall -n ${NAMESPACE} ${OPENDESK_RELEASE};
done
 
# Delete leftover resources
kubectl delete pvc --all --namespace ${NAMESPACE};
kubectl delete jobs --all --namespace ${NAMESPACE};
kubectl delete configmaps --all --namespace ${NAMESPACE};
Warning

Without specifying a --namespace flag, or by leaving it empty, cluster-wide components will get deleted!