below a draft of a very similar article I planned for long time. maybe over time we can combine both into a best practice running HPB as container
Talk HPB overview
Long planned article and implementation of Nextcloud Talk HPB. I’m doing it hard way with all components configured one by one. this is little harder than simply adding AiO Talk container (look at High Performance Backend for Talk on Nextcloud with Docker for details) which does the job a s well but I don’t like balck boxes and prefer to know what is inside and how it works. this manual way allows more control about individual parts and gives your understanding how they work together.
I had really hard time understanding how it works as almost no docs exist and things are not really hidden but not documented well too. In fact the integration turns out pretty simple with 3 (or 4) components required. Start with the turn server which is a must for each Talk installation. I’m using coturn but there are alternatives and I think there is no real difference. TURN server is workhorse doing hard job connecting clients in the internet bypassing firewall NAT, even CG-NAT to make client talk to each other.
Once the TURN server is in place participants can talk to each other but one problem remains - each client must send it’s media to every other meeting participant.. which becomes problematic if cpu power and bandwidth is limited. this is where the Talk HPB comes into play - it works as central instance receiving one media stream from each participant multiplexing it with other streams and sending one stream to each other participant. this components is known as MCU in other communication systems. HPB consists of 3 components: signalling server, janus and nats (which might be optional for small installations).
archticture
flowchart LR
fritz.box-- port forward<br>udp/3478<br>udp/50000-500100 -->TURN;
fritz.box-- port forward<br>http tcp/80<br>https tcp/443 -->RP;
subgraph fritzbox
fritz.box(router<br>192.168.179.1);
end
subgraph srv
subgraph nc.mydomain.tld
NC[app];
NCNW([more comonents like db, redis...]);
end
subgraph dev-nc.mydomain.tld
DEV-NC[app];
DEV-NCNW([more comonents like db, redis...]);
end
subgraph talk-hpb
TURN[coturn]
SIGNALLING(talk-hpb)
NATS
JANUS
SIGNALLING & JANUS -- turn:corurn:3478 --> TURN
SIGNALLING -- ws://nats://nats:4222 --> NATS
SIGNALLING -- ws://janus:8188 --> JANUS
end
RP-- https:// ${TALKHPB_FQDN} -->SIGNALLING
RP-- https -->NC & DEV-NC
TURN <-.-> NC & DEV-NC
RP[reverse proxy<br>:80 + :443]
end
configuration
below compose file creates the “talk-hpb” part of the above architecture image. strictly speaking coturn is not part of an HPB but both are required for Talk and could be shared for multiple independent Nextcloud installations.
global config .env
this files contains global settings and settings shared between services
# .env
#TURN server
COTURN_SECRET=<<<shared TRUN secret>>>
COTURN_FQDN=turn.mydomain.tld
TALKHPB_FQDN=talk-hpb.mydomain.tld
NATS_VERSION=2.11.7 # omit for :latest tag
SIGNALLING_VERSION=2.0.1 # omit for :latest tag
# janus
JANUS_VERSION=1.3.2
LIBSRTP_VERSION=2.7.0
USRSCTP_VERSION=b28f0b55b00bde67f6be80d6623e2775b88026b8
compose.yml
static docker compose file - config is done using .env file
# compose.yml
services:
nats:
image: nats:${NATS_VERSION:-latest}
#command: ["-c", "/config/gnatsd.conf"]
command:
- -p=4222
#- -m 8222 # management port
#- -D # enable debug for logs
restart: unless-stopped
janus:
image: local/janus-custom
build:
context: ./talk-hpb # Point to the directory containing your Dockerfile
dockerfile: ./janus-dockerfile
restart: unless-stopped
networks:
- proxy
command:
- janus
- --full-trickle
- --stun-server=coturn:3478
signalling:
image: strukturag/nextcloud-spreed-signaling:${SIGNALLING_VERSION:-latest}
restart: unless-stopped
depends_on:
- nats
- janus
- coturn
networks:
- proxy
- default
env_file:
- ./talk-hpb/signalling.env
environment:
- EXTERNAL_HOSTNAME=${TALKHPB_FQDN}
- TURN_API_KEY=${COTURN_SECRET}
- TURN_SECRET=${COTURN_SECRET}
# Define traefik router for the signaling server
labels:
- traefik.enable=true
- traefik.http.routers.signalling.rule=Host(`${TALKHPB_FQDN}`)
- traefik.http.routers.signalling.tls=true
- traefik.http.routers.signalling.tls.certresolver=letsencryptresolver
- traefik.http.services.signalling.loadbalancer.server.port=8080
- traefik.docker.network=proxy
coturn:
image: coturn/coturn
container_name: coturn
restart: unless-stopped
ports:
- 3478:3478
- 3478:3478/udp
- 50000-50099:50000-50099/udp
- 9641:9641
environment:
- DETECT_EXTERNAL_IP=yes
- DETECT_RELAY_IP=yes
command:
- -n
- --log-file=/var/turn.log
- --realm=${COTURN_FQDN}
- --use-auth-secret
- --static-auth-secret=${COTURN_SECRET}
- --verbose
volumes:
- ./coturn/:/var/
- ./turnserver.conf:/etc/coturn/turnserver.conf
networks:
- proxy
talk-hpb/signalling.env
# talk-hpb/signalling.env
# https://github.com/strukturag/nextcloud-spreed-signaling/tree/master/docker
HTTP_LISTEN=0.0.0.0:8080
TRUSTED_PROXIES=172.16.0.0/12,192.168.0.0/1,10.0.0.0/8,fc00::/7,fe80::/10,2001:db8::/32
MAX_STREAM_BITRATE=2097152 # 2Mbit/s
MAX_SCREEN_BITRATE=4194304 # 4Mbit/s
# Janus/WebRTC
USE_JANUS=1
JANUS_URL=ws://janus:8188
# No need for nats when only one Spreed-Server
NATS_URL=nats://nats:4222
TURN_SERVERS=turn:coturn:3478
#LOG_LEVEL="debug"
LOG_LEVEL="info"
#BACKENDS_ALLOWALL: Allow all backends. Extremly insecure - use only for development!
#BACKENDS_ALLOWALL_SECRET: Secret when BACKENDS_ALLOWALL is enabled.
BACKENDS="NC DEVNC TESTNC"
# nc
BACKEND_NC_URL=https://nc.mydomain.tld
BACKEND_NC_SHARED_SECRET=<<<replace me with a secret>>>
BACKEND_NC_SESSION_LIMIT=15
BACKEND_NC_MAX_STREAM_BITRATE=2097152
BACKEND_NC_MAX_SCREEN_BITRATE=4194304
# dev-nc
BACKEND_DEVNC_URL=https://dev-nc.mydomain.tld
BACKEND_DEVNC_SHARED_SECRET=<<<replace me with a secret>>>
BACKEND_DEVNC_SESSION_LIMIT=5
BACKEND_DEVNC_MAX_STREAM_BITRATE=1048576
BACKEND_DEVNC_MAX_SCREEN_BITRATE=2097152
# test-nc
BACKEND_TESTNC_URL=https://test-nc.mydomain.tld
BACKEND_TESTNC_SHARED_SECRET=<<<replace me with a secret>>>
BACKEND_TESTNC_SESSION_LIMIT=5
BACKEND_TESTNC_MAX_STREAM_BITRATE=1048576
BACKEND_TESTNC_MAX_SCREEN_BITRATE=2097152