Este guia explica como configurar um Backend de Alto Desempenho (HPB) para o Nextcloud Talk usando contêineres Docker. O HPB melhora significativamente a performance de videoconferências com múltiplos participantes.
Automação de exemplo para deploy do HPB. Adapte a playbook ao seu ambiente e às suas credenciais.
O HPB consiste em três componentes principais:
- Serviço STUN/TURN (Eturnal) - Gerencia conectividade através de NAT/firewall
- Serviço de Sinalização (spreedbackend) - Coordena comunicação WebRTC entre participantes
- Servidor Janus - Processa streams de áudio e vídeo
Este guia cobre a instalação por subdomínio. Se você preferir usar um caminho (path), adapte a configuração do proxy reverso ao seu ambiente.
Configure as seguintes entradas no seu provedor de DNS:
turn.example.comtalk-signaling.example.comjanus.example.com
Instale o aplicativo talk na sua instância Nextcloud.
Certifique-se de que as seguintes portas estejam liberadas no firewall:
3478/tcp/udp # TURN/STUN
5349/tcp # TURN com TLS (opcional)
50000-50100/udp # Portas de relay do TURN
Liberando as portas no UFW:
ufw allow 3478/tcp
ufw allow 3478/udp
ufw allow 5349/tcp
ufw allow 50000:50100/udp
ufw allow 8080,8443,8188/tcp
O HPB requer três segredos únicos para autenticação:
# Gere 3 segredos diferentes usando openssl
openssl rand --hex 32Execute o comando 3 vezes para obter:
- TURN_SECRET: Autenticação do servidor TURN
- SIGNALING_SECRET: Autenticação do serviço de sinalização
- INTERNAL_SECRET: Comunicação interna entre componentes
TURN_SECRET=86a057a959534eb761b20afb4122da6b5475a5f8db20ba16abbb91c65132ca03
SIGNALING_SECRET=f7d8e9a0b1c2d3e4f5g6h7i8j9k0l1m2n3o4p5q6r7s8t9u0v1w2x3y4z5a6b7c8
INTERNAL_SECRET=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6a7b8c9d0e1f2networks:
reverse-proxy:
external: true
name: reverse-proxy
internal:
driver: bridge
services:
eturnal:
image: ghcr.io/processone/eturnal:latest
container_name: eturnal-talk
ports:
- "3478:3478/udp"
- "3478:3478/tcp"
- "5349:5349/tcp"
- "50000-50100:50000-50100/udp"
restart: unless-stopped
environment:
- ETURNAL_SECRET=${TURN_SECRET}
- ETURNAL_REALM=turn.example.com
- ETURNAL_RELAY_IPV4_ADDR=SEU_IP_PUBLICO
- ETURNAL_RELAY_MIN_PORT=50000
- ETURNAL_RELAY_MAX_PORT=50100
- VIRTUAL_HOST=turn.example.com
- LETSENCRYPT_HOST=turn.example.com
- LETSENCRYPT_EMAIL=email@example.com
# Não há VIRTUAL_PORT aqui porque o proxy reverso não trabalha com UDP.
volumes:
- ./eturnal/eturnal.yml:/etc/eturnal.yml:ro
- ./volumes/eturnal/logs:/var/log/eturnal
networks:
- internal
- reverse-proxyeturnal:
secret: "${TURN_SECRET}"
realm: "turn.example.com"
relay_ipv4_addr: "SEU_IP_PUBLICO"
relay_ipv6_addr: "SEU_IP_PUBLICO_V6" # Opcional
relay_min_port: 50000
relay_max_port: 50100
strict_expiry: false
log_dir: stdout
listen:
- ip: "::"
port: 3478
transport: udp
enable_turn: true
- ip: "::"
port: 3478
transport: tcp
enable_turn: true
modules:
mod_log_stun: {}Se você for usar turns:// em produção, adicione também tls_crt_file e tls_key_file com um certificado válido.
Use a ferramenta online para testar:
- URL: https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/
- STUN/TURN URI:
turn:turn.example.com:3478 - Username:
user-test - Password:
SEU_TURN_SECRET
Clique em Add server e depois em Gather Candidates.
O IP e a porta devem ser listados.
Crie o arquivo volumes/hpb/config/server.conf com o seguinte conteúdo (altere conforme necessário):
[http]
listen = 0.0.0.0:8080
[app]
debug = false
trustedproxies = 172.0.0.0/8
[sessions]
hashkey = ${SESSION_HASHKEY} # Substitua por uma string aleatória de 32 ou 64 bytes
blockkey = ${SESSION_BLOCKKEY} # Substitua por uma string aleatória de 16, 24 ou 32 bytes para criptografar a sessão
[clients]
internalsecret = ${INTERNAL_SECRET}
[backend]
backends = backend
allowall = false
timeout = 20
connectionsperhost = 40
[backend]
url = https://${NEXTCLOUD_URL} # URL da sua instância do Nextcloud
secret = ${SIGNALING_SECRET} # Segredo gerado anteriormente. Deve ser inserido no plugin do Talk.
[nats]
# Endereço do serviço NATS
url = nats://nats:4222
[mcu]
type = janus
# URL do serviço Janus
url = ws://janus:8188/
maxstreambitrate = 1048576
maxscreenbitrate = 2097152
[turn]
# Chave da API usada quando o MCU requisitar as credenciais do TURN
apikey = ${TURN_API_KEY}
# Segredo do TURN. Deve ser o mesmo configurado no servidor TURN.
secret = ${TURN_SECRET}
# Lista de servidores TURN a serem usados
servers = turn:turn.example.com:3478?transport=udp,turn:turn.example.com:3478?transport=tcpAdicione o arquivo volumes/hpb/config/gnatsd.conf com a seguinte configuração:
cluster {
port: 4244 # port for inbound route connections
routes = [
# You can add other servers here to build up a cluster.
#nats-route://otherserver:4244
]
} spreedbackend:
image: mwalbeck/nextcloud-spreed-signaling
volumes:
- ./volumes/hpb/config/server.conf:/config/server.conf
- ./volumes/hpb/ssl/:/etc/nginx/ssl/
restart: unless-stopped
environment:
- JANUS_URL=janus.example.com
- USE_JANUS=1
- VIRTUAL_HOST=talk-signaling.example.com
- LETSENCRYPT_HOST=talk-signaling.example.com
- LETSENCRYPT_EMAIL=email@example.com
- VIRTUAL_PORT=8080
networks:
- reverse-proxy
- internal
extra_hosts:
- "hpb.example.com:SEU_IP_PUBLICO" # Domínio e IP público
Repositório upstream: nextcloud-spreed-signaling
curl -i https://talk-signaling.example.com/api/v1/welcomeResposta esperada:
{
"nextcloud-spreed-signaling": "Welcome",
"version": "1.3.2~docker"
}services:
janus:
image: ghcr.io/librecodecoop/janus:1.3.1
command: ["janus", "--full-trickle"]
# Se o servidor tiver um endereço privado, descomente a linha abaixo e substitua pelo seu IP público.
# command: ["janus", "--full-trickle", "--nat-1-1=SEU_IP_PUBLICO"]
ports:
- "20000-20100:20000-20100/udp"
restart: unless-stopped
volumes:
- ./volumes/janus/config/janus.jcfg:/usr/local/etc/janus/janus.jcfg:ro
- ./volumes/janus/config/janus.transport.websockets.jcfg:/usr/local/etc/janus/janus.transport.websockets.jcfg:rovolumes/janus/config/janus.jcfg
media: {
rtp_port_range = "20000-20100"
}volumes/janus/config/janus.transport.websockets.jcfg
general: {
ws = true
ws_port = 8188
}Se você publicar o HTTP API do Janus para testes, o endpoint padrão continua sendo http://<host>:8088/janus/info. No ambiente interno, o signaling usa ws://janus:8188/.
Acesse /settings/admin/talk no seu Nextcloud:
Clique em Adicionar servidor de back-end de alto desempenho.
Preencha com a URL do servidor de alto desempenho e o SIGNALING_SECRET criado anteriormente. No exemplo, use wss://talk-signaling.example.com.
Servidor TURN:
Adicione um novo servidor clicando em Adicionar um novo servidor TURN.
- Tipo de TURN:
turneturns - URL do servidor TURN:
turn.example.com:3478 - Segredo do servidor TURN:
SEU_TURN_SECRET - Protocolos: TCP e UDP habilitados
Servidor TURN com TLS:
- URL do servidor TURN com TLS:
turns.example.com:5349 - Segredo:
SEU_TURN_SECRET
Infraestrutura de Alto Desempenho:
- URL:
https://talk-signaling.example.com - Segredo compartilhado:
SEU_SIGNALING_SECRET
Sintoma:
session [...]: realm <hpb.example.com> user <>: incoming packet message processed, error 401: Unauthorized
Solução:
- Verifique se o segredo no frontend (Nextcloud) é idêntico ao configurado no backend (Eturnal)
- Confirme que não há espaços extras nos segredos
Sintoma:
Could not send request [...]: context deadline exceeded
Solução:
- Verifique conectividade de rede entre componentes
- Confirme que as portas estão abertas no firewall
- Verifique se os DNS estão resolvendo corretamente
Sintoma:
Could not create connection (nats: no servers available for connection)
Solução:
- Verifique conflitos de nome de contêiner
- Use nomes únicos para os contêineres
- Reinicie os serviços na ordem correta
Sintoma:
Unknown SSRC, dropping packet (SSRC ...)
Explicação:
- Isso é normal durante videoconferências
- Indica múltiplos streams de áudio/vídeo sendo processados
# Verificar logs do Eturnal
docker compose logs eturnal -f
# Verificar logs do Signaling
docker compose logs spreedbackend -f
# Verificar logs do Janus
docker compose logs janus -f
# Verificar status dos contêineres
docker compose ps- Acesse:
about:webrtc - Monitore conexões ativas e estatísticas
# Teste TURN
curl -v turn.example.com:3478
# Teste Signaling
curl -v https://talk-signaling.example.com/api/v1/welcome
# Teste Janus
# Se a API HTTP estiver exposta, o endpoint padrão é:
curl -v http://janus.example.com:8088/janus/info