В этом руководстве описано развертывание Slyber TURN Server в Docker-контейнере, настройка режимов аутентификации и проверка всех узлов системы при тестировании.
Выбор режима аутентификации
Перед запуском контейнера выберите режим проверки учетных данных WebRTC-клиентов с помощью переменной окружения AUTH_MODE:
AUTH_MODE="secret"(автономный режим по секретному ключу): сервер работает без внешних баз данных и проверяет временные пароли по алгоритму HMAC-SHA1 на основе общего ключаTURN_SECRET. Подходит для быстрого развертывания, когда вашему бэкенду достаточно выдавать клиентам временные токены. Ознакомьтесь с HTTP API.AUTH_MODE="redis"(динамический режим через Redis): при каждом подключении сервер проверяет наличие ключа пользователя в базе данных Redis. Это позволяет просматривать активные сессии в реальном времени, управлять их временем жизни (TTL) и мгновенно отключать конкретного участника прямо во время звонка путем удаления его ключа из базы.
По умолчанию при PUBLIC_IP="auto" сервер автоматически определяет свой внешний IPv4-адрес при запуске, поэтому ручная настройка IP не требуется.
Вариант 1. Запуск в режиме secret
Запустите контейнер Slyber TURN Server:
docker pull ghcr.io/slyber-app/slyber-turn-server:latest
docker rm -f slyber_turn 2>/dev/null || true
GEN_SECRET=$(head -c 16 /dev/urandom | od -An -tx1 | tr -d ' \n') && \
docker run -d \
--name slyber_turn \
--restart unless-stopped \
-p 3478:3478/udp \
-p 3478:3478/tcp \
-p 8080:8080/tcp \
-p 50000-50100:50000-50100/udp \
-e PUBLIC_IP="auto" \
-e REALM="turn.local" \
-e AUTH_MODE="secret" \
-e TURN_SECRET="${GEN_SECRET}" \
-e RELAY_MIN_PORT=50000 \
-e RELAY_MAX_PORT=50100 \
ghcr.io/slyber-app/slyber-turn-server:latest && \
sleep 1 && \
docker exec slyber_turn slyber_turn doctor && \
HOST_IP=$([ -n "${SSH_CONNECTION:-}" ] && curl -fsSL4 --max-time 2 ifconfig.me 2>/dev/null || echo 127.0.0.1) && \
echo " TURN / STUN URI : turn:${HOST_IP}:3478 (UDP/TCP)" && \
echo " HTTP API URL : http://${HOST_IP}:8080" && \
echo " Realm : turn.local" && \
echo " Auth Mode : secret (TURN_SECRET=${GEN_SECRET})" && \
echo " Test Creds API : curl -s \"http://${HOST_IP}:8080/api/turn-credentials?user_id=dev\" && echo" && \
echo " Run Benchmark : docker exec slyber_turn slyber_turn bench -clients 20 -duration 5s" && \
echo " Live Logs : docker logs -f slyber_turn" && \
echo "--------------------------------------------------"
Проверьте статус сервера с помощью встроенной утилиты doctor:
docker exec slyber_turn slyber_turn doctor
Проверьте генерацию временных учетных данных через HTTP API.
В режиме secret встроенный API на порту 8080 генерирует готовую пару username и password с ограниченным сроком действия для указанного user_id:
curl -s "http://127.0.0.1:8080/api/turn-credentials?user_id=some_user_id" && echo ""
Вариант 2. Запуск в режиме redis
Запустите контейнер Slyber TURN Server в связке с Redis:
docker network create slyber_net 2>/dev/null || true
docker rm -f slyber_redis 2>/dev/null || true
docker run -d \
--name slyber_redis \
--restart unless-stopped \
--network slyber_net \
-p 6379:6379/tcp \
redis:alpine redis-server --protected-mode no
docker pull ghcr.io/slyber-app/slyber-turn-server:latest
docker rm -f slyber_turn 2>/dev/null || true
docker run -d \
--name slyber_turn \
--restart unless-stopped \
--network slyber_net \
-p 3478:3478/udp \
-p 3478:3478/tcp \
-p 8080:8080/tcp \
-p 50000-50100:50000-50100/udp \
-e PUBLIC_IP="auto" \
-e REALM="turn.local" \
-e AUTH_MODE="redis" \
-e REDIS_ADDR="slyber_redis:6379" \
-e RELAY_MIN_PORT=50000 \
-e RELAY_MAX_PORT=50100 \
ghcr.io/slyber-app/slyber-turn-server:latest && \
sleep 2 && \
docker exec slyber_turn slyber_turn --version && \
docker exec slyber_turn slyber_turn doctor && \
HOST_IP=$([ -n "${SSH_CONNECTION:-}" ] && curl -fsSL4 --max-time 2 ifconfig.me 2>/dev/null || echo 127.0.0.1) && \
echo " TURN / STUN URI : turn:${HOST_IP}:3478 (UDP/TCP)" && \
echo " Redis Endpoint : ${HOST_IP}:6379 (internal: slyber_redis:6379)" && \
echo " HTTP Health URL : http://${HOST_IP}:8080/healthz" && \
echo " Realm : turn.local" && \
echo " Auth Mode : redis" && \
echo " Inspect Keys : docker exec slyber_redis redis-cli KEYS \"turn/realm/*\"" && \
echo " Live Redis Mon : docker exec -it slyber_redis redis-cli MONITOR" && \
echo " Run Benchmark : docker exec slyber_turn slyber_turn bench -clients 20 -duration 5s" && \
echo " Live Logs : docker logs -f slyber_turn" && \
echo "--------------------------------------------------"
Проверьте соединение TURN и Redis с помощью утилиты самодиагностики:
docker exec slyber_turn slyber_turn doctor
Работа с Redis при тестировании: где лежат ключи и как их проверить
В режиме AUTH_MODE="redis" сервер ищет ключи в формате turn/realm/<REALM>/user/<USERNAME>/key. Значением ключа является 32-символьный MD5-хеш строки <USERNAME>:<REALM>:<PASSWORD> согласно стандарту RFC 5389.
1. Ручное создание тестового пользователя
Чтобы создать пользователя session_777 с паролем pass_777 в домене (realm) turn.local и временем жизни ключа 3600 секунд (1 час), выполните:
На Linux:
KEY_HEX=$(printf "session_777:turn.local:pass_777" | md5sum | awk '{print $1}')
docker exec slyber_redis redis-cli SET "turn/realm/turn.local/user/session_777/key" "$KEY_HEX" EX 3600
На macOS:
KEY_HEX=$(printf "session_777:turn.local:pass_777" | md5 | tr -d ' \n')
docker exec slyber_redis redis-cli SET "turn/realm/turn.local/user/session_777/key" "$KEY_HEX" EX 3600
2. Просмотр всех активных пользователей в Redis
Чтобы посмотреть список всех учетных записей, находящихся в данный момент в базе данных (включая пары пиров вроде p3_u1_da37e6, созданные тестовым набором):
docker exec slyber_redis redis-cli KEYS "turn/realm/*"
Пример вывода:
1) "turn/realm/turn.local/user/session_777/key"
2) "turn/realm/turn.local/user/p3_u1_da37e6/key"
3) "turn/realm/turn.local/user/p3_u2_da37e6/key"
3. Проверка хеша конкретного пользователя
Чтобы посмотреть сохраненный MD5-ключ конкретного пользователя:
docker exec slyber_redis redis-cli GET "turn/realm/turn.local/user/session_777/key"
4. Проверка оставшегося времени жизни ключа (TTL)
Чтобы узнать, сколько секунд осталось до автоматического удаления сессии из Redis:
docker exec slyber_redis redis-cli TTL "turn/realm/turn.local/user/session_777/key"
5. Мониторинг обращений TURN-сервера к Redis в реальном времени
Чтобы убедиться, что сервер действительно запрашивает ключи из базы при установке звонка или вызове Ice restart, запустите монитор команд Redis в реальном времени:
docker exec -it slyber_redis redis-cli MONITOR
6. Принудительное отключение пользователя (отзыв ключа)
Чтобы закрыть доступ пользователю, удалите его ключ:
docker exec slyber_redis redis-cli DEL "turn/realm/turn.local/user/session_777/key"
Запуск через Docker Compose
Для запуска всей инфраструктуры одной командой сохраните следующий файл docker-compose.yml:
services:
slyber_redis:
image: redis:alpine
container_name: slyber_redis
restart: unless-stopped
ports:
- "127.0.0.1:6379:6379/tcp"
networks:
- slyber_net
slyber_turn:
image: ghcr.io/slyber-app/slyber-turn-server:latest
container_name: slyber_turn
restart: unless-stopped
depends_on:
- slyber_redis
networks:
- slyber_net
ports:
- "3478:3478/udp"
- "3478:3478/tcp"
- "127.0.0.1:8080:8080/tcp"
- "50000-50100:50000-50100/udp"
environment:
PUBLIC_IP: "auto"
REALM: "turn.local"
AUTH_MODE: "redis"
REDIS_ADDR: "slyber_redis:6379"
RELAY_MIN_PORT: "50000"
RELAY_MAX_PORT: "50100"
networks:
slyber_net:
driver: bridge
Запуск и остановка стека:
docker compose up -d
docker compose down
Шпаргалка по проверке и отладке сервера
Просмотр логов TURN-сервера в реальном времени: показывает определенный при старте PUBLIC_IP, активный режим AUTH_MODE и события выделения relay-портов:
docker logs -f slyber_turn
Комплексная самодиагностика контейнера: проверяет доступность UDP/TCP-сокетов на порту 3478, HTTP API на порту 8080, пул relay-портов и подключение к Redis:
docker exec slyber_turn slyber_turn doctor
Проверка проброшенных портов Docker на хосте:
docker port slyber_turn
Проверка версии бинарного файла внутри образа:
docker run --rm ghcr.io/slyber-app/slyber-turn-server:latest --version
Очистка всех ключей в Redis без остановки контейнеров
Если во время тестирования нужно сбросить все созданные учетные записи в Redis и начать с чистой базы:
docker exec slyber_redis redis-cli FLUSHALL
Обновление при использовании docker run
Скачайте свежую версию образа из реестра:
docker pull ghcr.io/slyber-app/slyber-turn-server:latest
Удалите текущий контейнер slyber_turn и пересоздайте его из нового образа:
Для режима secret:
SAVED_SECRET=$(docker inspect -f '{{range .Config.Env}}{{println .}}{{end}}' slyber_turn 2>/dev/null | grep '^TURN_SECRET=' | cut -d= -f2-)
GEN_SECRET="${SAVED_SECRET:-$(head -c 16 /dev/urandom | od -An -tx1 | tr -d ' \n')}"
docker rm -f slyber_turn 2>/dev/null || true
docker run -d \
--name slyber_turn \
--restart unless-stopped \
-p 3478:3478/udp \
-p 3478:3478/tcp \
-p 8080:8080/tcp \
-p 50000-50100:50000-50100/udp \
-e PUBLIC_IP="auto" \
-e REALM="turn.local" \
-e AUTH_MODE="secret" \
-e TURN_SECRET="${GEN_SECRET}" \
-e RELAY_MIN_PORT=50000 \
-e RELAY_MAX_PORT=50100 \
ghcr.io/slyber-app/slyber-turn-server:latest && \
sleep 1 && \
docker exec slyber_turn slyber_turn --version && \
docker exec slyber_turn slyber_turn doctor && \
HOST_IP=$([ -n "${SSH_CONNECTION:-}" ] && curl -fsSL4 --max-time 2 ifconfig.me 2>/dev/null || echo 127.0.0.1) && \
echo " TURN / STUN URI : turn:${HOST_IP}:3478 (UDP/TCP)" && \
echo " HTTP API URL : http://${HOST_IP}:8080" && \
echo " Realm : turn.local" && \
echo " Auth Mode : secret (TURN_SECRET=${GEN_SECRET})" && \
echo " Test Creds API : curl -s \"http://${HOST_IP}:8080/api/turn-credentials?user_id=dev\" && echo" && \
echo " Run Benchmark : docker exec slyber_turn slyber_turn bench -clients 20 -duration 5s" && \
echo " Live Logs : docker logs -f slyber_turn" && \
echo "--------------------------------------------------"
Для режима redis (контейнер slyber_redis останавливать не нужно, все ключи в базе сохранятся):
docker rm -f slyber_turn 2>/dev/null || true
docker run -d \
--name slyber_turn \
--restart unless-stopped \
--network slyber_net \
-p 3478:3478/udp \
-p 3478:3478/tcp \
-p 8080:8080/tcp \
-p 50000-50100:50000-50100/udp \
-e PUBLIC_IP="auto" \
-e REALM="turn.local" \
-e AUTH_MODE="redis" \
-e REDIS_ADDR="slyber_redis:6379" \
-e RELAY_MIN_PORT=50000 \
-e RELAY_MAX_PORT=50100 \
ghcr.io/slyber-app/slyber-turn-server:latest && \
sleep 1 && \
docker exec slyber_turn slyber_turn --version && \
docker exec slyber_turn slyber_turn doctor && \
HOST_IP=$([ -n "${SSH_CONNECTION:-}" ] && curl -fsSL4 --max-time 2 ifconfig.me 2>/dev/null || echo 127.0.0.1) && \
echo " TURN / STUN URI : turn:${HOST_IP}:3478 (UDP/TCP)" && \
echo " HTTP Health URL : http://${HOST_IP}:8080/healthz" && \
echo " Realm : turn.local" && \
echo " Auth Mode : redis (REDIS_ADDR=slyber_redis:6379)" && \
echo " Inspect Keys : docker exec slyber_redis redis-cli KEYS \"turn/realm/*\"" && \
echo " Live Redis Mon : docker exec -it slyber_redis redis-cli MONITOR" && \
echo " Run Benchmark : docker exec slyber_turn slyber_turn bench -clients 20 -duration 5s" && \
echo " Live Logs : docker logs -f slyber_turn" && \
echo "--------------------------------------------------"
Убедитесь, что версия обновилась и сервер исправен:
docker exec slyber_turn slyber_turn --version
docker exec slyber_turn slyber_turn doctor
Таблица переменных окружения
| Переменная | По умолчанию | Описание |
PUBLIC_IP | auto | Автоматическое определение внешнего IPv4-адреса сервера (для локальных тестов на одной машине можно указать 127.0.0.1) |
REALM | turn.local | Домен (realm) аутентификации TURN-сервера |
AUTH_MODE | secret | Режим аутентификации: secret (HMAC-SHA1) или redis (динамические ключи в БД) |
TURN_SECRET | — | Секретный ключ для подписи временных паролей в режиме secret |
REDIS_ADDR | 127.0.0.1:6379 | Адрес подключения к серверу Redis в режиме redis |
RELAY_MIN_PORT | 49152 | Нижняя граница диапазона UDP-портов для ретрансляции медиапотоков |
RELAY_MAX_PORT | 65535 | Верхняя граница диапазона UDP-портов для ретрансляции медиапотоков |