Skip to main content

Self-hosting the administration panel

Availability

info

The administration panel is only available in the SAAS version of WorkAdventure. For most users, we ask you to use the SAAS version of WorkAdventure as it is the easiest and most reliable way to use WorkAdventure. We provide a high-quality service with automatic updates and backups, and we take care of the infrastructure for you. Exceptionally, for some specific use cases (large corporate or institutional clients with a strong need for privacy and a large number of users), we can provide a self-hosted version of the administration panel.

If you are interested in the self-hosted version of the administration panel, please contact us at [email protected].

Requirements

You will need the following domain names to host the administration panel:

  • A domain name for the administration panel (e.g. admin.example.com)
  • A domain name for the "members" website (e.g. member.example.com)
  • A domain name for PHPMyAdmin to troubleshoot the database (optional) (e.g. phpmyadmin.example.com)
  • A domain name for Matrix-Synapse (e.g. matrix.example.com)

In addition, if you plan to deploy WorkAdventure with the administration panel, you will need:

  • Three domain names for WorkAdventure (e.g. play.example.com, pusher.example.com, room-api.example.com)
  • A domain name for "icon fetcher" service (e.g. icon.example.com)
  • A wildcard domain name for the map storage (e.g. *.map-storage.example.com) (or at least one subdomain per world)
  • A domain name for "uploader" service (e.g. uploader.example.com)

Finally, this documentation does not detail the setup of the Jitsi Meet and TURN services. Do not forget to set up these services too.

Installing the administration panel

We provide a Helm chart to install the administration panel on a Kubernetes cluster.

The Helm chart is available at https://charts.workadventu.re.

The very first step is to create a public / private key pair for the Laravel Passport keys and save them in a Kubernetes secret.

openssl genrsa -out private.key 2048
openssl rsa -in private.key -pubout -out public.key

# Create a namespace and put the keys in a secret
kubectl create namespace [your-namespace]
kubectl -n [your-namespace] create secret generic passport-keys \
--from-file=private.key=private.key \
--from-file=public.key=public.key

Then, you can configure the values.yaml file with the correct values for your installation.

Here is an example of a minimal values.yaml file:

domainName: "example.com"

admin:
imageCredentials:
# This password will be provided to you by WorkAdventure
password: "your-docker-registry-password"

ingress:
tls: true
# Here, put whatever annotations you need to configure the ingress (and the certificate)
annotationsPath:
cert-manager.io/cluster-issuer: letsencrypt-prod

Once the values.yaml file is configured, you can install the administration panel with the following commands:

helm repo add workadventure-charts https://charts.workadventu.re
helm upgrade --install -n [your-namespace] -f values.yaml workadventure-admin workadventure-charts/workadventure-admin

Setting up database credentials

By default, the Helm chart will set up a MySQL database and generate random credentials for the "root" user, and for the "workadventure" user.

If you want to provide your own credentials, you can do so by adding the following section to your values.yaml file:

# Root password for the MySQL database
# If empty, will be autogenerated
dbRootPassword: ""

# Database password of the "workadventure" user
# If empty, will be autogenerated
dbPassword: ""

Configuring the database

It is advised to configure the disk space for the database PVC, along with the resources requests to be sure the database is allocated on a pod with enough resources.

Here is an example of a values.yaml file to configure the database:

mysql:
primary:
persistence:
size: 10Gi
resources:
requests:
memory: 3Gi
cpu: 1

Configuring the database backup

The administration panel comes with a backup system that can be configured to automatically backup the database to an S3 compatible storage.

Here is an example of a values.yaml file to configure the backup system:

backup:
enabled: false
bucket: null
fileName: workadventure-mysql-backup
endpointUrl: null
accessKeyId: null
secretAccessKey: null
schedule: "0 4 * * *"
count: 30

Adding PHPMyAdmin to the administration panel

In order to debug and maintain the database of the administration panel, you may want to install PHPMyAdmin.

Here is an example of a values.yaml file to install PHPMyAdmin:

phpmyadmin:
enabled: true
ingress:
enabled: true
hostname: phpmyadmin.example.com
tls: true
annotations:
# Here, put whatever annotations you need to configure the ingress (and the certificate)
# Your mileage may vary depending on your Kubernetes cluster and your ingress controller
cert-manager.io/cluster-issuer: letsencrypt-prod

The complete list of available values can be read in Bitnami's PhpMyAdmin chart documentation.

Setting up OpenID credentials

The administration panel uses OpenID to authenticate users from WorkAdventure and from Synapse. By default, it will create 2 OpenID client credentials with the appropriate secrets.

Because it can be tedious to retrieve those secrets, we advise you to provide them in the values.yaml file:

admin:
secretEnv:
"PASSPORT_PRIVATE_KEY": "a 40 characters long secret alphanumeric string"
"PASSPORT_CLIENT_WORKADVENTURE_SECRET": "another 40 characters long secret alphanumeric string"

Setting up the SMTP server

The admin dashboard sends emails to users for various reasons (password reset, sending invitations, ...).

You can configure the SMTP server to use in the values.yaml file:

admin:
env:
MAIL_MAILER: smtp
MAIL_HOST: <your SMTP server domain name>
MAIL_PORT: <your SMTP server domain name>
MAIL_USERNAME: <user name>
MAIL_ENCRYPTION: <encryption method>
MAIL_FROM_ADDRESS: "[email protected]"
MAIL_FROM_NAME: "No reply"
secretEnv:
MAIL_PASSWORD: <password>

Configuring uploaded files storage

The administration panel will need to store uploaded files (like Wokas, custom logos, ...). Those files will be stored in a S3 compatible storage.

Here is an example of a values.yaml file to configure the uploaded files storage:

admin:
env:
AWS_ENDPOINT: "<URL to the S3 compatible storage>"
AWS_BUCKET: "<name of the bucket>"
AWS_DEFAULT_REGION: "<region of the bucket>"

secretEnv:
AWS_ACCESS_KEY_ID: "<access key>"
AWS_SECRET_ACCESS_KEY: "<secret key>"

WorkAdventure configuration

By default, the admin chart will install a WorkAdventure instance with the default configuration.

You should customize the configuration of the WorkAdventure instance by providing a specific workadventure entry in the values.yaml file.

workadventure:
enabled: true
domainName: "example.com"
ejabberdDomain: "ejabberd.example.com"

ingress:
tls: true
annotationsRoot:
cert-manager.io/cluster-issuer: letsencrypt-prod

Map storage multi domain setup

The map-storage container needs to listen on all subdomains of the "map-storage" domain. This can be tricky to set up as it means you will need a wildcard ingress, with the associated certificates.

There are two solutions to this problem:

  • use a wildcard ingress and a wildcard certificate for the map-storage domain
  • or manually create ingresses for every subdomain of the map-storage domain you use (this will require modifying the configuration each time you create a new world)

Wildcard configuration

If you go with the first solution, you will need a Traefik ingress controller and a wildcard certificate for the map-storage domain.

Turn on the enableWildcardMapstorageDomains option in the values.yaml file:

# Whether to enable or not wildcard map storage domains. This requires a Traefik ingress controller to work
enableWildcardMapstorageDomains: true
# Suffix of the map storage domain. Note: there is one map-storage domain per world
# Defaults to ".map-storage.[domainName]"
publicMapStorageDomainSuffix: ""

workadventure:
mapstorage:
# Let's disable the default ingress
ingress:
enabled: false

This will create a custom IngressRoute for Traefik to handle the wildcard domain.

Manual configuration

If you go with the second solution, you should declare the domain names in the values.yaml file:

workadventure:
mapstorage:
ingress:
# Each time you create a new world, you need to add the domain name here
domainNames:
- my-world-1.map-storage.example.com
- my-other-world-2.map-storage.example.com
- ...
caution

Only use this solution if you cannot obtain a wildcard certificate for your domain. It will require manual intervention each time you create a new world.

Setting up specific annotations for WorkAdventure ingress

The WorkAdventure chart does not provide HTTPS certificates out of the box but instead relies on third party software like cert-manager to provide them.

You can configure the ingress with specific annotations to use your own certificate:

workadventure:
ingress:
tls: true
annotationsRoot:
# If you are using nginx + cert-manager, you can use the following annotations
cert-manager.io/cluster-issuer: letsencrypt-prod
# If you are using Traefik, you can use the following annotations
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls.certresolver: letsencrypt

Configuring Jitsi Meet

To plug WorkAdventure to your Jitsi instance, you need to provide the following configuration in the values.yaml file:

workadventure:
commonEnv:
# The Jitsi domain name (with the protocol)
JITSI_DOMAIN: "<Jitsi domain name>"
# The XMPP domain configured in your Jitsi instance (by default it is meet.jitsi)
JITSI_XMPP_DOMAIN: "meet.jitsi"
# The XMPP domain configured for MUC rooms in your Jitsi instance (by default it is muc.meet.jitsi)
JITSI_MUC_DOMAIN: "muc.meet.jitsi"
# The full URL to your Jitsi server (with the protocol)
JITSI_URL: "https://jitsi.deeplabverse.deeplab.fr"
# An ISS value for JWT tokens. Can be anything
JITSI_ISS: "meetworkadventure"

commonSecretEnv:
# The key should match the one in the Jitsi Helm Chart (prosody.extraEnvs.JWT_APP_SECRET)
SECRET_JITSI_KEY: "<some secret key>"

Configuring the TURN server

To plug WorkAdventure to your TURN server, you need to provide the following configuration in the values.yaml file:

workadventure:
commonEnv:
# The default Stun server to use
STUN_SERVER: stun:stun.l.google.com:19302
# The TURN server to use (you can put several values separated by commas)
TURN_SERVER: turn:57.128.59.167:3478,turn:57.128.59.167?transport=tcp
commonSecretEnv:
# The TURN authentication secret used to generate dynamic passwords
TURN_STATIC_AUTH_SECRET: "<some secret key>"

Configuring the map-storage storage service

The map-storage service can store the maps in a PVC or in a S3 compatible storage.

Here is an example of a values.yaml file to configure the map-storage service with a PVC:

