Skip to content
View in the app

A better way to browse. Learn more.

Unraid

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

[GUIDE] Matrix-Synapse w/ postgres DB (chat server) + Element (web client) + Coturn (voice)

Featured Replies

@dave234ee From a bit of quick googling it sounds like your database was either corrupted or deleted while in use. Are you able to restore from backup?

  • 1 month later...
  • Replies 78
  • Views 89k
  • Created
  • Last Reply

Top Posters In This Topic

Most Popular Posts

  • Fixed it, it's always the simplest things. I had a trailing / at the end of the home server URL in the compose file. Removed that and it starts fine.

  • GeekyGecko
    GeekyGecko

    Hi @strauberry, I seem to remember having a similar network issue and for me the magic solution was this setting in opnsense. Do you have something similar in pfsense and is it checked?  

  • For anyone looking for a guide on how I did this, here it is.   Login to pgAdmin4. On the left expand Server > Matrix > Databases, then right click Databases then go Create > Databa

Posted Images

When I try to create the admin user this is the error I get:

 

$ register_new_matrix_user -c /data/homeserver.yaml http://0.0.0.0:8008
New user localpart [matrix]: admin
Password: 
Confirm password: 
Make admin [no]: y
Traceback (most recent call last):
  File "/matrix/venv/lib/python3.11/site-packages/urllib3/connection.py", line 198, in _new_conn
    sock = connection.create_connection(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/matrix/venv/lib/python3.11/site-packages/urllib3/util/connection.py", line 85, in create_connection
    raise err
  File "/matrix/venv/lib/python3.11/site-packages/urllib3/util/connection.py", line 73, in create_connection
    sock.connect(sa)
ConnectionRefusedError: [Errno 111] Connection refused

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/matrix/venv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 793, in urlopen
    response = self._make_request(
               ^^^^^^^^^^^^^^^^^^^
  File "/matrix/venv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 496, in _make_request
    conn.request(
  File "/matrix/venv/lib/python3.11/site-packages/urllib3/connection.py", line 400, in request
    self.endheaders()
  File "/usr/lib/python3.11/http/client.py", line 1298, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/usr/lib/python3.11/http/client.py", line 1058, in _send_output
    self.send(msg)
  File "/usr/lib/python3.11/http/client.py", line 996, in send
    self.connect()
  File "/matrix/venv/lib/python3.11/site-packages/urllib3/connection.py", line 238, in connect
    self.sock = self._new_conn()
                ^^^^^^^^^^^^^^^^
  File "/matrix/venv/lib/python3.11/site-packages/urllib3/connection.py", line 213, in _new_conn
    raise NewConnectionError(
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0x14590391e010>: Failed to establish a new connection: [Errno 111] Connection refused

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/matrix/venv/lib/python3.11/site-packages/requests/adapters.py", line 589, in send
    resp = conn.urlopen(
           ^^^^^^^^^^^^^
  File "/matrix/venv/lib/python3.11/site-packages/urllib3/connectionpool.py", line 847, in urlopen
    retries = retries.increment(
              ^^^^^^^^^^^^^^^^^^
  File "/matrix/venv/lib/python3.11/site-packages/urllib3/util/retry.py", line 515, in increment
    raise MaxRetryError(_pool, url, reason) from reason  # type: ignore[arg-type]
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='0.0.0.0', port=8008): Max retries exceeded with url: /_synapse/admin/v1/register (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x14590391e010>: Failed to establish a new connection: [Errno 111] Connection refused'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/matrix/venv/bin/register_new_matrix_user", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/matrix/venv/lib/python3.11/site-packages/synapse/_scripts/register_new_matrix_user.py", line 272, in main
    register_new_user(
  File "/matrix/venv/lib/python3.11/site-packages/synapse/_scripts/register_new_matrix_user.py", line 156, in register_new_user
    request_registration(
  File "/matrix/venv/lib/python3.11/site-packages/synapse/_scripts/register_new_matrix_user.py", line 59, in request_registration
    r = requests.get(url)
        ^^^^^^^^^^^^^^^^^
  File "/matrix/venv/lib/python3.11/site-packages/requests/api.py", line 73, in get
    return request("get", url, params=params, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/matrix/venv/lib/python3.11/site-packages/requests/api.py", line 59, in request
    return session.request(method=method, url=url, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/matrix/venv/lib/python3.11/site-packages/requests/sessions.py", line 589, in request
    resp = self.send(prep, **send_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/matrix/venv/lib/python3.11/site-packages/requests/sessions.py", line 703, in send
    r = adapter.send(request, **kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/matrix/venv/lib/python3.11/site-packages/requests/adapters.py", line 622, in send
    raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='0.0.0.0', port=8008): Max retries exceeded with url: /_synapse/admin/v1/register (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x14590391e010>: Failed to establish a new connection: [Errno 111] Connection refused'))

 

I can't access the web UI at http://unraidip:8008/ but I can't figure out why. Could that be the reason for the error?

  • 1 month later...

Hello,

Im quite new to unraid and self-hosting, but is it possible to use cloudflare tunnels to get messages and audio and video calls to work? If this is possible, do you know of a good resource that would help me get this done since i have not found any guide that is using unraid and coudflare and has set up messages and audio/video calls?

  • 4 weeks later...

Update:

I used a Ubuntu VM and installed docker on it and all the matrix stuff. I ended up using dendrite since i had some issues with the synapse deployment. For the TURN, i have created cloudflare calls turn credentials and added them to .yaml file and it is now working fine, messages, audio and video calls.

Links that were useful for my situation:
Deployment of Matrix server: https://www.youtube.com/watch?v=TFDFR6EBG3k
TURN cloudflare: https://developers.cloudflare.com/api/operations/calls-turn-key-create , https://developers.cloudflare.com/calls/turn/generate-credentials/#create-a-turn-key
Add stickers to server: https://www.youtube.com/watch?v=Yz3H6KJTEI0

In case there are any problems with the deployment, please check the folder structure, make sure to use ../ when it is needed, i know for stickers i needed to change web/packs to ../web/packs in the sticker-import since i only used that.

 

 

Edited by pera_perkan

  • 1 month later...

I was scrolling through the forum & came back to this, things have changed a lot over the years but for anyone interested the reverse proxy settings has been updated: https://element-hq.github.io/synapse/latest/reverse_proxy.html

 

For the Nginx proxy manager, the /.well-known is no longer used & substituted with:

Quote

/_matrix

/_synapse/client

These 2 entries will do.

  • 3 weeks later...
On 8/21/2024 at 7:47 AM, pera_perkan said:

Update:

I used a Ubuntu VM and installed docker on it and all the matrix stuff. I ended up using dendrite since i had some issues with the synapse deployment. For the TURN, i have created cloudflare calls turn credentials and added them to .yaml file and it is now working fine, messages, audio and video calls.

Links that were useful for my situation:
Deployment of Matrix server: https://www.youtube.com/watch?v=TFDFR6EBG3k
TURN cloudflare: https://developers.cloudflare.com/api/operations/calls-turn-key-create , https://developers.cloudflare.com/calls/turn/generate-credentials/#create-a-turn-key
Add stickers to server: https://www.youtube.com/watch?v=Yz3H6KJTEI0

In case there are any problems with the deployment, please check the folder structure, make sure to use ../ when it is needed, i know for stickers i needed to change web/packs to ../web/packs in the sticker-import since i only used that.

 

 

Thank you for providing that as I am looking into doing the same thing.  Would you be able to provide additional information/steps as to how you implemented the turn service using cloudflare?  For some reason I am unable to successfully get it working.  Thanks in advance!

  • 3 weeks later...

Thanks for the guide, i managed to get it working within a few hours.

Has anyone considered or managed to install custom bots available, for example this reminder bot? https://github.com/maubot/reminder

Hi friends,

 

Has anyone tried installing Matrix on Unraid using this github project?
https://github.com/spantaleev/matrix-docker-ansible-deploy

 

From what I understand, it should make the installation process easier and it also allows for easy installation of the various bridges and bots.

If I had the necessary knowledge, I would try to install it on Unraid myself, but unfortunately I don't know how to start installing it.

If someone can guide me, I'm willing to be a guinea pig for everyone else 🙏 :)

Edited by mjeshurun

You just need those three things templates (put them in /boot/config/plugins/dockerMan/templates-user/ :

my-redis.xml

my-PostgreSQL.xml

my-Matrix-Synapse.xml

 

Redis and PostgreSQL should start before Matrix.

 

The configuration is the tricky part and is what most users struggle with but the creator from this thread did a great job with the write up.

 

Just a word of caution running a Matrix server... you may need lots of space on your server (I mean a lot of space) if you join big chat rooms.

I wouldn't recommend setting up a server just for you and a hand full of friends, granted I don't know what you are doing with your instance.

9 hours ago, ich777 said:

You just need those three things templates (put them in /boot/config/plugins/dockerMan/templates-user/ :

my-redis.xml 1.41 kB · 0 downloads

my-PostgreSQL.xml 2.71 kB · 0 downloads

my-Matrix-Synapse.xml 2.57 kB · 0 downloads

 

Redis and PostgreSQL should start before Matrix.

 

The configuration is the tricky part and is what most users struggle with but the creator from this thread did a great job with the write up.

 

Just a word of caution running a Matrix server... you may need lots of space on your server (I mean a lot of space) if you join big chat rooms.

I wouldn't recommend setting up a server just for you and a hand full of friends, granted I don't know what you are doing with your instance.

Hi @ich777,
Is your comment a reply to my question?
If it is, how would I go about running the ansible playbooks that install and run the various server components, bridges and bots, they mention on the github page?
Do I need to install ansible somehow for the playbooks commands to work?
 

@mjeshurun sorry I don‘t use Ansible nor do I have multiple servs, I thought this was just a question how to get Matrix running on Unraid.

  • 3 weeks later...
  • 1 month later...

Hey Everbody,

hopefully the Post is still watched. I had in the past allready an Matrix docker running on a System. So everthing worked fine. Now I need it again on a different Server and had only trouble to get it working. Basically I think it is an permission topic because i get several times:

Cannot create pid file: /var/run/turnserver.pid: Permission denied
PermissionError: [Errno 13] Permission denied: '/homeserver.log'

 

So i did allready the fix of https://github.com/A75G/docker-templates/issues/77. for the homeserver.log.  But i seems that there is still an permission error and I'm not completely sure what is the right solution for it. 

 

Maybe someone can help?

Thanks!

  • 1 month later...
On 4/28/2023 at 4:35 PM, masterdot said:

Maybe someone can help me a bit?

 

I have everything installed now, but the server does start and stop. This here is the only output I get:

Setting ownership on /data to 99:100
Config file '/data/homeserver.yaml' already exists. Generating any missing config files.
Setting ownership on /data to 99:100
Config file '/data/homeserver.yaml' already exists. Generating any missing config files.
Setting ownership on /data to 99:100
Config file '/data/homeserver.yaml' already exists. Generating any missing config files.
Setting ownership on /data to 99:100
Config file '/data/homeserver.yaml' already exists. Generating any missing config files.

** Press ANY KEY to close this window ** 

 

Nothing else.

 

Did you ever get it working? I've facing the same issue.

  • 7 months later...

Hello everyone,

I'm contacting you because I'm reaching my limits with the setup of Element Call (LiveKit backend) for my Matrix Synapse server on Unraid. Despite days of troubleshooting, every video call fails."Waiting for media..."hang. Call signaling via the JWT service works, but the media stream (audio/video) is not established.

I have already tried many things: First with coturn (failed due to similar network/IP detection problems in bridge mode), now with the recommendedLiveKit + JWT-Service. I hope someone has experience with this configuration on Unraid.

My system:

  • Unraid Version: 7.1.4

  • Server IP (Unraid Host): UNRAID_IP (z.B. 192.168.178.95)

  • Docker network:PrimaryIPVLAN(br0) is configured. Docker Standard Bridge (172.17.0.0/16) and others are also active.

  • Matrix Synapse:Docker container (Matrix-Synapse), config under /mnt/user/appdata/synapse/homeserver.yaml, accessible via https://MAIN_DOMAIN. homeserver.yaml has been extended with experimental features (msc3266, msc4222, msc4140) and adjusted rc_message/rc_delayed_event_mgmt limits for MatrixRTC.

  • Reverse Proxy:Nginx Proxy Manager (NPM, official container jc21/nginx-proxy-manager), manages SSL (Let's Encrypt) for all domains.

  • Router:FRITZ!Box (ROUTER_IP). Port forwarding for LiveKit (TCP 7880, 7881; UDP 65246-65500) is configured for the UNRAID_IP.Important:A test with"Exposed Host"has the problemnotFixed – the router firewall does not seem to be the cause.

  • DDNS:MAIN_DOMAIN (via DDNS provider) for Synapse + RTC_DOMAIN (via DuckDNS container) for the LiveKit backend. Both correctly point to my dynamic public IP (currently PUBLIC_IP).

  • Clients:Tested with the latestElement Desktop App (Windows) and Element Web (Chrome)Clients have been reloaded multiple times (including cache clearing). Microphone/camera permissions have been granted.

Current LiveKit/JWT configuration (Plan M - Minimal Host Mode):

Since all attempts inBridge-Modus(wrong nodeIP despite STUN success, unexplained UDP port conflicts address already in use, ignoring DETECT_EXTERNAL_IP / external-ip=hostname in config) and withMacVLAN/IPVLAN(Network creation error Pool overlaps / device busy) failed, the LiveKit containers run as a last attempt in theHost-Modus:

  • docker-compose.yaml (/mnt/user/appdata/element-call-backend/docker-compose.yaml):
    YAML
    version: '3.7' # Ignored, but FYI
    services:
      matrix-element-call-jwt:
        image: ghcr.io/element-hq/lk-jwt-service:latest
        # ... container_name, hostname ...
        environment:
          - LK_JWT_PORT=7080 # Host-Port 7080
          - LIVEKIT_URL=https://RTC_DOMAIN/livekit/sfu
          - LIVEKIT_KEY=LIVEKIT_KEY
          - LIVEKIT_SECRET=LIVEKIT_SECRET
          - LIVEKIT_FULL_ACCESS_HOMESERVERS=HAUPT_DOMAIN
        network_mode: host
        restart: unless-stopped
      matrix-element-call-livekit:
        image: livekit/livekit-server:latest
        # ... container_name, hostname ...
        command: --config /etc/livekit.yaml
        network_mode: host
        restart: unless-stopped
        volumes:
          - ./livekit.yaml:/etc/livekit.yaml:ro

  • livekit.yaml(/mnt/user/appdata/element-call-backend/livekit.yaml): (Minimal config for host mode)
    YAML
    port: 7880
    bind_addresses: ["0.0.0.0"] # Should be ignored in host mode
    rtc:
      tcp_port: 7881
      port_range_start: 65246 # Area already shared in FritzBox
      port_range_end: 65500
      use_external_ip: true # Attempt automatic detection
    logging:
      level: debug # Debug level enabled
    turn:
      enabled: false
    keys:
      LIVEKIT_KEY: "LIVEKIT_SECRET"

  • LiveKit Logs (Start): The logs show that LiveKit detects and appears to be using the correct public IP:
    starting LiveKit server ... "nodeIP": "OEFFENTLICHE_IP", ... "rtc.portICERange": [65246, 65500]

NPM configuration:

  • Proxy Host RTC_DOMAIN:

  • SSL: Let's Encrypt active & valid (status "Online" after fixing UNRECOGNIZED_NAME_ALERT and LEGACY_RENEGOTIATION errors), Force SSL, HSTS, HTTP/2 on.Websockets Support an.

  • Advanced Tab (Targets host IPs):
    Nginx
    # JWT Service
    location ^~ /livekit/jwt/ { /* ... Header ... */ proxy_pass http://UNRAID_IP:7080/; }
    # LiveKit SFU
    location ^~ /livekit/sfu/ { /* ... Header inkl. Upgrade/Connection ... */ proxy_pass http://UNRAID_IP:7880/; }

  • Proxy Host HAUPT_DOMAIN:

  • Advanced Tab (Well-Known):
    Nginx
    location /.well-known/matrix/client { /* ... Header ... */ return 200 '{"m.homeserver": {"base_url": "https://HAUPT_DOMAIN"}, /*...*/ "org.matrix.msc4143.rtc_foci": [{"type": "livekit", "livekit_service_url": "https://RTC_DOMAIN/livekit/jwt"}]}'; }

  • curl test on .well-known is successful.

The problem:

Despite this configuration (server detectsapparentlycorrect external IP in the log, ports open, NPM forwards, clients up to date) every call remains with"Waiting for media..."hang. TheDebug-Logs von LiveKitshow during the call attemptno obvious ICE errors, binding errors or UDP problems– only the initial warnings during IP validation ("could not validate external IP", "error reading from UDP socket: use of closed network connection"), but the server still starts with the correct nodeIP.

My guess:

Although the nodeIP looks correct in the startup log, LiveKit in host mode under Unraid/IPVLAN may announcefaulty ICE candidates(e.g. still the internal IP UNRAID_IP or a Docker IP for the UDP connection), or the Unraid host blocks/drops the incoming UDP packets on ports 65246-65500,beforethey reach the LiveKit process (despite host mode).

My question:

Has anyoneLiveKit successfully runs in host mode on Unraid (specifically with IPVLAN as primary Docker network)Is it running? Are there any known kernel parameters (sysctl), firewall rules (iptables on the host), or Docker/IPVLAN settings that need to be adjusted to ensure that UDP packets are correctly forwarded for media relaying in host mode? Why does the media connection fail even though the starting node IP is correct and no errors are visible in the debug logs during the call?

I'm really desperate and grateful for any advice!

Thank you in advance!


  • 3 months later...

this is a nice guide. I'm still ironing out some kinks but have a semai decent setup here
https://github.com/bmartino1/matrix-textvoicevideo

where you git clone

cd /mnt/user/appdata
git clone https://github.com/bmartino1/matrix-textvoicevideo.git

Run the automated script...
./setup.sh --domain chat.yourdomain.com

*I used a afraiddns sub domain name
https://freedns.afraid.org/

then setup docker compose point to your github download folder.

docker compose example:
image.png

editing the stack AFTER THE SCRIPT RUN!
image.png

proff of concept:
image.png

using:

docker exec -it matrix-synapse \
register_new_matrix_user \
-k "synapse-homeserver.yaml config shared registrationkey" \
http://localhost:8008

to make users...

By al means its not perfect.
image.png

*I have adatinal thigns I don to my compos files...

But this should help alevate concerns/ questions on making a turn key run and done...
while voice and viode work i'm having a hard time geting them to function.

I can then use the element web app for phone / browser...
https://element.io/en/download

given alot of users looking for discord alternatives...

I've stumbled into this post as I'm making my Maxtrix Synapse server, manually and adding pieces, step by step with the help of Claude.

HestiaCP (its a web hosting tool) is my reverse proxy and auto renews certs
Matrix Synapse is configured (with Postgres)
Postgres container for Matrix only is configured
Coturn is configured, works with Matrix (Calls only)

When I tried to make a video room, got this error.

Error Code: MISSING_MATRIX_RTC_FOCUS.

I'm just trying to understand because this last part I'm stuck.
I added Livekit container (added a Reddis Server internally as well) Don't know if Reddis even matters

Matrix-Element-call

Matrix-Element-web

Any chance you can give a brief explanation for adding last two dockers above. I couldn't find them on the store, Just need to know where I can get the docker details so I can add it manually as a container if it's not on AppStore.

And once this is set, the Server is done yes?
Calls work, but Video Rooms do not for now.

The biggest headache in my opinion was making Federation work, and learning where to properly add the nginx reverse proxy settings.

The script is really well done, but I'm using it as reference as I build the pieces manually, also so I can understand how this whole stack works, in case I ever have to troubleshoot something.

Also, I created each one of these dockers with br0 and assigned an ip address internally. Not sure if that matters.

Edited by unraidrocks

I have finished updateing scripts notes configs and decided to go jitsi for video and voice.

https://github.com/bmartino1/matrix-textvoicevideo

I have tested this on mutiple sytems with a dns domain name.
I have tested both video and voice. complete self hosted.

to keep things simple I set coturn and jvb for jitsu video/voic connections to the host unraid lan ip.
image.png

and the rest in its own compose contorled docker network... see coments in line with code...
using docker nat form nginx bridge mode to router nat incoming 443 or 80 default http/https traffic though router NAT to talk to 60443 60080 for nginx RP ssl certs....

This leaves the livekit (organly i ran both cotrun and livkit as cotun is a TURN server and livekit also has a TURN server and the both conflcied as synapsoe is built to run wht cotrun but not the turn server withint livkit.

Since elemnt will fallback to meet.jitsi public domain i decdied to add the abilt to use a slef host version. soemthing that i have tested and can gurante a spin up...
data folder has example configs with in you can manual edit eh env and mathcc the data in it to teh needed items int eh configs to learn more about each docker setup and piece.
*This includes nginx RP forwading settings turn use and how... (See readme)

This is the best I can do to hlep facilate new user jumping in and to help some of my knownw friend gorups to quickly spin up a encrypted full functial matrix server.

Its really well done and written, lots of documentation.

I have an error when setting up server. Certbot fails, even with ports setup 60443 and 60080 mapped to 443 and 80.
Its not a big deal, I'm able to generate my own SSL certs can copy them over when the script is complete.
This is an example of the domain I'm using
matrix.domain.com

meet.matrix.domain.com

sudo bash setup.sh --domain matrix.domain.com --reset

Everything works fine. Only issue I continue to have is the Video Rooms and joining call. I still get the error:

Call is not supported
The server is not configured to work with Element Call. Please contact your server admin (Domain: matrix.domain.com, Error Code: MISSING_MATRIX_RTC_FOCUS).

I looked at my compose and opened all these ports on my server:
# WAN 443 \u2192 Unraid:60443 (nginx HTTPS)

# WAN 80 \u2192 Unraid:60080 (nginx HTTP / ACME)

# WAN 3478 \u2192 Unraid:3478 (coturn TURN/STUN)

# WAN 5349 \u2192 Unraid:5349 (coturn TURNS/TLS)

# WAN 10000 UDP \u2192 Unraid:10000 (jitsi-jvb WebRTC media)



I looked at the docker compose, even the status script, I don't see 10000 UDP port on any of the jitsi-jvb dockers.
I don't know if I'm missing something that on the synapse server yaml that prevents it from recognizing jitsi and the 10000 UDP port.
If you have a config files i can compare to, I am not sure if the Certbot failing causes script to not set all configurations.
I checked my ".env" file Jitsi sees my ip and server URL.
JVB_ADVERTISE_IPS
JITSI_PUBLIC_URL
JITSI_DOMAIN

Actually, now that I'm writing this,
JITSI_AUTH_DOMAIN="auth.meet.matrix.domain.com"

JITSI_INTERNAL_MUC_DOMAIN="internal-muc.meet.matrix.domain.com"

JITSI_MUC_DOMAIN="muc.meet.matrix.domain.com"


Do I need to create these additional A records that appear in .ENV file?


The other question, and ran into an issue, how do I run server local?
This is also to compare and for troubleshooting purposes, to have a matrix server internally, no outside clients. LAN testing.

# LAN-only / no internet / no TLS
sudo bash setup.sh --domain myserver.local --no-tls

When I setup this server to test, the only interface to connect to synapse was nginx and it points to 60443/60080.
I'm just confused on how to make the local server work.
If it takes over port 80 of host, then I believe Unraid will go down, because HTTP web UI to unraid already uses port 80.
Does local server still need an A Record that works internally to point to UNRAID:80 and UNRAID:443?
I'm only able to make domains work.



Any pointers or comparing configs would help with this setup.

Thanks again.


Also here's status script results:

/mnt/user/appdata/matrix-textvoicevideo# ./scripts/status.sh
=== Container Status ===
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
jitsi-jicofo jitsi/jicofo:stable "/init" jitsi-jicofo 44 minutes ago Up 44 minutes
jitsi-jvb jitsi/jvb:stable "/init" jitsi-jvb 44 minutes ago Up 44 minutes
jitsi-prosody jitsi/prosody:stable "/init" jitsi-prosody 44 minutes ago Up 44 minutes 5222/tcp, 5280/tcp
jitsi-web jitsi/web:stable "/init" jitsi-web 44 minutes ago Up 43 minutes 80/tcp, 443/tcp
matrix-coturn coturn/coturn:latest "docker-entrypoint.s…" coturn 44 minutes ago Up 44 minutes
matrix-element-web vectorim/element-web:latest "/docker-entrypoint.…" element-web 44 minutes ago Up 44 minutes (healthy) 8080/tcp
matrix-nginx nginx:alpine "/docker-entrypoint.…" nginx 44 minutes ago Up 38 minutes 0.0.0.0:60080->80/tcp, :::60080->80/tcp, 0.0.0.0:60443->443/tcp, :::60443->443/tcp
matrix-postgres postgres:16-alpine "docker-entrypoint.s…" postgres 44 minutes ago Up 44 minutes (healthy) 5432/tcp
matrix-synapse matrixdotorg/synapse:latest "/start.py" synapse 44 minutes ago Up 43 minutes (healthy) 8008/tcp, 8448/tcp, 19090/tcp
matrix-valkey valkey/valkey:latest "docker-entrypoint.s…" valkey 44 minutes ago Up 44 minutes (healthy) 6379/tcp

=== Internal Services ===
✓ PostgreSQL (matrix-postgres)
✓ Valkey (matrix-valkey)
✓ Synapse API
✓ Element Web
✓ Nginx (HTTP)
✓ Jitsi Web

=== External Endpoints ===
✓ Matrix HTTPS
✓ Well-Known Client
✓ Well-Known Server
✓ Jitsi Video

=== Coturn TURN Server ===
Install netcat (nc) to test Coturn UDP reachability
✓ Coturn container running

=== Resource Usage ===
NAME CPU % MEM USAGE / LIMIT
matrix-nginx 0.00% 46.15MiB / 125.7GiB
jitsi-web 0.00% 27.3MiB / 125.7GiB
jitsi-jvb 0.15% 249.4MiB / 125.7GiB
matrix-synapse 0.13% 186.2MiB / 125.7GiB
jitsi-jicofo 0.11% 210.2MiB / 125.7GiB
jitsi-prosody 0.08% 58.47MiB / 125.7GiB
matrix-postgres 0.00% 77.95MiB / 125.7GiB
matrix-element-web 0.00% 25.38MiB / 125.7GiB
matrix-valkey 0.14% 18.84MiB / 125.7GiB
matrix-coturn 0.10% 22.9MiB / 125.7GiB
matrix-awt 0.00% 12.01MiB / 125.7GiB

=== Configuration Summary ===
Domain: matrix.domain.com
Public URL: https://matrix.domain.com
Jitsi URL: https://meet.domain.com
External IP: 67.x.x.x
Internal IP: 172.x.x.x
Data Dir: /mnt/user/appdata/matrix-textvoicevideo/data
TLS: false

Edited by unraidrocks

I may need to run something to make sure nginx is not running and use the same ports as nginx

Coturn and jitsu ?jvb? Are set to docker host mode. That is the 1000 port.

Certbot is more for setup tsl and use a self signed cert. See the certbot-int (lator I need to update it) as it is a docker run issue with nginxrinning and needing the router port 80 for acme/yls registration...) tested with a cloud flared domain and updated the script, I see I didn't update the GitHub with the correction to run certbot. As certbot need to run docker. Ridge and match same ports as nginx...)

DNS needs 2 DNS names to the same cert.

If my domain name is unraid.com

I will also need meet.unraid.com

That is what cause slef host jitsu from make videos rooms.

I'm away from PC today and will take a close look at the post and things in GitHub tomorrow.

There are a lot of moving parts and I tried to share a lot of secure by default setup. By no means is this GitHub stack complete but it's enough to get people started.

I went jitsu due to changes with synapse and new intergration as the config is set to use the server it self and not the public meet.jitsu for a room.

I'm also working with 3 other groups that require a little bit of other configuration editing and ATM can only reference the documentation for matrix synapse and element.

On 2/20/2026 at 3:27 PM, unraidrocks said:

Its really well done and written, lots of documentation.

I have an error when setting up server. Certbot fails, even with ports setup 60443 and 60080 mapped to 443 and 80.
Its not a big deal, I'm able to generate my own SSL certs can copy them over when the script is complete.
This is an example of the domain I'm using
matrix.domain.com

meet.matrix.domain.com

sudo bash setup.sh --domain matrix.domain.com --reset

Everything works fine. Only issue I continue to have is the Video Rooms and joining call. I still get the error:

Call is not supported
The server is not configured to work with Element Call. Please contact your server admin (Domain: matrix.domain.com, Error Code: MISSING_MATRIX_RTC_FOCUS).

I looked at my compose and opened all these ports on my server:
# WAN 443 \u2192 Unraid:60443 (nginx HTTPS)

# WAN 80 \u2192 Unraid:60080 (nginx HTTP / ACME)

# WAN 3478 \u2192 Unraid:3478 (coturn TURN/STUN)

# WAN 5349 \u2192 Unraid:5349 (coturn TURNS/TLS)

# WAN 10000 UDP \u2192 Unraid:10000 (jitsi-jvb WebRTC media)



I looked at the docker compose, even the status script, I don't see 10000 UDP port on any of the jitsi-jvb dockers.
I don't know if I'm missing something that on the synapse server yaml that prevents it from recognizing jitsi and the 10000 UDP port.
If you have a config files i can compare to, I am not sure if the Certbot failing causes script to not set all configurations.
I checked my ".env" file Jitsi sees my ip and server URL.
JVB_ADVERTISE_IPS
JITSI_PUBLIC_URL
JITSI_DOMAIN

Actually, now that I'm writing this,
JITSI_AUTH_DOMAIN="auth.meet.matrix.domain.com"

JITSI_INTERNAL_MUC_DOMAIN="internal-muc.meet.matrix.domain.com"

JITSI_MUC_DOMAIN="muc.meet.matrix.domain.com"


Do I need to create these additional A records that appear in .ENV file?


The other question, and ran into an issue, how do I run server local?
This is also to compare and for troubleshooting purposes, to have a matrix server internally, no outside clients. LAN testing.

# LAN-only / no internet / no TLS
sudo bash setup.sh --domain myserver.local --no-tls

When I setup this server to test, the only interface to connect to synapse was nginx and it points to 60443/60080.
I'm just confused on how to make the local server work.
If it takes over port 80 of host, then I believe Unraid will go down, because HTTP web UI to unraid already uses port 80.
Does local server still need an A Record that works internally to point to UNRAID:80 and UNRAID:443?
I'm only able to make domains work.



Any pointers or comparing configs would help with this setup.

Thanks again.


Also here's status script results:

/mnt/user/appdata/matrix-textvoicevideo# ./scripts/status.sh
=== Container Status ===
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
jitsi-jicofo jitsi/jicofo:stable "/init" jitsi-jicofo 44 minutes ago Up 44 minutes
jitsi-jvb jitsi/jvb:stable "/init" jitsi-jvb 44 minutes ago Up 44 minutes
jitsi-prosody jitsi/prosody:stable "/init" jitsi-prosody 44 minutes ago Up 44 minutes 5222/tcp, 5280/tcp
jitsi-web jitsi/web:stable "/init" jitsi-web 44 minutes ago Up 43 minutes 80/tcp, 443/tcp
matrix-coturn coturn/coturn:latest "docker-entrypoint.s…" coturn 44 minutes ago Up 44 minutes
matrix-element-web vectorim/element-web:latest "/docker-entrypoint.…" element-web 44 minutes ago Up 44 minutes (healthy) 8080/tcp
matrix-nginx nginx:alpine "/docker-entrypoint.…" nginx 44 minutes ago Up 38 minutes 0.0.0.0:60080->80/tcp, :::60080->80/tcp, 0.0.0.0:60443->443/tcp, :::60443->443/tcp
matrix-postgres postgres:16-alpine "docker-entrypoint.s…" postgres 44 minutes ago Up 44 minutes (healthy) 5432/tcp
matrix-synapse matrixdotorg/synapse:latest "/start.py" synapse 44 minutes ago Up 43 minutes (healthy) 8008/tcp, 8448/tcp, 19090/tcp
matrix-valkey valkey/valkey:latest "docker-entrypoint.s…" valkey 44 minutes ago Up 44 minutes (healthy) 6379/tcp

=== Internal Services ===
✓ PostgreSQL (matrix-postgres)
✓ Valkey (matrix-valkey)
✓ Synapse API
✓ Element Web
✓ Nginx (HTTP)
✓ Jitsi Web

=== External Endpoints ===
✓ Matrix HTTPS
✓ Well-Known Client
✓ Well-Known Server
✓ Jitsi Video

=== Coturn TURN Server ===
Install netcat (nc) to test Coturn UDP reachability
✓ Coturn container running

=== Resource Usage ===
NAME CPU % MEM USAGE / LIMIT
matrix-nginx 0.00% 46.15MiB / 125.7GiB
jitsi-web 0.00% 27.3MiB / 125.7GiB
jitsi-jvb 0.15% 249.4MiB / 125.7GiB
matrix-synapse 0.13% 186.2MiB / 125.7GiB
jitsi-jicofo 0.11% 210.2MiB / 125.7GiB
jitsi-prosody 0.08% 58.47MiB / 125.7GiB
matrix-postgres 0.00% 77.95MiB / 125.7GiB
matrix-element-web 0.00% 25.38MiB / 125.7GiB
matrix-valkey 0.14% 18.84MiB / 125.7GiB
matrix-coturn 0.10% 22.9MiB / 125.7GiB
matrix-awt 0.00% 12.01MiB / 125.7GiB

=== Configuration Summary ===
Domain: matrix.domain.com
Public URL: https://matrix.domain.com
Jitsi URL: https://meet.domain.com
External IP: 67.x.x.x
Internal IP: 172.x.x.x
Data Dir: /mnt/user/appdata/matrix-textvoicevideo/data
TLS: false


I have recenly pushed and updated code. Per a earlier github issues regarding gui RPs such as NPM... I've added an adataionl flag for some config help edits...

So here is a Q/A as I can't type to save my life and use AI / web tools to assit in responses... and will not be able to provide suport for things outside of the stack intedned job. Mainly that I tried to use teh Gui RPs and alwys end up neededing to manual configure teh configs... this is why the nginx stack exisitng in my stack to begin with with the manual edited nginx config...

Q/A:

Q:
MISSING_MATRIX_RTC_FOCUS — this is the most important one to get right. The user is hitting the Element Call button, not the Jitsi widget. Element Call is a completely different calling system that needs matrix-rtc infrastructure this stack doesn't run. The fix is just confirming the three feature_*: false flags are in their config.json, and redirecting them to the correct way to start a Jitsi call (via the widget, not the native call button).


A:
So example:

root@BMM-Tower:/mnt/user/appdata/matrix-textvoicevideo/data/element-web/config# ls

config.json*

image.png

These need adjusted in the elemnet web config:

"features": {
  "feature_video_rooms": false,
  "feature_group_calls": false,
  "feature_element_call_video_rooms": false
}

With elemnt via the web borwser i disabled these so default should be false... This si to enforce a room / caht with 2 poeple only use cotrun. 3 or more use jitsi meet. see more documentation here:
https://docs.element.io/latest/element-server-suite-pro/advanced/

Recap: Element Call / Video Rooms — MISSING_MATRIX_RTC_FOCUS

This error is not a Jitsi or port problem. It is caused by Element Web trying to use Element Call (a newer WebRTC calling system built into Matrix itself), which requires a separate matrix-rtc service that is not part of this stack.

This stack uses Jitsi for video — which is a separate system that Element Web launches as a widget. Element Call and Jitsi are two different things.

Fix: Video rooms must be started through the Jitsi widget, not the native Element Call button. To disable the Element Call button entirely and prevent this confusion, make sure your element-web/config/config.json contains the updated element web config above..:

If you ran setup.sh, this is already written for you. If you see the error, double-check the file at:

data/element-web/config/config.json

To start a Jitsi video call: open a room → click the video camera widget icon → Add Jitsi widget. That is how video calling works with this stack.


Q:
DNS subdomains — they're worried about auth.meet.*, internal-muc.meet.* etc. Clear answer: those are internal XMPP identifiers, they never leave Docker, no DNS needed. Only two public records required.

A:


Exaplained in above post example and ont eh github readme...:

DNS needs 2 DNS names to the same cert.

If my domain name is unraid.com

I will also need meet.unraid.com

No. Those entries in .env (JITSI_AUTH_DOMAIN, JITSI_MUC_DOMAIN, JITSI_INTERNAL_MUC_DOMAIN) are internal XMPP domain names used by Jitsi's components to talk to each other inside Docker. They never leave the container network and do not need public DNS records.

You only need two public DNS A records, both pointing to the same public IP:

matrix.domain.com        A    YOUR.PUBLIC.IP
meet.matrix.domain.com   A    YOUR.PUBLIC.IP

That is it. The certificate covers both. Everything else is internal.


Q:

JVB UDP 10000 missing from docker ps — classic host-network confusion. The port isn't missing, it's just that host-networked containers don't show port mappings in docker ps. Gave them a ss -ulnp command to verify it's actually bound.


A:
Thought this was celarly exmplaind in teh github readme...
This is expected. jitsi-jvb uses network_mode: host — it binds directly to the host network interface rather than going through Docker's port mapping system. That is why no port mapping shows in docker ps.

UDP 10000 is open and listening on your Unraid host directly. You can verify with:

ss -ulnp | grep 10000

Your router just needs UDP 10000 forwarded to your Unraid IP (same IP, same port — no translation needed). Same applies to Coturn on 3478/5349.

You can learn some more here via my guide on unraid docker netwroks.. whcih also flowls the docker docs...
https://bmartino1.weebly.com/guide-dockernetworks.html


and the docker docs... Host was chosen due to issue with docker security and udp traffic to use turn/stun properly. Host allows access into the docker netowrk via the unraid ip and is port forward able to use over the wider internet... a RP in fornt in theory could re route the netowrk with port forwards are not needed for udb traffic though the RP... But due to muticast udp packets and the 2 dockers. cotrun and JVB. it is best (when runnign as docker) to set them to host mode for access into unriads network and capabilties loced due to docker netowrk security.

Q:

Certbot failure — confirmed their diagnosis is right (nginx holds 60080), pointed them to certbot-init.sh which handles the stop/start, and gave them the manual cert copy path for people using Cloudflare or their own certs.

A:

*this has been updated in the github now. setup, and teh admin script with certbot are fixed to re use nginx ports makein sure my stack nginx is down so ports are open to comeplte lets encrypt... docker compose TLS profile is also avilabe t=for run and renwal outsdie of the admin scripts..

The root cause is that nginx is already running and holding port 60080 when certbot tries to bind it. Certbot's standalone mode needs to own that port exclusively to serve the ACME challenge.

The fix is to stop nginx first, run certbot, then restart nginx. The updated certbot-init.sh script in this repo handles that automatically:

bash

# Stop nginx, obtain cert, restart nginx
./scripts/certbot-init.sh

If you already have your own SSL certs (e.g. from Cloudflare or your own CA), you can skip certbot entirely and copy them directly:

bash

mkdir -p data/nginx/certs/live/matrix.domain.com
cp your-fullchain.pem data/nginx/certs/live/matrix.domain.com/fullchain.pem
cp your-privkey.pem   data/nginx/certs/live/matrix.domain.com/privkey.pem
docker compose restart matrix-nginx matrix-coturn

Nginx and Coturn both read certs from that path.

LAN / --no-tls confusion — clarified that port 80 is never touched even in no-tls mode (nginx stays on 60080), explained hairpin NAT as Option A, and local DNS as Option B. This directly answers their confusion about Unraid going down.

A:
orginaly this was more lan side testing for me... and stayed for what was side testing / options latter due to nginx RPs adn certs issues for explination to other users...

What this does: is no nginx config 443 and cert generation... You may need the new added feature for --behind-proxy ...

--no-tls HTTP-only — skip all TLS/certbot entirely Use for: LAN/testing, or when an external proxy on a different machine handles TLS before reaching this host

*also recenlty updated in the github read me...
https://github.com/bmartino1/matrix-textvoicevideo?tab=readme-ov-file#tls-certificates-and-https

TLS Certificates and HTTPS

This stack supports three TLS modes. Choose based on your setup:

Mode

Flag

When to use

Self-managed

(default)

Nginx handles TLS directly. Certbot obtains a Let's Encrypt cert. Best for most setups.

Behind external proxy

--behind-proxy

Another proxy (NPM, Traefik, Caddy) sits in front of this stack and handles TLS. Nginx runs HTTP-only internally.

HTTP only

--no-tls

No TLS at all. Use for LAN-only, testing, or development.


Default Mode — Nginx Manages TLS

Internet → WAN:443 → Router NAT → Unraid:60443 → nginx (TLS termination) → services
Internet → WAN:80  → Router NAT → Unraid:60080 → nginx (ACME / redirect)

Nginx holds the TLS certificate and terminates HTTPS for all services. Certbot obtains and renews the certificate from Let's Encrypt.

See New added data:
https://github.com/bmartino1/matrix-textvoicevideo?tab=readme-ov-file#--behind-proxy-mode--external-reverse-proxy-handles-tls

So recap as
LAN / Local Server — --no-tls and port 80 on Unraid

You are right that --no-tls on Unraid cannot use port 80 — Unraid's web GUI owns it. The --no-tls mode still uses the same host ports 60080/60443 as the rest of the stack (set in docker-compose.yml). Nothing changes about port binding.

What changes with --no-tls is that nginx does not redirect HTTP to HTTPS and does not require cert files. The stack is just accessible over plain HTTP.

For LAN access you have two options:

Option A — Use your real domain but access it on the LAN: Your DNS A record points to your public IP. Access from inside your LAN goes out through your router and back in (hairpin NAT), or you add a local DNS override in your router/Pi-hole pointing matrix.domain.com to your Unraid LAN IP. The stack runs exactly the same — no changes needed.

Option B — Local-only hostname with --no-tls:

bash

sudo bash setup.sh --domain matrix.local --no-tls

Then add a local DNS entry (router, Pi-hole, /etc/hosts) pointing matrix.local to your Unraid IP. Access the UI at http://matrix.local:60080. No A record, no internet required. Note: federation with other Matrix servers won't work without HTTPS.

Future Guidelines. as Im just going over docs and doing what the docs say...

General Support Guidance

This stack has a lot of moving parts and the upstream projects each have their own documentation. For issues beyond basic setup, these are the best references:

This repo is a best-effort starting point

Edited by bmartino1
typo / data -forum hickup

I post here more due to a pre-existing guide...

This repo is a best-effort starting point ( to get you into something similar to a turn key)
https://github.com/bmartino1/matrix-textvoicevideo

its only job is to get a working stack running with sane defaults and some recommended security hardening. Custom configurations, federation debugging, and integrations with other services will require referencing the upstream docs:

Similar I won't be able to supply much support or help beyond what I personally tested and run as there are a lot of moving parts this repo runs 10 dockers and manges the configuration at a min to just get working... configuration of each service docker and its configuration ultimate rely on you. What you want it to do and how you want to interact with it...

Edited by bmartino1
typo

Thank you so much for your hard work and effort.

I was experimenting with Alpine linux, and decided to try the docker compose stack on this Virtual machine I spun up.

I had to install this in the same path as Unraid, just because this is what this setup is designed for.

Install worked.
It installed everything.

I had to add a few things, just because I manually put SSL certs for both domains.

I did this install without the SSL/TSL certificates (certbot failed) because I already have the certs saved/created by another web app.
I just copied over private and fullchain keys.

Also, because I did this manually, and in case anyone runs this this issue, NGINX needs the path of the meet.matrix.domain.com certs or else, Jitsi addon won't display inside Element or in web browser.

Also I needed to add these lines to nginx for meet.matrix.domain.com
Only after adding this, UDP 10000 hits worked (Confirmed)
Meetings to jitsi meet.matrix.domain.com are public. (Anyone can make a meeting)

# --- ADD THESE ---

proxy_http_version 1.1;

proxy_set_header Upgrade $http_upgrade;

proxy_set_header Connection "upgrade";

proxy_read_timeout 3600s;

proxy_send_timeout 3600s;

# ------------------



And I finally understand how Jitsi works.
The owner of the room creates a Jitsi widget.
This is where users can join call, share screen, collab, video chat, ect.

The error I kept having was when joining the Jitsi meeting, it immediately closed. Web Socket error. Adding the entries to the NGINX section of meet.matrix.domain.com fixed it.

Group chats are a widget, users join, and its good.


This is what I modified. I added in BOLD the SSL certs meet.matrix.domain.com, or else the domain
ssl_certificate /etc/nginx/certs/live/meet.matrix.domain.com/fullchain.pem;

ssl_certificate_key /etc/nginx/certs/live/meet.matrix.domain.com/privkey.pem;


The meet domain works as well, meet.matrix.domain.com is the direct link Jitsi server.
Its public. Anyone can make a meeting and it will work. I don't know if this is meant to be open to outside world.

Is it suppose to be like this? The Jitsi web conference being public?


Yes, this is a starting point. But the stacks work and installed it on Alpine Linux. It was a learning process and needed to understand how this stack works. Too many moving parts. I had to ask AI alot of questions.

The only question I have is the Jitsi server meet.domain.com is public and anyone that goes to the site can start meeting.
Again, still learning, and as you stated, this is a good starting point. It really is. Have to tweak or lockdown the moving parts.
Obliviously, this has to go with a cloud flare or other means of locking down, that is beyond the scope of this post.
But I can confirm it does work.

9 hours ago, unraidrocks said:

Thank you so much for your hard work and effort.

I was experimenting with Alpine linux, and decided to try the docker compose stack on this Virtual machine I spun up.

I had to install this in the same path as Unraid, just because this is what this setup is designed for.

Install worked.
It installed everything.

I had to add a few things, just because I manually put SSL certs for both domains.

I did this install without the SSL/TSL certificates (certbot failed) because I already have the certs saved/created by another web app.
I just copied over private and fullchain keys.

Also, because I did this manually, and in case anyone runs this this issue, NGINX needs the path of the meet.matrix.domain.com certs or else, Jitsi addon won't display inside Element or in web browser.

Also I needed to add these lines to nginx for meet.matrix.domain.com
Only after adding this, UDP 10000 hits worked (Confirmed)
Meetings to jitsi meet.matrix.domain.com are public. (Anyone can make a meeting)

# --- ADD THESE ---

proxy_http_version 1.1;

proxy_set_header Upgrade $http_upgrade;

proxy_set_header Connection "upgrade";

proxy_read_timeout 3600s;

proxy_send_timeout 3600s;

# ------------------



And I finally understand how Jitsi works.
The owner of the room creates a Jitsi widget.
This is where users can join call, share screen, collab, video chat, ect.

The error I kept having was when joining the Jitsi meeting, it immediately closed. Web Socket error. Adding the entries to the NGINX section of meet.matrix.domain.com fixed it.

Group chats are a widget, users join, and its good.


This is what I modified. I added in BOLD the SSL certs meet.matrix.domain.com, or else the domain
ssl_certificate /etc/nginx/certs/live/meet.matrix.domain.com/fullchain.pem;

ssl_certificate_key /etc/nginx/certs/live/meet.matrix.domain.com/privkey.pem;


The meet domain works as well, meet.matrix.domain.com is the direct link Jitsi server.
Its public. Anyone can make a meeting and it will work. I don't know if this is meant to be open to outside world.

Is it suppose to be like this? The Jitsi web conference being public?


Yes, this is a starting point. But the stacks work and installed it on Alpine Linux. It was a learning process and needed to understand how this stack works. Too many moving parts. I had to ask AI alot of questions.

The only question I have is the Jitsi server meet.domain.com is public and anyone that goes to the site can start meeting.
Again, still learning, and as you stated, this is a good starting point. It really is. Have to tweak or lockdown the moving parts.
Obliviously, this has to go with a cloud flare or other means of locking down, that is beyond the scope of this post.
But I can confirm it does work.

I'm glad you have it working.
Its public. Anyone can make a meeting and it will work. I don't know if this is meant to be open to outside world.

yes this was a concern of mine its that way by desing and in theory could be foreced behind teh RP where only your server can call meet.ExampleDomain.com
I'm still working on a nginx RP manual config eidt to acomplish this but due to teh sperate docker isntce comared to a vm/lxc install of the componets (as differenct cofngs get mirred when using docker ...

For secruity you wouldn't want that public. but its also fine if it is as when some one can hit the meet domain and make a meeting its a bit harder to us the meet site directly to add users to join the meeting. as ther are some calls and things per the configuration taht will only allow people in a meeting at that level to be able to comunicate.

this is more with the udp docker in in teh host net due to udb issues in the docker bridge. and how to secure and deploy.

Thus the reason here is somethign to get a example and quick look while working one should manuly edit and define the docker configuration for each and secure it to threre needs.


ATM yes this is by desing to show proof of concept for security it needs to be behind the RP. you can also use the jitsu meet public server as a back end.
example:
https://meet.jit.si/

##########################

Right now my stack is “public Jitsi with Matrix in front.”

What you want is:

🔒 Jitsi only usable by people already inside your Matrix/Element ecosystem
No direct public access to meet.DOMAIN
No exposed 10000/UDP
No exposed 3478/5349
Everything flows through your reverse proxy

Let’s break this down carefully and realistically.

Important Reality Check (WebRTC Limitation)

WebRTC media (JVB + TURN) cannot be fully proxied through Nginx.

  • UDP 10000 cannot be reverse proxied.

  • TURN 3478/5349 cannot be reverse proxied.

  • Media traffic is not HTTP.

You can hide the web UI behind nginx.(the meet.exampledomain.com)
or use a/the public jitsui server...
https://jitsi.org/jitsi-meet/


that said work arounds...

You cannot tunnel WebRTC media through nginx unless you:

  • Switch JVB to TCP 443 mode

  • Or run everything through TURN over TLS 443


What You Actually Want (Secure Architecture)

Instead of:

Internet → 10000 UDP → JVB
Internet → 3478 → Coturn
Internet → meet.DOMAIN

You want:

Internet → 443 → Nginx
                      └── / → Element
                      └── /_matrix → Synapse
                      └── meet.DOMAIN → Jitsi Web
                      └── 443 TCP → JVB (via nginx stream or direct TLS passthrough)

And NO other open ports.

here is how I would go about it form testing (tesing is not done)

Step 1 — Remove Public Port Forwards

On router/firewall:
Remove:
10000 UDP
3478
5349
direct 80 to jitsi
direct 443 to jitsi

Only allow:
80 → nginx (60080)
443 → nginx (60443)


Step 2 — Put Jitsi Web Fully Behind Nginx

In your nginx.conf:


server {
listen 443 ssl http2;
server_name meet.domain_name;

ssl_certificate /etc/nginx/certs/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/privkey.pem;

location / {
proxy_pass http://172.42.0.22:8000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto https;
}

location /xmpp-websocket {
proxy_pass http://172.42.0.22:8000/xmpp-websocket;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}

*Now meet.DOMAIN is not exposed directly.

Step 3 — Secure JVB (Critical Part)

You have two options:

🔹 OPTION A (Cleanest) — Force JVB over TCP 443

Edit JVB config:

In sip-communicator.properties:

org.jitsi.videobridge.DISABLE_TCP_HARVESTER=false
org.jitsi.videobridge.TCP_HARVESTER_PORT=443
org.jitsi.videobridge.TCP_HARVESTER_SSLTCP=true


Then:

Remove 10000 UDP entirely.
Only allow TCP 443.

JVB will piggyback over HTTPS.

This allows:
No UDP open
No 10000 open
Everything over 443

(however I've bee deleting the jitsue docker data fodler and leting the docker configuration recreat and edit configs.. and wound;t be able to point you where that configuration is...)

OR

🔹 OPTION B — Force Everything Through TURN over 443
*What I did as coturn is the legacy and more documentation is on it (secured having workeid with it in the past...)
Configure Coturn to listen only on 443 TLS:

Coturn config:


listening-port=443
tls-listening-port=443
fingerprint
use-auth-secret
no-udp


And configure Jitsi:

ENABLE_TURN=true
https://jitsi.github.io/handbook/docs/dev-guide/dev-guide-configuration/


Idealy current setup is Now:
No 3478 exposed
No 5349 exposed
Only 443

Media will relay via TURN...

🔐 Step 4 — Lock Jitsi to Matrix Users Only

You do NOT want random visitors hitting:

https://meet.domain_name

In Prosody config:

authentication = "internal_hashed"

And enable secure domain:


VirtualHost "meet.domain_name"
authentication = "internal_hashed"

VirtualHost "guest.meet.domain_name"
authentication = "anonymous"
c2s_require_encryption = false


Then in Jicofo config:

org.jitsi.jicofo.auth.URL=XMPP:meet.domain_name

Now only authenticated users (via Matrix widget) can create rooms.

🧠 Even Better (Hard Isolation Mode)

You can block public access entirely at nginx level:

location / {
allow 172.42.0.0/24;
deny all;
}


OR

Require a secret custom header example:

if ($http_x_matrix_auth != "secretkey123") {
return 403;
}

Then inject that header only from Element... etc

But Ultimately this type of setup will mkae meet unusable outside your ecosystem. and only functianl with element

📦 Final Secure Architecture udpate
Internet

└── 443 → Nginx
├── Element
├── Synapse
├── Jitsi Web
└── TCP passthrough to JVB

No:

UDP 10000
3478
5349
Direct Jitsi exposure

Only Matrix users can start calls.

But I'm stil devlepling the code going through docs and working with some other usrs who have ran a simalr matrix synapse and jitsu setup for a couple years.
There is a big difference with direct installing vs docker ran versio of this.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.