#!/usr/bin/env bash # Рендерит статические конфиги coturn/LiveKit из шаблонов (deploy/**/*.template) # в реальные файлы, которые монтирует docker-compose. Оба образа (coturn, # livekit-server) НЕ поддерживают подстановку переменных окружения в файле # конфигурации (см. комментарии в *.template) — единственный способ вынести # секреты/IP в .env и не хранить их в git — сгенерировать файл перед стартом. # # Вызывается автоматически из install.sh. При ручном запуске (без install.sh) # запускайте ПЕРЕД `docker compose up` (и после каждого изменения .env, # влияющего на эти конфиги) — из корня репозитория: # ./deploy/render-templates.sh set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ENV_FILE="$SCRIPT_DIR/../.env" if [ ! -f "$ENV_FILE" ]; then echo "render-templates.sh: не найден $ENV_FILE — сначала запустите ./install.sh или скопируйте .env.example в .env" >&2 exit 1 fi # Читаем только нужные ключи через grep/cut (НЕ `source .env`) — .env содержит # значения вроде `SMTP_FROM=VidConf `, где `<` — # валидный литерал для docker-compose/pydantic, но невалидный bash-синтаксис # (интерпретируется как редирект) при попытке `source` файла целиком. # # `|| true` в конце обязателен: под `set -e -o pipefail` (см. выше) сборка # `"$(env_var VAR)"` для ключа, которого в файле нет ВООБЩЕ (не просто # пустое значение, а отсутствующая строка) иначе завершает весь скрипт # ошибкой grep ДО того, как сработает дружелюбная проверка `:?` ниже — # найдено на TURN_TLS_HOST (новый необязательный ключ, есть не во всех # существующих .env). env_var() { grep -E "^${1}=" "$ENV_FILE" 2>/dev/null | tail -1 | cut -d= -f2- || true } TURN_STATIC_AUTH_SECRET="$(env_var TURN_STATIC_AUTH_SECRET)" TURN_REALM="$(env_var TURN_REALM)" TURN_EXTERNAL_IP="$(env_var TURN_EXTERNAL_IP)" # TURN_TLS_HOST — единственный переключатель TURN over TLS (5349) во всём # проекте: непустой = TLS смонтирован и объявляется клиентам, пустой = TLS # отсутствует везде (dev по умолчанию). Поэтому НЕ обязателен (без `:?`) — # в отличие от TURN_EXTERNAL_IP, который должен быть IP хоста, TURN_TLS_HOST # обязан быть ДОМЕНОМ сертификата (иначе браузер не пройдёт TLS-валидацию # по имени хоста для `turns:`, см. комментарий в livekit.yaml.template). TURN_TLS_HOST="$(env_var TURN_TLS_HOST)" LIVEKIT_API_KEY="$(env_var LIVEKIT_API_KEY)" LIVEKIT_NODE_IP="$(env_var LIVEKIT_NODE_IP)" LIVEKIT_USE_EXTERNAL_IP="$(env_var LIVEKIT_USE_EXTERNAL_IP)" REDIS_PASSWORD="$(env_var REDIS_PASSWORD)" : "${TURN_STATIC_AUTH_SECRET:?TURN_STATIC_AUTH_SECRET не задан в .env}" : "${TURN_REALM:?TURN_REALM не задан в .env}" : "${TURN_EXTERNAL_IP:?TURN_EXTERNAL_IP не задан в .env (внешний IP/домен сервера для TURN-релея)}" : "${LIVEKIT_API_KEY:?LIVEKIT_API_KEY не задан в .env}" : "${LIVEKIT_NODE_IP:?LIVEKIT_NODE_IP не задан в .env (внешний IP/домен для ICE)}" : "${LIVEKIT_USE_EXTERNAL_IP:?LIVEKIT_USE_EXTERNAL_IP не задан в .env (true/false)}" : "${REDIS_PASSWORD:?REDIS_PASSWORD не задан в .env (redis запускается с --requirepass, см. docker-compose.yml)}" export TURN_STATIC_AUTH_SECRET TURN_REALM TURN_EXTERNAL_IP TURN_TLS_HOST LIVEKIT_API_KEY LIVEKIT_NODE_IP LIVEKIT_USE_EXTERNAL_IP REDIS_PASSWORD # Вырезает блок между парой маркеров-комментариев (не только их самих), если # TURN_TLS_HOST пуст — так рендер отражает реальное наличие TLS-сертификатов, # а не просто закомментированные "на будущее" строки. strip_tls_block_if_disabled() { local file="$1" begin_marker="$2" end_marker="$3" if [ -z "$TURN_TLS_HOST" ]; then sed -i.bak "/${begin_marker}/,/${end_marker}/d" "$file" && rm -f "$file.bak" else sed -i.bak "/${begin_marker}/d; /${end_marker}/d" "$file" && rm -f "$file.bak" fi } envsubst '${TURN_STATIC_AUTH_SECRET} ${TURN_REALM} ${TURN_EXTERNAL_IP}' \ < "$SCRIPT_DIR/coturn/turnserver.conf.template" > "$SCRIPT_DIR/coturn/turnserver.conf" strip_tls_block_if_disabled "$SCRIPT_DIR/coturn/turnserver.conf" "# BEGIN-TLS-CERT" "# END-TLS-CERT" echo "[render] deploy/coturn/turnserver.conf готов$([ -n "$TURN_TLS_HOST" ] && echo " (TLS включён)" || echo " (TLS выключен — TURN_TLS_HOST пуст)")" # TURN_EXTERNAL_IP и TURN_STATIC_AUTH_SECRET нужны и здесь: с 0.0.14 LiveKit # анонсирует клиентам внешний coturn (секция `rtc.turn_servers`), и секрет # обязан совпадать с `static-auth-secret` в turnserver.conf выше. envsubst '${LIVEKIT_USE_EXTERNAL_IP} ${LIVEKIT_NODE_IP} ${LIVEKIT_API_KEY} ${REDIS_PASSWORD} ${TURN_EXTERNAL_IP} ${TURN_STATIC_AUTH_SECRET} ${TURN_TLS_HOST}' \ < "$SCRIPT_DIR/livekit/livekit.yaml.template" > "$SCRIPT_DIR/livekit/livekit.yaml" strip_tls_block_if_disabled "$SCRIPT_DIR/livekit/livekit.yaml" "# BEGIN-TLS-TURN" "# END-TLS-TURN" echo "[render] deploy/livekit/livekit.yaml готов" envsubst '${REDIS_PASSWORD}' \ < "$SCRIPT_DIR/egress/egress.yaml.template" > "$SCRIPT_DIR/egress/egress.yaml" echo "[render] deploy/egress/egress.yaml готов"