workadventure:
mapstorage:
persistence:
enabled: true
size: "1Gi"

Here is an example of a values.yaml file to configure the map-storage service with a S3 compatible storage:

workadventure:
mapstorage:
env:
AWS_URL: "<URL to the S3 compatible storage (if not AWS)>"
AWS_BUCKET: "<name of the bucket>"
AWS_DEFAULT_REGION: "<region of the bucket>"

secretEnv:
AWS_ACCESS_KEY_ID: "<access key>"
AWS_SECRET_ACCESS_KEY: "<secret key>"

Matrix Synapse configuration

In order to install the Matrix Synapse server, we provide a separate Helm chart that can be installed along with the administration panel.

Note that you don't have to use our Matrix Synapse chart, you can use your own Matrix Synapse server if you want.

The chart we provide is based on the Ananace's Matrix Synapse chart and provides in addition a backup system and an automatic creation of an user dedicated to WorkAdventure.

The first step is to generate a secret containing the Matrix Synapse signing key. Be sure to save this signing key in a secure place. If you lose it, federation will stop working as the other Matrix servers are caching this signing key.

Getting a valid signing key is the hard part. A Docker installation of Matrix Synapse will generate one for you.

kubectl -n [your-namespace] create secret generic matrix-synapse-signing-key \
--from-file=signing.key=path_to_your_signing_key

Next, you need to provide the values.yaml file with the correct values for your installation.

You MUST at least provide the domain name of the Matrix Synapse server in the values.yaml file. Also, you MUST configure the OpenID endpoint in the values.yaml file to point to the administration panel.

synapse:

# The domain name for the Synapse server
serverName: "matrix.example.com"

# The public Matrix server name, this will be used for any public URLs
# in config as well as for client API links in the ingress.
publicServerName: "matrix.example.com"

ingress:
tls:
- secretName: ingress-secret-admin
# Don't forget to set the domain name here to generate a SSL certificate for it.
hosts:
- matrix.example.com


extraConfig:
oidc_providers:
- idp_id: workadventure-admin
idp_name: WorkAdventure
issuer: "http://member.[YOUR-WA-DOMAIN]"
skip_verification: true
client_id: "2"
client_secret: "[YOUR SECRET]"
scopes: ["openid", "email", "matrix", "profile"]

user_mapping_provider:
config:
# matrix_local_part is provided by the special "matrix" scope
localpart_template: "{{ user.matrix_local_part }}"
display_name_template: "{{ user.name }}"
email_template: "{{ user.email }}"

sso:
client_whitelist:
- https://pusher.[YOUR-WA-DOMAIN]/
- https://play.[YOUR-WA-DOMAIN]/

Note: replace [YOUR SECRET] with the Synapse client secret. In order to get it, you can look in your admin values.yaml file for the admin.secretEnv.PASSPORT_CLIENT_SYNAPSE_SECRET key.

If this secret is not set, WorkAdventure generated one for you. You can read it using this command:

kubectl -n [your-namespace] get secrets secret-env-admin -o jsonpath='{.data.PASSPORT_CLIENT_SYNAPSE_SECRET}' | base64 -d

When everything is setup, you can proceed to install the Matrix Synapse server with the following commands:

helm upgrade --install -n [your-namespace] -f values.yaml workadventure-synapse workadventure-charts/workadventure-synapse

Automatically creating a Matrix user

WorkAdventure needs a dedicated user on the Matrix Synapse server to create rooms and invite users. The Synapse chart can automatically create this user for you.

createMatrixUser: true
matrixUser: admin
matrixPassword: [TO BE FILLED]

Configuring the Matrix Synapse server in WorkAdventure

In order to connect WorkAdventure to the Matrix Synapse server, you need to provide the following configuration in the values.yaml file of the WorkAdventure chart:

workadventure:
commonEnv:
MATRIX_API_URI: "http://matrix:8008/"
MATRIX_PUBLIC_URI: "https://[YOUR-SYNAPSE-DOMAIN]/"
MATRIX_DOMAIN: '[YOUR-SYNAPSE-DOMAIN]'
MATRIX_ADMIN_USER: '[YOUR-SYNAPSE-USER]'
MATRIX_ADMIN_PASSWORD: '[YOUR-SYNAPSE-PASSWORD]'

In the example above:

  • replace [YOUR-SYNAPSE-DOMAIN] with the value of synapse.serverName in the values.yaml file of the Synapse chart
  • replace [YOUR-SYNAPSE-USER] with the value of matrixUser in the values.yaml file of the Synapse chart
  • replace [YOUR-SYNAPSE-PASSWORD] with the value of matrixPassword in the values.yaml file of the Synapse chart

Configuring the Matrix Synapse backup

You can configure the Matrix Synapse backup system to automatically back up the database to an S3 compatible storage.

backup:
enable: true
#schedule: "* * * * *"
keepDays: 7
s3:
accessKeyId: "[TO BE FILLED]"
bucket: "[TO BE FILLED]"
# If you are using a S3-compatible endpoint, you can set the URL here
# endpointUrl: "[TO BE FILLED]"
region: "[TO BE FILLED]"
secretAccessKey: "[TO BE FILLED]"