fix(livekit): конфиг по официальной схеме livekit-server

- убраны недопустимые поля (audio.min_level, audio.smooth_intervals,
  video.dynacast, video.disable_simulcast) — из-за них контейнер livekit
  циклически перезапускался
- набор кодеков задаётся через room.enabled_codecs: VP8 на lite/standard,
  VP8+VP9+H.264+AV1 на plus/pro
- keys: {} — ключи передаются через LIVEKIT_KEYS (секрет не попадает в файл)
- smoke.sh: ветка --skip-tls больше не проверяет HTTPS, бэкап с расширением
  .age больше не помечается как незашифрованный
This commit is contained in:
2026-09-19 19:55:31 +03:00
parent d4c6cfa643
commit 8f7620026d
4 changed files with 64 additions and 23 deletions
+11
View File
@@ -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
+19 -18
View File
@@ -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}
+7 -5
View File
@@ -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)"
+27
View File
@@ -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}" \
"$@"