Zoom Sucks: Riot Chat + Jitsi Video Conference Setup

This a somewhat complex install, and in high demand right now, so I figured i’d share my steps in getting a Riot.im chat server syndicated through a Matrix bridge that supports a Jitsi voip/video conference bridge. The end result is a self-hosted discord-like chat server where any chat room can become a video conference with a single click! It has some other neat features like end-to-end encryption and syndication with other matrix server AND other types of chat servers (you can have a chat room that links to a discord room, irc channel, etc). We’ll do almost all of this using apps from the Unraid Community Applications repo!

Summary:
We’ll setup some domains for each of our components, then use a LetsEncrypt proxy to generate certificates. Matrix will run the back-end, Riot Chat will run the front-end, and Jitsi will handle the A/V.

DNS Setup:
You’re gonna want a few subdomains, even if you have a dyndns setup pointing to your host. Then can all point to the same IP, or you can use CNAME or ALIAS records to point to the root domain. A DNS setup for somedomain.gg might look like this:

Type Host Value
A @ 1.2.3.4
CNAME bridge somedomain.gg
CNAME chat somedomain.gg
CNAME video somedomain.gg

In the above-the @ A-record will set the IP for your domain root, and the CNAME-records will cause the 3 subdomains to resolved to whatever domain name you point them at (the root domain, this this case).

Each domain will host the following:
bridge: matrix - The core communications protocol
chat: riot - The chat web UI
video: jitsi - The video conferencing bridge

LetsEncrypt:
First, wait for your DNS server to update, and make sure you can resolve 4 of the domains remotely. This is REQUIRED for LetsEncrypt to validate the domains!

First off, LetsEncrypt will need to listen on port 80 and port 443 of your WAN (public-facing) interface so that it can validate your ownership of the domains. So configure your firewall’s port forwarding to redirect port 80 and port 443 to ports 180 and 1443 respectively on 172.20.0.10.

We’re going to use a Docker from the Unraid Community Applications docker. But before we do, we need to enabled user defined networks in our Docker settings.

  1. In Unraid, go to Settings->Docker.
  2. Disable docker so you can make changes: set Enable Docker to No
  3. Set Preserve user defined networks to Yes
  4. Re-enable Docker
  5. Open the Unraid console or SSH in.
  6. Create a new Docker network by executing docker network --subnet 172.20.0.0/24 create sslproxy

Now we’re ready to install the LetsEncrypt container!

  1. In Community Applications, search for LetsEncrypt and install the container from linuxserver
  2. Set the Network Type to Custom: ssl proxy
  3. Set the Fixed IP address to 172.20.0.10
  4. Make sure Privileged is set to On
  5. Set the http port to 180 and the https port to 1443 (or whatever works for you)
  6. Supply an email
  7. Enter your domain name, ie somedomain.gg
  8. Enter your subdomains: chat,bridge,voice (and any others you want to encrypt)
  9. Optional: set Only Subdomains to false, if you want the root domain to also have a cert!

The rest of the options should be fine as-is.
If you do NOT have a domain, but use a dynamic dns service, you can still mange but might be limited to a single domain. Make sure your Only Subdomains is set to True, otherwise your install will fail as LetsEncrypt will expect you have be running on your dyndns services web server! The following steps will also require you to do some nginx subdirectory redirection instead of domain proxying, so that’s a task for somewhat more advanced users.

Once you’ve created the docker instance, review the log. It might take a minute or two to generate the certificates. Let it finished and make sure there are no errors. It should say Server ready at the end if all goes well!

Try browsing to your newly encrypted page via https://somedomain.gg (your domain) and make sure all looks right. You should see a letsencrypt landing page for now.

Matrix
A Matrix container is available from avhost in Community Applications.

  1. In Community Applications, search for Matrix and install the container from avhost
  2. Set the Network Type to Custom: ssl proxy
  3. Set the Fixed IP address to 172.20.0.30
  4. Set the Server Name to bridge.somedomain.gg (your domain)
  5. The rest of the settings should be fine, and I suggest not changing the ports if you can get away with it. Create the container and run it.

