diff --git a/deploy/install.sh b/deploy/install.sh index 73135ec..77e58d2 100755 --- a/deploy/install.sh +++ b/deploy/install.sh @@ -251,9 +251,19 @@ resolve_derived_values() { use_external_ip="true" PROFILE_LIVEKIT_USE_EXTERNAL_IP="$use_external_ip" + # Набор кодеков зависит от профиля: на lite/standard оставляем VP8 + # (минимум CPU у отправителя), на plus/pro добавляем VP9/H.264/AV1. + livekit_extra_codecs="" + if [ "${PROFILE_LIVEKIT_SIMULCAST:-0}" -gt 0 ] 2>/dev/null; then + livekit_extra_codecs=' - mime: video/vp9 + - mime: video/h264 + - mime: video/av1' + fi + GLCHAT_DATA_DIR="${GLCHAT_DATA_DIR}" GLCHAT_CADDY_PROFILE="${CADDY_PROFILE}" export FILES_DOMAIN_RESOLVED CADDY_PROFILE LIVEKIT_PUBLISH TURN_EXTERNAL_TLS \ + livekit_extra_codecs \ PROFILE_LIVEKIT_DISABLE_SIMULCAST PROFILE_LIVEKIT_USE_EXTERNAL_IP \ GLCHAT_DATA_DIR GLCHAT_CADDY_PROFILE } @@ -671,6 +681,7 @@ render_all_templates() { "TURN_TLS_PORT=${TURN_TLS_PORT}" \ "TURN_EXTERNAL_TLS=${turn_external_tls}" \ "LIVEKIT_MAX_PARTICIPANTS=${PROFILE_LIVEKIT_MAX_PARTICIPANTS}" \ + "LIVEKIT_EXTRA_CODECS=${livekit_extra_codecs}" \ "LIVEKIT_DISABLE_SIMULCAST=${disable_simulcast}" if [ "$ENABLE_FAIL2BAN" = "true" ]; then diff --git a/deploy/livekit/livekit.yaml.tpl b/deploy/livekit/livekit.yaml.tpl index ee873e0..60c1a06 100644 --- a/deploy/livekit/livekit.yaml.tpl +++ b/deploy/livekit/livekit.yaml.tpl @@ -1,5 +1,6 @@ # Сгенерировано deploy/install.sh — не редактируйте вручную. -# Документация: https://docs.livekit.io/home/self-hosting/deployment/ +# Ключи сверены с официальным config-sample.yaml livekit-server: неизвестные +# поля приводят к отказу запуска, поэтому здесь только поддержанные настройки. port: ${LIVEKIT_WS_PORT} bind_addresses: - "0.0.0.0" @@ -8,16 +9,10 @@ rtc: tcp_port: ${LIVEKIT_TCP_PORT} udp_port: ${LIVEKIT_UDP_PORT} use_external_ip: ${LIVEKIT_USE_EXTERNAL_IP} - # Синхронизация портов с публичным адресом: контейнер публикует порты напрямую. - port_range_start: 0 - port_range_end: 0 + # TCP-fallback, когда UDP заблокирован сетью клиента (AGENT.md 7.14). + allow_tcp_fallback: true -turn: - enabled: ${TURN_ENABLED} - domain: ${TURN_DOMAIN} - udp_port: ${TURN_UDP_PORT} - tls_port: ${TURN_TLS_PORT} - external_tls: ${TURN_EXTERNAL_TLS} +keys: {} room: auto_create: true @@ -25,18 +20,24 @@ room: departure_timeout: 20 max_participants: ${LIVEKIT_MAX_PARTICIPANTS} enable_remote_unmute: false + # VP8 — самый дешёвый по CPU на отправителе; на профилях plus/pro + # к нему добавляются VP9, H.264 и AV1. + enabled_codecs: + - mime: audio/opus + - mime: video/vp8 +${LIVEKIT_EXTRA_CODECS} audio: - # Opus с низким битрейтом: экономия канала при 1 vCPU (AGENT.md 9.1). + # Уровень активности говорящего, 0–127 (меньше — чувствительнее). active_level: 35 - min_level: 25 - smooth_intervals: false - -video: - dynacast: true - disable_simulcast: ${LIVEKIT_DISABLE_SIMULCAST} logging: level: info json: true - sample: true + +turn: + enabled: ${TURN_ENABLED} + domain: ${TURN_DOMAIN} + udp_port: ${TURN_UDP_PORT} + tls_port: ${TURN_TLS_PORT} + external_tls: ${TURN_EXTERNAL_TLS} diff --git a/deploy/smoke.sh b/deploy/smoke.sh index 9af0a89..6d333de 100755 --- a/deploy/smoke.sh +++ b/deploy/smoke.sh @@ -72,14 +72,14 @@ else fi printf '\n[3] Публичный доступ\n' -if [ "$PROXY_MODE" = "external" ]; then +if [ "$SKIP_TLS" = "1" ]; then + skip "TLS отключён (--skip-tls): публичная проверка пропущена" +elif [ "$PROXY_MODE" = "external" ]; then if curl -fsS --max-time 10 "https://${DOMAIN}/api/v1/meta" >/dev/null 2>&1; then pass "https://${DOMAIN}/api/v1/meta отвечает через внешний прокси" else fail "https://${DOMAIN} недоступен: добавьте блок из ${GLCHAT_ETC_DIR}/external-proxy.conf во внешний прокси" fi -elif [ "$SKIP_TLS" = "1" ]; then - skip "TLS отключён (--skip-tls): публичная проверка пропущена" else if curl -fsS --max-time 15 "https://${DOMAIN}/api/v1/meta" >/dev/null 2>&1; then pass "https://${DOMAIN}/api/v1/meta отвечает (сертификат валиден)" @@ -185,8 +185,10 @@ printf '\n[9] Бэкап\n' if GLCHAT_ETC_DIR="$GLCHAT_ETC_DIR" bash "${GLCHAT_ETC_DIR}/backup.sh" >/tmp/glchat-smoke-backup.log 2>&1; then last_backup="$(ls -1t "${GLCHAT_ETC_DIR}/data/backups"/glchat-*.tar.gz* 2>/dev/null | head -1)" pass "бэкап создан: $(basename "${last_backup:-unknown}")" - if [ "${last_backup}" != *.age ]; then - skip "бэкап без шифрования (AGE_RECIPIENT не задан)" + if [ "${last_backup}" = *.age ]; then + pass "бэкап зашифрован age" + else + warn "бэкап создан без шифрования: задайте AGE_RECIPIENT (install.sh генерирует его автоматически)" fi else fail "бэкап не создан (см. /tmp/glchat-smoke-backup.log)" diff --git a/scripts/target-install.sh b/scripts/target-install.sh new file mode 100644 index 0000000..0a17b4d --- /dev/null +++ b/scripts/target-install.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +# Установка glchat на целевой стенд (HomeServer) в режиме без домена. +# Требует root: при запуске через `sudo -S` пароль передаётся на stdin, +# поэтому перенаправлять stdin из /dev/null нельзя. +set -euo pipefail + +REPO="${GLCHAT_REPO:-/opt/glchat-src-new}" +DOMAIN="${GLCHAT_DOMAIN:-10.77.0.13}" +ADMIN_EMAIL="${GLCHAT_ADMIN_EMAIL:-admin@gl.mhspx.su}" + +[ "$(id -u)" -eq 0 ] || { + echo "запустите через sudo: sudo bash scripts/target-install.sh" >&2 + exit 1 +} +[ -f "${REPO}/deploy/install.sh" ] || { + echo "не найден репозиторий: ${REPO}" >&2 + exit 1 +} + +cd "$REPO" +shift 0 +exec bash deploy/install.sh \ + --domain "$DOMAIN" \ + --email "${GLCHAT_ACME_EMAIL:-admin@gl.mhspx.su}" \ + --admin "$ADMIN_EMAIL" \ + --password "${GLCHAT_ADMIN_PASSWORD:?задайте GLCHAT_ADMIN_PASSWORD}" \ + "$@"