Faire tourner coturn dans Docker paraît simple jusqu'à ce que le premier appel échoue et que vous compreniez que le conteneur n'a jamais eu de vrai chemin pour le trafic de relais. L'image est petite et l'installation vraiment rapide, cinq minutes si tout se passe bien, mais presque tout le monde se heurte au même mur dès le premier essai : le réseau par défaut de Docker et les besoins en ports d'un serveur TURN ne font pas bon ménage.
Voici le docker-compose.yml qui fonctionne vraiment, les réglages de turnserver.conf qui comptent, et la seule décision réseau qui détermine si votre conteneur coturn Docker tient une vraie charge d'appels ou seulement un rapide test en local.
Réponse rapide
Aller à une section
Prérequis
Avant de commencer
- Docker Engine et Docker Compose installés sur un hôte Linux (le réseau de l'hôte, le mode utilisé dans ce guide, est une fonctionnalité de Docker propre à Linux et se comporte autrement sous Docker Desktop pour Mac/Windows).
- Un serveur avec une adresse IP publique et fixe. Le relais TURN ne fonctionne pas derrière un CGNAT ni avec une IP résidentielle qui change.
- Un nom de domaine pointant vers cette IP si vous voulez la prise en charge de TLS (turns:), ainsi qu'un certificat pour ce domaine.
- Les ports 3478 et 5349 (TCP et UDP) et la plage de ports de relais choisie ouverts sur le pare-feu de l'hôte et dans tout groupe de sécurité cloud placé devant.
L'image Docker officielle de coturn
L'image à utiliser est coturn/coturn sur Docker Hub, maintenue directement par le projet coturn et non par un tiers. Elle existe en variante basée sur Debian et en variante plus légère basée sur Alpine (des tags comme 4.14-alpine), et les deux suivent les versions de coturn. Épinglez un tag précis en production ; n'utilisez pas latest pour découvrir qu'un comportement du relais a changé la semaine même d'un incident.
L'image propose trois façons de configurer le serveur : un turnserver.conf monté, des options en ligne de commande ajoutées après le nom de l'image, ou un petit ensemble de variables d'environnement pour la détection automatique d'IP. C'est sur cette troisième option que la plupart des gens trébuchent, nous y revenons plus bas.
Coturn Docker Compose : la configuration
Voici un docker-compose.yml qui fonctionne vraiment, et non la version allégée qui ne gère que la partie STUN :
services:
coturn:
image: coturn/coturn:4.14-alpine
container_name: coturn
restart: unless-stopped
network_mode: host
volumes:
- ./turnserver.conf:/etc/coturn/turnserver.conf:ro
- ./certs:/etc/coturn/certs:ro
- coturn-data:/var/lib/coturn
volumes:
coturn-data: Deux points à remarquer. Il n'y a pas de bloc ports:, et ce n'est pas une erreur : le réseau de l'hôte le rend inutile et Compose l'ignorerait de toute façon. Et coturn-data est un volume nommé plutôt qu'un bind mount, puisque la seule chose qui vit dans /var/lib/coturn/ est un état de session transitoire que vous n'avez pas besoin d'inspecter depuis l'hôte.
Lancez-le de la manière habituelle :
docker compose up -d
docker compose logs -f coturn Configurer turnserver.conf
C'est ce fichier qui fait le vrai travail. Une version minimale mais utilisable en production :
listening-port=3478
tls-listening-port=5349
min-port=49152
max-port=65535
external-ip=203.0.113.10
realm=turn.example.com
use-auth-secret
static-auth-secret=replace-this-with-a-long-random-string
cert=/etc/coturn/certs/fullchain.pem
pkey=/etc/coturn/certs/privkey.pem
no-cli
no-multicast-peers
log-file=stdout Certains de ces réglages comptent plus qu'il n'y paraît :
- external-ip : indiquez l'IP publique réelle de votre serveur, ne laissez pas ce champ vide. Derrière un NAT (c'est techniquement le cas de la plupart des VM cloud, même avec une IP publique associée), il faut dire à coturn quelle adresse annoncer aux clients, sinon les candidats de relais reviennent avec l'IP privée et rien ne se connecte.
- realm : c'est l'un des termes que les gens recherchent directement, et il est simple : ce n'est qu'une chaîne, généralement votre domaine, qui délimite le domaine d'authentification. Il n'a pas besoin que le DNS pointe quelque part pour que TURN fonctionne, mais votre certificat TLS, si.
- use-auth-secret / static-auth-secret : c'est le mécanisme d'identifiants à long terme (des paires nom d'utilisateur/mot de passe basées sur HMAC et à durée limitée), la même approche que dans l'AMI Coturn pour AWS de Meetrix. C'est plus simple à exploiter qu'une liste statique de noms d'utilisateur et de mots de passe, et cela ne demande pas de base de données.
- no-cli : désactive l'interface d'administration en ligne de commande de coturn, accessible par telnet sur le port 5766. Rien ne justifie de l'exposer dans un conteneur, et la laisser active est une surface d'attaque inutile.
Variables d'environnement ou fichier de configuration
Si vous cherchiez précisément des variables d'environnement coturn pour Docker afin de définir TURN_REALM ou équivalent, voici la réponse directe : l'image officielle n'en a pas. Elle ne prend en charge que quatre variables d'environnement, toutes liées à la détection automatique d'IP et non au comportement de TURN :
| Variable | Rôle |
|---|---|
DETECT_EXTERNAL_IP | Détecte automatiquement au démarrage l'adresse IPv4 externe du conteneur |
DETECT_RELAY_IP | Détecte automatiquement l'adresse IPv4 à utiliser pour les allocations de relais |
DETECT_EXTERNAL_IPV6 | Comme ci-dessus, pour IPv6 |
DETECT_RELAY_IPV6 | Comme ci-dessus, pour le relais IPv6 |
Tout le reste, le realm, le static-auth-secret, les certificats TLS, la plage de ports, doit passer par turnserver.conf ou par une option ajoutée à la ligne de commande de docker run ou de Compose. Si vous avez vu un article ou une réponse Stack Overflow où une variable d'environnement TURN_REALM= fonctionne, il s'agit presque certainement d'une image tierce et non de l'officielle, et cela ne suivra pas si vous changez d'image plus tard.
Pourquoi le réseau de l'hôte compte
C'est le point qui fait échouer la plupart des premiers essais, y compris ceux copiés de tutoriels qui l'omettent. TURN a besoin d'une large plage de ports UDP ouverte pour les allocations de relais, de 49152 à 65535 par défaut, soit plus de 16 000 ports. La façon habituelle de Docker d'exposer des ports, une option -p ou un bloc ports: par port, lance un processus docker-proxy distinct en espace utilisateur pour chacun. Seize mille de ces processus mettent un hôte à genoux bien avant l'arrivée du vrai trafic.
network_mode: host contourne entièrement le problème : le conteneur partage directement la pile réseau de l'hôte, sans NAT, sans proxy par port et sans couche de traduction contre laquelle coturn devrait lutter pour déterminer sa propre IP externe.
Si vous ne pouvez pas utiliser le réseau de l'hôte
Encore une chose à savoir avant de déployer : un ticket coturn sur GitHub (#966) documente exactement ce problème, qui se manifeste par des appels qui se connectent puis se coupent, avec « allocation watchdog determined stale session state » dans les journaux, et dont l'origine est que le conteneur devine mal l'IP externe en réseau hôte. Définir external-ip explicitement, comme dans la configuration ci-dessus, permet de l'éviter.
Tester le conteneur
Une fois le conteneur lancé, générez un nom d'utilisateur et un mot de passe temporaires à partir de votre static-auth-secret :
secret=replace-this-with-a-long-random-string && \
time=$(date +%s) && \
expiry=86400 && \
username=$(( $time + $expiry )) && \
echo username:$username && \
echo password:$(echo -n $username | openssl dgst -binary -sha1 -hmac $secret | openssl base64) Saisissez ensuite l'adresse du serveur, le nom d'utilisateur et le mot de passe générés dans l'outil de test Trickle ICE, lancez la collecte des candidats et cherchez un candidat de type relay dans les résultats. Pas de candidat relay signifie que le conteneur tourne mais n'est pas encore utilisable comme serveur TURN, généralement à cause d'external-ip, du pare-feu ou de la plage de ports plutôt que de coturn lui-même. Notre testeur ICE WebRTC effectue la même vérification et explique clairement chaque candidat trouvé.
Dépannage
- Le conteneur démarre mais aucun candidat relay n'apparaît : vérifiez que
external-ipdans turnserver.conf correspond à l'IP publique réelle du serveur, et que le groupe de sécurité ou le pare-feu placé devant autorise toute la plage UDP de min-port à max-port, pas seulement 3478 et 5349. - Ça marche en local mais échoue pour les utilisateurs distants : c'est presque toujours une lacune du pare-feu ou du groupe de sécurité sur la plage de ports de relais, ou le conteneur tourne sans réseau hôte avec seulement 3478/5349 publiés.
- La négociation TLS échoue sur le 5349 : le chemin de montage du volume des certificats doit correspondre exactement à ce que pointent
certetpkeydans le conteneur. Une faute de frappe dans un chemin relatif échoue ici sans bruit dans les journaux, à moins de les surveiller de près. - CPU élevé sous charge : si vous n'êtes pas en réseau hôte, c'est très souvent la surcharge de docker-proxy décrite plus haut, et non coturn lui-même qui peine.
Quand éviter l'installation maison
Faire tourner coturn dans Docker est le bon choix quand vous voulez un contrôle total de la configuration, que vous utilisez déjà une pile basée sur Docker, ou que vous testez avant de vous engager sur une infrastructure. C'est aussi un service de plus dont vous êtes responsable : mettre à jour l'image, surveiller le disque et la mémoire, renouveler les certificats, et être celui qu'on appelle quand un changement réseau dont personne ne vous a parlé bloque la plage de ports de relais.
Si vous préférez ne pas assurer ces astreintes vous-même, Meetrix maintient une AMI Coturn pour AWS préconfigurée et une image GCP équivalente, toutes deux avec le réseau, TLS et les identifiants à long terme déjà correctement configurés. Il existe aussi une option de déploiement en un clic si vous voulez les économies de l'auto-hébergement sans jamais toucher à un docker-compose.yml. Et si le serveur TURN est destiné à un déploiement Jitsi Meet, le guide de configuration TURN pour Jitsi et le guide Jitsi sur AWS (ou son équivalent GCP) couvrent les différences de configuration propres à ce cas.
Questions fréquentes
Quelle est l'image Docker officielle de coturn ?
C'est coturn/coturn sur Docker Hub, maintenue par le projet coturn lui-même. Elle existe en variantes basées sur Debian et sur Alpine (les tags alpine sont nettement plus légers). Des images tierces comme instrumentisto/coturn existent aussi, mais l'image officielle est celle à privilégier.
L'image Docker de coturn prend-elle en charge des variables d'environnement comme TURN_REALM ?
Non. L'image officielle n'expose qu'une poignée de variables d'environnement pour la détection automatique d'IP (DETECT_EXTERNAL_IP, DETECT_RELAY_IP et leurs équivalents IPv6). Le realm, le static-auth-secret et tous les autres réglages TURN viennent d'un fichier turnserver.conf monté ou d'options en ligne de commande, pas de variables d'environnement.
Pourquoi coturn a-t-il besoin de network_mode: host dans Docker ?
Coturn relaie les flux média sur une large plage de ports UDP, de 49152 à 65535 par défaut. Publier toute cette plage avec le mappage de ports habituel de Docker lance un processus docker-proxy par port, ce qui étouffe l'hôte sous une vraie charge d'appels. Le réseau de l'hôte contourne entièrement cette couche.
Puis-je faire tourner coturn dans Docker sans le réseau de l'hôte ?
Oui, si vous réduisez d'abord la plage de relais. Réglez min-port et max-port sur quelque chose comme 49152 à 49352 dans turnserver.conf, puis publiez cette plage réduite ainsi que 3478 et 5349 dans votre fichier compose. Cela fonctionne, mais limite le nombre d'appels relayés simultanés que le serveur peut gérer.
Comment générer des identifiants TURN pour tester un conteneur coturn ?
Avec use-auth-secret et un static-auth-secret définis dans turnserver.conf, générez un nom d'utilisateur et un mot de passe à durée limitée avec un script HMAC-SHA1 (openssl dgst -hmac), puis testez-les contre le conteneur avec l'outil WebRTC Trickle ICE avant de le brancher sur votre application.
Où coturn stocke-t-il ses données dans Docker ?
L'image écrit par défaut dans /var/lib/coturn/, principalement l'état SQLite du processus turnserver. Si vous n'utilisez que des identifiants à long terme via static-auth-secret plutôt qu'une base d'utilisateurs, vous pouvez monter ce chemin en tmpfs, car rien ne mérite d'être conservé entre deux redémarrages.
Évitez complètement l'installation Docker
Lancez un serveur coturn préconfiguré sur AWS, avec le réseau, TLS et les identifiants déjà correctement réglés.
Obtenir Coturn sur AWS Marketplace