Now we need to edit our Matrix config.

  1. Edit /mnt/user/appdata/matrix/homeserver.yaml
  2. Change server_name: "bridge.somedomain.gg"
  3. Change public_baseurl: https://bridge.somedomain.gg/"
  4. Under listeners: and - port: 8008 change bind_address: ['0.0.0.0']
  5. Change enable_registration: true
  6. Change registration_shared_secret: xxxx to some random value. It doesn’t matter what it is, just don’t use the one from the default config!

There are a ton of other settings you can play with, but I’d wait until after it working to get too fancy!

Now we need to setup the LetsEncrypt proxy to route requests to bridge.somedomain.gg to this container. We want to setup a redirection of domains that start with bridge.* to the IP of the container named matrix, and the port we have it listening on (8008).

  1. Create a file /mnt/user/appdata/letsencrypt/nginx/proxy-confs/matrix.subdomain.conf
  2. Give it the contents found below
  3. Restart your LetsEncrypt container
  4. Make sure it works by browsing to https://bridge.somedomain.gg/ and ensure that you can see the Matrix It works! page.

matrix.subdomain.conf:

server {
       listen 443 ssl;
       server_name bridge.*;
       include /config/nginx/ssl.conf;
       client_max_body_size 0;

       location / {
               include /config/nginx/proxy.conf;
               resolver 127.0.0.11 valid=30s;
               set $upstream_app matrix;
               set $upstream_port 8008;
               set $upstream_proto http;
               proxy_pass $upstream_proto://$upstream_app:$upstream_port;
       }
}

Riot Chat
Riot Chat servers as we web front-end chat interface. There’s also a great mobile app called RiotIM. For the web interface, there’s an Community Applications image for that!

  1. Before we start, we need to manually create the config path and pull in the default config. So open a console/SSH to your server.
  2. Create the config path by executing mkdir -p /mnt/user/appdata/riot-web/config
  3. Download the default config by executing wget -O /mnt/user/appdata/riot-web/config/config.json https://raw.githubusercontent.com/vector-im/riot-web/develop/config.sample.json (NOTE: This is a different URL than the one suggested in the Docker!)
  4. In Community Applications, search for riot web and install the container from vectorim. Watch you, there are two – use the one with the fancy icon, which doesn’t end with an asterisk (*)!
  5. Set the Network Type to Custom: ssl proxy
  6. Set the Fixed IP address to 172.20.0.20
  7. The rest of the settings should be fine. Create the container and run it.

Now lets edit our Riot config. It’s a JSON file, so make sure you respect JSON syntax

  1. Edit /mnt/user/appdata/riot-web/config/config.json
  2. Change "base_url": "https://bridge.somedomain.gg",
  3. Change "server_name": "somedomain.gg",
  4. Under the "Jitsi:" subsection near the bottom, change "preferredDomain": "voice.somedomain.gg"

Next we need to setup the LetsEncrypt nginx redirection.

  1. Create a file /mnt/user/appdata/letsencrypt/nginx/proxy-confs/riot-web.subdomain.conf
  2. Give it the contents found below
  3. Restart your LetsEncrypt container
  4. Make sure it works by browsing to https://chat.somedomain.gg/ and ensure that you can see the RiotIM Signup page.

riot-web.subdomain.conf:

server {
       listen 443 ssl;
       server_name chat.*;
       include /config/nginx/ssl.conf;
       client_max_body_size 0;

       location / {
               include /config/nginx/proxy.conf;
               resolver 127.0.0.11 valid=30s;
               set $upstream_app riot-web;
               set $upstream_port 8075;
               set $upstream_proto http;
               proxy_pass $upstream_proto://$upstream_app:$upstream_port;
       }
 }                      

