add snikket-turn (coturn) container for voice/video calls

- Add snikket_turn service (coturn/coturn) with STUN/TURN/TURNS support
- Mount snikket_data volume read-only for TLS certificates from snikket_certs
- Add TURN_SECRET to secrets.env.example
- Enable mod_external_services in Prosody and configure STUN/TURN/TURNS
  endpoints so clients receive time-limited credentials via XMPP IQ

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
bvn13 2026-02-28 01:20:43 +03:00
parent fa87882498
commit c29add0748
3 changed files with 66 additions and 0 deletions

View File

@ -61,6 +61,34 @@ services:
PRESIGN_EXPIRE: "3600" PRESIGN_EXPIRE: "3600"
restart: "unless-stopped" restart: "unless-stopped"
snikket_turn:
container_name: snikket-turn
image: coturn/coturn:latest
network_mode: host
env_file:
- snikket.conf
- secrets.env
volumes:
- snikket_data:/snikket:ro
entrypoint: ["/bin/sh", "-c"]
command: >-
turnserver
--use-auth-secret
--static-auth-secret=$TURN_SECRET
--realm=$SNIKKET_DOMAIN
--listening-port=3478
--tls-listening-port=5349
--cert=/snikket/letsencrypt/live/$SNIKKET_DOMAIN/fullchain.pem
--pkey=/snikket/letsencrypt/live/$SNIKKET_DOMAIN/privkey.pem
--min-port=49152
--max-port=65535
--fingerprint
--no-cli
--log-file=stdout
restart: "unless-stopped"
depends_on:
- snikket_certs
postgres: postgres:
container_name: snikket-postgres container_name: snikket-postgres
image: postgres:17 image: postgres:17

View File

@ -26,6 +26,7 @@ modules_disabled = {
modules_enabled = { modules_enabled = {
"http_upload_external"; "http_upload_external";
"external_services";
} }
-- URL of the external upload service that handles S3 interaction. -- URL of the external upload service that handles S3 interaction.
@ -56,3 +57,36 @@ webrtc = {
} }
} }
} }
----------------------------------------------------------------------
-- TURN/STUN for voice/video calls (via mod_external_services)
-- Credentials are generated on-the-fly using TURN REST API (RFC 8489 §9.2)
-- Shared secret must match TURN_SECRET in secrets.env
----------------------------------------------------------------------
external_services = {
{
type = "stun";
host = os.getenv("SNIKKET_DOMAIN");
port = 3478;
transport = "udp";
},
{
type = "turn";
host = os.getenv("SNIKKET_DOMAIN");
port = 3478;
transport = "udp";
secret = os.getenv("TURN_SECRET");
algorithm = "turn";
ttl = 86400;
},
{
type = "turns";
host = os.getenv("SNIKKET_DOMAIN");
port = 5349;
transport = "tcp";
secret = os.getenv("TURN_SECRET");
algorithm = "turn";
ttl = 86400;
},
};

View File

@ -5,3 +5,7 @@ AWS_SECRET_ACCESS_KEY=change-me
# PostgreSQL secrets # PostgreSQL secrets
POSTGRES_PASSWORD=change-me POSTGRES_PASSWORD=change-me
# TURN server shared secret (used by both coturn and Prosody mod_external_services)
# Generate with: openssl rand -hex 32
TURN_SECRET=change-me