Установка в Docker

Обновлено:

В этом руководстве описано развертывание 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:

Bash
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:

Bash
docker exec slyber_turn slyber_turn doctor

Проверьте генерацию временных учетных данных через HTTP API.

В режиме secret встроенный API на порту 8080 генерирует готовую пару username и password с ограниченным сроком действия для указанного user_id:

Bash
curl -s "http://127.0.0.1:8080/api/turn-credentials?user_id=some_user_id" && echo ""

Вариант 2. Запуск в режиме redis

Запустите контейнер Slyber TURN Server в связке с Redis:

Bash
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 с помощью утилиты самодиагностики:

Bash
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:

Bash
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:

Bash
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, созданные тестовым набором):

Bash
docker exec slyber_redis redis-cli KEYS "turn/realm/*"

Пример вывода:

Code
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-ключ конкретного пользователя:

Bash
docker exec slyber_redis redis-cli GET "turn/realm/turn.local/user/session_777/key"

4. Проверка оставшегося времени жизни ключа (TTL)

Чтобы узнать, сколько секунд осталось до автоматического удаления сессии из Redis:

Bash
docker exec slyber_redis redis-cli TTL "turn/realm/turn.local/user/session_777/key"

5. Мониторинг обращений TURN-сервера к Redis в реальном времени

Чтобы убедиться, что сервер действительно запрашивает ключи из базы при установке звонка или вызове Ice restart, запустите монитор команд Redis в реальном времени:

Bash
docker exec -it slyber_redis redis-cli MONITOR

6. Принудительное отключение пользователя (отзыв ключа)

Чтобы закрыть доступ пользователю, удалите его ключ:

Bash
docker exec slyber_redis redis-cli DEL "turn/realm/turn.local/user/session_777/key"

Запуск через Docker Compose

Для запуска всей инфраструктуры одной командой сохраните следующий файл docker-compose.yml:

YAML
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

Запуск и остановка стека:

Bash
docker compose up -d
docker compose down

Шпаргалка по проверке и отладке сервера

Просмотр логов TURN-сервера в реальном времени: показывает определенный при старте PUBLIC_IP, активный режим AUTH_MODE и события выделения relay-портов:

Bash
docker logs -f slyber_turn

Комплексная самодиагностика контейнера: проверяет доступность UDP/TCP-сокетов на порту 3478, HTTP API на порту 8080, пул relay-портов и подключение к Redis:

Bash
docker exec slyber_turn slyber_turn doctor

Проверка проброшенных портов Docker на хосте:

Bash
docker port slyber_turn

Проверка версии бинарного файла внутри образа:

Bash
docker run --rm ghcr.io/slyber-app/slyber-turn-server:latest --version

Очистка всех ключей в Redis без остановки контейнеров

Если во время тестирования нужно сбросить все созданные учетные записи в Redis и начать с чистой базы:

Bash
docker exec slyber_redis redis-cli FLUSHALL

Обновление при использовании docker run

Скачайте свежую версию образа из реестра:

Bash
docker pull ghcr.io/slyber-app/slyber-turn-server:latest

Удалите текущий контейнер slyber_turn и пересоздайте его из нового образа:

Для режима secret:

Bash
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 останавливать не нужно, все ключи в базе сохранятся):

Bash
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 "--------------------------------------------------"

Убедитесь, что версия обновилась и сервер исправен:

Bash
docker exec slyber_turn slyber_turn --version
docker exec slyber_turn slyber_turn doctor

Таблица переменных окружения

ПеременнаяПо умолчаниюОписание
PUBLIC_IPautoАвтоматическое определение внешнего IPv4-адреса сервера (для локальных тестов на одной машине можно указать 127.0.0.1)
REALMturn.localДомен (realm) аутентификации TURN-сервера
AUTH_MODEsecretРежим аутентификации: secret (HMAC-SHA1) или redis (динамические ключи в БД)
TURN_SECRET—Секретный ключ для подписи временных паролей в режиме secret
REDIS_ADDR127.0.0.1:6379Адрес подключения к серверу Redis в режиме redis
RELAY_MIN_PORT49152Нижняя граница диапазона UDP-портов для ретрансляции медиапотоков
RELAY_MAX_PORT65535Верхняя граница диапазона UDP-портов для ретрансляции медиапотоков