Now lets create our first account!

  1. From the welcome page, click Create Account
  2. If the prior config was correct, Advanced should already be selected and it should say something like Create your Matrix account on somedomain.gg. If the Free option is set, then your RiotChat web client is using the public matrix.org service instead of your private instance! Make sure your base_url setting in your config.json is correct. Or just click Advanced, and enter https://bridge.somedomain.gg in the Other Servers: Enter your custom homeserver URL box.
  3. Set your username and password
  4. Setup encryption by following the prompts (or skip if you don’t care). This may require that you whitelist any browser script blockers that you have running.

Done! You now have a privately hosted Discord-alternative! Lets add some voice and video chat so we can stop using Zoom :stuck_out_tongue:

Jitsi
Ok, this part doesn’t have a solid Docker image in the Community Application store, so there’s a few more steps involved. We’re gonna need to clone their docker setup, which uses docker-compose. We’re also going to install the Etherpad module, which will let you add shared documents for everyone to edit in your video conferences!

  1. Open a console/SSH to your server
  2. Install docker-compose by executing curl -L "https://github.com/docker/compose/releases/download/1.25.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
  3. Make it executable: chmod u+x /usr/local/bin/docker-compose
  4. Move to your appdata folder : cd /mnt/user/appdata
  5. Clone the docker-jitsi-meet repo: git clone https://github.com/jitsi/docker-jitsi-meet
  6. Navigate to the docker-jitsi-meet path: cd docker-jitsi-meet
  7. Create an install environment: cp env.example .env
  8. Populate some random secrets in your environment: ./gen-passwords.sh
  9. Edit the install environment (I’m using nano, but edit however you want): nano .env
  10. Change CONFIG=/mnt//mnt/user/appdata/jitsi-meet/
  11. Set TZ to your timezome, ie TZ=America/Denver
  12. Change PUBLIC_URL=https://video.somedomain.gg
  13. Change DOCKER_HOST_ADDRESS=192.168.0.1 or whatever the LAN address of your Unraid server is
  14. Create and start the containers: docker-compose -p jitsi-meet -f docker-compose.yml -f etherpad.yml up
  15. This will create 4 Jitsi dockers, which you can see in your Unraid Docker tab. The instances will be running in the foreground, but press Ctrl+c to stop them, then just restart them from the Unraid web UI. While there, take note of the jitsi-meet_web_1 ports, which should be 8000 and 8443. If you got any errors, it’s likely a port conflict somewhere, so find the corresponding setting in your .env file and adjust as needed, reflecting any relevant changes in the next step.
  16. We also need another port forward rule in our firewall for the audio/voice service. Forward UDP port 10000 to your Unraid IP.

Next we need to setup the LetsEncrypt nginx redirection.

  1. Create a file /mnt/user/appdata/letsencrypt/nginx/proxy-confs/jitsi.subdomain.conf
  2. Give it the contents found below, but be sure to set the $upstream_app to the LAN IP of you Unraid server! The docker-compose tool may use different names, so we don’t want to rely on that.
  3. Restart your LetsEncrypt container
  4. Make sure it works by browsing to https://voice.somedomain.gg/ and ensure that you can see the Jitsi welcome screen where you can start a conference! Give it a go, if you like.

jitsi.subdomain.conf:

server {
       listen 443 ssl;
       server_name voice.*;
       include /config/nginx/ssl.conf;
       client_max_body_size 0;

       location / {
               include /config/nginx/proxy.conf;
               resolver 127.0.0.11 valid=30s;
               set $upstream_app 192.168.0.1;  <----- CHANGE THIS!!!!!!
               set $upstream_port 8000;
               set $upstream_proto http;
               proxy_pass $upstream_proto://$upstream_app:$upstream_port;
       }
}

Now find a friend and get them to register a Riot account on your server at https://chat.somedomain.gg (or use the mobile app and connect to the custom host). Get in a chat room together, then click the Video icon next to the text input box and make sure it works.

That is, hope this helps! Enjoy!

2 Likes