Sunday, December 19, 2021

Customizing the Jitsi Meet UI in a Docker deployment

I manage a Jitsi instance for a small for-benefit organization. I wanted to make some changes to the UI to make it visually belong to the organization. Unfortunately, Jitsi doesn't make it easy to do this. Upon every upgrade your changes are gone. This post describes a workaround for Jitsi deployments that use Docker.

Although the details can be hairy, the idea is quite simple. We are going to put another layer over the provided Docker image called 'web'. The additional layer contains all the changes we need. When Jitsi publishes an update, we just apply the changes again as part of the deployment process.

Our starting point is the docker-compose.yaml provided by Jitsi. Make all the changes as instructed. However, before we make any changes to the UI, you should make sure your Jitsi instance is working.

Its working? Congratulations! Start with a small change to your docker-compose.yaml.
Replace:

web: image: jitsi/web:latest

with:

web: build: ./jitsi-web

This sets you up for building your own Docker image.

Create the jitsi-web directory, and put all the artwork you want to override in it. You should end up with a directory structure like this (more details follow):

Directory structure

The Dockerfile in the jitsi-web initially has just one line like this:

FROM jitsi/web

Build the image and deploy it with:

docker-compose build --pull docker-compose up -d

Make sure that Jitsi is still working.

Now it is your turn to get creative. With some RUN instructions you can change any file in the base image.

To get you started, I'll show what is in my Dockerfile. Details are discussed directly below:

FROM jitsi/web # Add wasm mime type # https://community.jitsi.org/t/loading-wasm-webassembly-file-on-jitsimeetjs/68071/3 RUN sed -i '/}/i \ application/wasm wasm;' /etc/nginx/mime.types # Replace/add some images COPY --chown=root:root overrides /usr/share/jitsi-meet/ RUN sed -i "s|\(// \)\?defaultLanguage:.*|defaultLanguage: 'nl',|" /defaults/config.js; \ sed -e 's/welcome-background.png/welcome-background.jpg/' \ -e 's|.deep-linking-mobile .header{width:100%;height:70px;background-color:#f1f2f5;text-align:center}|.deep-linking-mobile .header{width:100%;height:70px;background-color:#003867;text-align:center}|' \ -e 's|.deep-linking-mobile .header .logo{margin-top:15px;margin-left:auto;margin-right:auto;height:40px}|.deep-linking-mobile .header .logo{margin-top:10px;margin-left:auto;margin-right:auto;height:50px}|' \ -i /usr/share/jitsi-meet/css/all.css; \ sed -e 's|"headerTitle": "Jitsi Meet"|"headerTitle": "Mijn Organisatie"|' \ -e 's|"headerSubtitle": "Veilige vergaderingen van hoge kwaliteit"|"headerSubtitle": "Wij vergaderen online!"|' \ -i /usr/share/jitsi-meet/lang/main-nl.json; \ sed -e 's|C().createElement("h1",{className:"header-text-title"},t("welcomepage.headerTitle"))|C().createElement("h1",{className:"header-text-title"},C().createElement("img",{src:"images/logo-deep-linking.png",alt:"Mijn Organisatie",height:100}))|' \ -e 's|"headerTitle":"Jitsi Meet"|"headerTitle":"Mijn Organisatie"|' \ -e 's|"headerSubtitle":"Secure and high quality meetings"|"headerSubtitle":"Wij vergaderen online!"|' \ -i /usr/share/jitsi-meet/libs/app.bundle.min.js; \ sed -e "s|\bAPP_NAME: .*|APP_NAME: 'Mijn Organisatie Jitsi',|" \ -e "s|\bPROVIDER_NAME: .*|PROVIDER_NAME: 'Mijn Organisatie Cloud',|" \ -e "s|\bDEFAULT_REMOTE_DISPLAY_NAME: .*|DEFAULT_REMOTE_DISPLAY_NAME: 'Gespreksgenoot',|" \ -e "s|\bDEFAULT_LOCAL_DISPLAY_NAME: .*|DEFAULT_LOCAL_DISPLAY_NAME: 'Ik',|" \ -e "s|\bGENERATE_ROOMNAMES_ON_WELCOME_PAGE: .*|GENERATE_ROOMNAMES_ON_WELCOME_PAGE: false,|" \ -i /defaults/interface_config.js

The first RUN instruction adds a line to the Nginx configuration which enables clients to download Wasm files. Unfortunately this is not yet fixed in Jitsi docker itself (checked at December 2021, but YMMV).

The COPY instruction copies your images over the existing stuff. Feel free to add more as needed.

The second RUN instruction is where the magic happens. This changes existing files. Let's go through them one by one.

The first file that gets changes in /defaults/config.js where we set the default language to Dutch.

The next file that gets changes is /usr/share/jitsi-meet/css/all.css. Normally Jitsi uses a png background image on the welcome page but I needed to use a jpg image. The first line takes care of that. Note that there is no welcome-background.jpg image in the base image, but I added it in the overrides/images directory.
The next 2 changes for this file are some small color and layout changes to the welcome page for mobile browsers.

The next file that gets changes is /usr/share/jitsi-meet/lang/main-nl.json. There are many more files in this directory, one for each language.

The next one, file /usr/share/jitsi-meet/libs/app.bundle.min.js is tricky. This file contains a fully compiled React application in minified Javascript. The first change you see here replaces the header text with a header image. The next two lines replace the the default titles with the Dutch version. For some reason Jitsi initially renders the page in English and then re-renders it in the correct locale. On slow devices this can take quite some time. I found this quite disturbing, especially for the texts that make your first impression. By changing some default texts, most of my users (which are Dutch) will see less flapping texts.
This is the file that is most sensitive to changes in the base image. Make sure your tweaks still work after an upgrade.

Finally, in /defaults/interface_config.js some more settings are tweaked.

Some more tips

Don't worry if you break something. Just fix your changes and re-deploy. A re-deploy is very quick.

Finding out what to change can be pretty hard. Sometimes it helps to extract the file from the image to see what it contains. First find the file you want to change by opening a shell in the base image:

docker-compose exec web bash

Extract the file for more detailed inspection with something like this:

docker-compose exec web cat /usr/share/jitsi-meet/libs/app.bundle.min.js > app.bundle.min.js

Jitsi updates

When you see new images appear at Jitsi on docker hub you can deploy them as follows:

# Pulls the images that we're not changing (e.g. prosody, jicofo and jvb): docker-compose pull # Rebuild the 'web' image, checking for a new base image: docker-compose build --pull # Deploy changes: docker-compose up -d # Remove old images: docker image prune

Most of the things that were tweaked here were pretty stable over the last years. But I advice you check anyway.

That's it, go creative!

4 comments:

  1. this is too messy...thanks for sharing but it's a total disgrace to mantain similar monster. shame to jitsi

    ReplyDelete
    Replies
    1. LOL! Yeah, it's quite messy. I am glad this instance was no longer needed and I could discard it. A 'disgrace'? I am not sure. Its open source, it might not be build for the purpose you have in mind.

      Delete
    2. Any chance you could expound on why the instance was "no longer needed"? Is that just a tech stack thing?

      Unfortunately, unless I missed something, is seem docker still minifies english and makes it impractical to change.

      Delete
    3. It was no longer needed because the users moved elsewhere.

      Delete