Bedrud Документация

Bedrud использует YAML-файлы конфигурации как для основного сервера, так и для встроенного медиасервера LiveKit.

См. также: Быстрый старт | Установка | Руководство по развёртыванию | Руководство по Docker

Минимальная конфигурация для production

Конфигурация по умолчанию подходит для разработки. Для production измените следующие значения в /etc/bedrud/config.yaml:

auth:
  jwtSecret: "change-to-random-string-32-chars"
  sessionSecret: "change-to-another-random-string"

Перезапустите после изменений:

sudo systemctl restart bedrud livekit

Полная справка ниже.


Конфигурация сервера

Расположение: server/config.yaml (разработка) или /etc/bedrud/config.yaml (production)

Полная справка

server:
  port: 8090                    # HTTP порт
  host: "localhost"             # Адрес привязки
  maxParticipantsLimit: 1000    # Hard ceiling for room capacity (0 = unlimited). Env: SERVER_MAX_PARTICIPANTS_LIMIT
  maxRoomsPerUser: 100          # Max active rooms per user (0 = unlimited). Env: SERVER_MAX_ROOMS_PER_USER
 
database:
  type: "sqlite"                # Тип базы данных: sqlite или postgres
  path: "data.db"               # Путь к файлу базы данных SQLite
 
logger:
  level: "debug"                # Уровень логирования: debug, info, warn, error. Управляет логами приложения и SQL-запросов.
  outputPath: ""                # Путь к файлу логов (пусто = stdout)
 
livekit:
  host: "http://localhost:8090/livekit"  # Внешний URL LiveKit
  internalHost: "http://127.0.0.1:7880"  # Внутренний URL LiveKit
  apiKey: "devkey"              # API-ключ LiveKit (auto-generated if empty)
  apiSecret: "devsecret"        # API-секрет LiveKit
 
auth:
  jwtSecret: "your-jwt-secret"           # Секрет для подписи JWT-токенов
  tokenDuration: 24                       # Срок действия токена в часах
  sessionSecret: "your-session-secret"    # Секрет для cookie сессий
  frontendURL: "http://localhost:8090"    # URL фронтенда (для редиректов OAuth)
  passkeyChallengeTTL: 5                # Срок действия Passkey-вызова в минутах
 
  # Провайдеры OAuth (опционально)
  google:
    clientId: ""
    clientSecret: ""
  github:
    clientId: ""
    clientSecret: ""
  twitter:
    clientKey: ""
    clientSecret: ""
 
cors:
  allowedOrigins: "http://localhost:8090,http://localhost:3000"  # Через запятую
  allowedHeaders: "Origin, Content-Type, Accept, Authorization"
  allowedMethods: "GET, POST, PUT, DELETE, OPTIONS"
  allowCredentials: true
 
rateLimit:
  authMaxRequests: 10       # Max auth requests per window (login, register, refresh, passkey). 0 = disable
  authWindowSecs: 60         # Auth rate limit window in seconds
  guestMaxRequests: 5        # Max guest join requests per window. 0 = disable
  guestWindowSecs: 60        # Guest rate limit window in seconds
 
chat:
  maxUploadBytesPerUser: 524288000       # Per-user upload quota (500 MB). 0 = unlimited. Env: CHAT_MAX_UPLOAD_BYTES_PER_USER
  globalDiskThresholdBytes: 0            # Global storage ceiling across all users. 0 = unlimited. Env: CHAT_GLOBAL_DISK_THRESHOLD_BYTES
  maxMessageCount: 10000                 # Max chat messages kept per room (0 = unlimited). Env: CHAT_MAX_MESSAGE_COUNT
  messageTTLHours: 2160                  # Purge messages older than this in hours (0 = forever). 2160 = 90 days. Env: CHAT_MESSAGE_TTL_HOURS
 
 
recording:
  maxFileSizeMB: 2048           # Max recording file size in MB (0 = unlimited). Env: RECORDING_MAX_FILE_SIZE_MB
  storageDir: "./data/recordings"  # Local storage path for disk-backed recordings. Env: RECORDING_STORAGE_DIR
  maxRecordingsPerRoom: 100     # Max total recordings per room (0 = unlimited). Env: RECORDING_MAX_PER_ROOM
 
queue:
  pollInterval: 500              # ms between job polls. Env: QUEUE_POLL_INTERVAL
  maxAttempts: 3                 # retries before marking failed. Env: QUEUE_MAX_ATTEMPTS
  concurrency: 1                 # worker goroutines. Env: QUEUE_CONCURRENCY
 
email:
  smtpHost: ""                    # SMTP server hostname. Env: EMAIL_SMTP_HOST
  smtpPort: 587                   # SMTP server port. Env: EMAIL_SMTP_PORT
  username: ""                    # SMTP username. Env: EMAIL_USERNAME
  password: ""                    # SMTP password. Env: EMAIL_PASSWORD
  fromAddress: ""                 # From address. Env: EMAIL_FROM_ADDRESS
  fromName: "Bedrud"              # From display name. Env: EMAIL_FROM_NAME
  tlsSkipVerify: false       # Skip TLS certificate validation. Env: EMAIL_TLS_SKIP_VERIFY
  smtpsMode: false           # Direct TLS (SMTPS, port 465). Env: EMAIL_SMTPS_MODE

Основные настройки

База данных

По умолчанию Bedrud использует SQLite с файлом по указанному пути path. Для production с высокой параллельностью переключитесь на PostgreSQL, указав строку подключения. При использовании PostgreSQL поле path содержит строку подключения, а не путь к файлу:

database:
  type: "postgres"
  path: "postgres://user:password@localhost:5432/bedrud?sslmode=disable"

Аутентификация

jwtSecret используется для подписи access- и refresh-токенов. Измените его со значения по умолчанию в production.

Провайдеры OAuth опциональны. Если вы их не настроите, кнопки входа через соцсети не появятся в интерфейсе. Для каждого провайдера необходимо зарегистрировать OAuth-приложение в соответствующем сервисе и указать client ID и секрет.

CORS

Строка allowedOrigins (через запятую) должна содержать URL, по которому обслуживается фронтенд. В разработке это http://localhost:3000. В production укажите ваш домен (например, https://meet.example.com).

Ограничение скорости

Ограничение скорости защищает эндпоинты аутентификации от атак методом перебора и DoS-атак. Два типа:

  • Эндпоинты аутентификации (вход, регистрация, обновление токена, Passkey) — по умолчанию: 10 запросов за 60 секунд на IP
  • Гостевой вход — по умолчанию: 5 запросов за 60 секунд на IP

Опустите раздел rateLimit для использования значений по умолчанию. Установите authMaxRequests: 0 или guestMaxRequests: 0 для отключения.

Chat History

Bedrud applies advisory retention limits to in-room chat messages. Since LiveKit — the real-time media layer — does not persist data channel messages server-side, these limits are enforced on the client:

  • maxMessageCount — caps the number of chat messages held in memory and sessionStorage per room. When exceeded, the oldest messages are trimmed. Default: 10000. Set to 0 for unlimited.
  • messageTTLHours — messages older than this threshold are purged from the local cache. Default: 2160 (90 days). Set to 0 to keep messages indefinitely.

Chat messages in Bedrud are transmitted exclusively through LiveKit data channels and are not stored on the server. The retention limits above control how many messages the frontend keeps in memory and sessionStorage. A dedicated chat history service (with server-side persistence) would be needed for true history across sessions — this is tracked as a future enhancement.

Recordings

Room recording is controlled by the RecordingsEnabled system setting (toggle in admin Settings → General). When enabled:

  • Moderators can start/stop composite MP4 recordings from the meeting controls bar
  • Recordings are stored alongside chat uploads using the configured storage backend (disk/S3)
  • Each room has a per-room recordingsAllowed toggle that must also be enabled
  • Failed/pending recordings over 7 days old are automatically cleaned up daily
  • Non-persistent rooms have a configurable per-room recording cap (maxRecordingsPerRoom) to prevent abuse
  • After a room is deleted, the recording creator can still access their recordings from the same room URL

YAML Reference:

  • maxFileSizeMB — maximum file size for a single recording in MB. 0 = unlimited. Default: 2048. Env: RECORDING_MAX_FILE_SIZE_MB
  • storageDir — directory for disk-backed recordings. Only used when S3 is not configured. Default: ./data/recordings. Env: RECORDING_STORAGE_DIR
  • maxRecordingsPerRoom — caps total recordings per room (all statuses: completed, failed, etc.). 0 = unlimited. Only enforced for non-persistent rooms. Default: 100. Env: RECORDING_MAX_PER_ROOM

See the Recordings Guide for full details.

Очередь (система задач)

Внутренняя очередь задач обрабатывает асинхронные фоновые задачи, такие как удаление пользователей/комнат, приостановка и загрузка файлов чата.

  • pollInterval — как часто worker проверяет новые задачи (в мс). Меньшие значения уменьшают задержку за счет большего количества запросов к БД.
  • maxAttempts — максимальное количество повторных попыток, прежде чем задача будет помечена как неудачная. Повторные попытки используют экспоненциальную задержку (2^попытка * 5s, с上限м в 1 час).
  • concurrency — количество goroutine worker. Увеличьте для более высокой пропускной способности на PostgreSQL. SQLite ограничен одним worker (одно соединение).

Уведомления по электронной почте

Bedrud может отправлять транзакционные письма (приветствие, сброс пароля, приглашение в комнату) через SMTP.

  • smtpHost / smtpPort — адрес SMTP-сервера. Порт 587 (STARTTLS) используется по умолчанию.
  • username / password — учетные данные SMTP.
  • fromAddress / fromName — идентификатор отправителя для исходящих писем.
  • tlsSkipVerify — пропустить проверку TLS-сертификата (для самоподписанных сертификатов).
  • smtpsMode — Прямой TLS (SMTPS, порт 465).

Конфигурация LiveKit

Расположение: server/config/livekit.yaml (разработка) или /etc/bedrud/livekit.yaml (production)

port: 7880                      # HTTP/WebSocket порт LiveKit
 
rtc:
  port_range_start: 50000       # Начало диапазона UDP-портов
  port_range_end: 60000         # Конец диапазона UDP-портов
  use_external_ip: true         # Использовать внешний IP для RTC
 
turn:
  enabled: true
  domain: "localhost"
  tls_port: 5349
  udp_port: 3478
 
keys:
  devkey: "devsecret"           # Должно совпадать с конфигурацией сервера
 
logging:
  level: info
 
room:
  auto_create: true              # Автосоздание комнат при подключении участников
  empty_timeout: 60              # Секунды до удаления пустой комнаты
  departure_timeout: 60          # Секунды хранения комнаты после ухода всех участников
  max_participants: 20           # Максимум участников в комнате (0 = без ограничений)
  enable_remote_unmute: true     # Разрешить серверное снятие мута у участников

Значения keys в livekit.yaml должны совпадать с livekit.apiKey и livekit.apiSecret в файле config.yaml сервера.

Диапазон портов RTC

LiveKit использует UDP-порты для медиапотоков. Диапазон по умолчанию 50000-60000 подходит для большинства конфигураций. Если сервер находится за файрволом, убедитесь, что эти порты открыты.

См. WebRTC-подключение для архитектуры и устранения неполадок.

Сервер TURN

Встроенный сервер TURN ретранслирует медиа для клиентов за строгими NAT или корпоративными файрволами. Он включён по умолчанию на портах 3478 (UDP) и 5349 (TLS).

TURN - это ретрансляция последнего рубежа - большинство клиентов (~80%) подключаются напрямую через UDP и никогда его не используют. Когда TURN активируется, сервер несёт всю нагрузку ретранслируемого медиатрафика.

Требование TLS: TURN/TLS (порт 5349) требует действительный TLS-сертификат. Для production установите turn.tls_port: 443 и укажите cert_file/key_file для вашего сертификата, либо разместите Layer 4 балансировщик нагрузки спереди с external_tls: true.

См. Руководство по серверу TURN для архитектуры, деталей конфигурации, расчёта пропускной способности и устранения неполадок.

Webhook (обнаружение отключения)

Bedrud receives webhook events from LiveKit to detect when participants disconnect unexpectedly (e.g., browser crash, network drop) and mark them as inactive in the database.

Endpoint: POST /api/livekit/webhook

Authentication: Uses LiveKit JWT signing with the same apiKey/apiSecret. No separate secret needed.

Embedded LiveKit: When Bedrud manages its own LiveKit server (default), the webhook URL is auto-configured in the generated LiveKit YAML. No user action needed.

External LiveKit (Cloud or self-hosted with external: true): Manually configure the webhook URL in your LiveKit dashboard:

https://<your-domain>/api/livekit/webhook

Events handled:

EventAction
participant_disconnectedMarks participant as inactive in room_participants
room_finishedMarks all participants + room as inactive

If apiKey is left empty in config, a random keypair is generated at startup. The embedded LiveKit server and webhook handler both use the same generated key — no manual configuration needed.

Настройки комнат

Секция room: управляет поведением комнат конференций:

  • auto_create - Автоматически создавать комнаты при подключении участников (по умолчанию: true)
  • empty_timeout - Секунды до удаления комнаты, в которую никто не подключился (по умолчанию: 60)
  • departure_timeout - Секунды хранения комнаты активной после ухода всех участников (по умолчанию: 60)
  • max_participants - Максимум участников в комнате. Установите 0 для снятия ограничений (по умолчанию: 20)
  • enable_remote_unmute - Разрешить серверное управление мутом участников (по умолчанию: true)

Настройка для различных сценариев:

  • Командные совещания: max_participants: 10-20
  • Большие вебинары: max_participants: 100 (или 0 без ограничений)
  • Серверы с ограниченными ресурсами: Уменьшите max_participants для снижения нагрузки на CPU/память

Переменные окружения

Значения конфигурации можно переопределить через переменные окружения. Именование следует соглашению префиксов по секциям:

Для развёртывания в Docker см. Руководство по Docker.

export SERVER_PORT=8090
export DB_PATH=/var/lib/bedrud/bedrud.db
export JWT_SECRET=production-secret
export LIVEKIT_HOST=http://localhost:8090/livekit
export LIVEKIT_API_KEY=prodkey
export LIVEKIT_API_SECRET=prodsecret

Полная справка по переменным окружения

ПеременнаяПуть в YAMLОписание
SERVER_PORTserver.portHTTP-порт прослушивания
SERVER_ENABLE_TLSserver.enableTLSВключить HTTPS (true/false)
SERVER_CERT_FILEserver.certFileПуть к TLS-сертификату
SERVER_KEY_FILEserver.keyFileПуть к закрытому ключу TLS
SERVER_DOMAINserver.domainИмя домена
SERVER_EMAILserver.emailEmail для Let’s Encrypt
SERVER_USE_ACMEserver.useACMEВключить автоматический Let’s Encrypt (true/false)
SERVER_TRUSTED_PROXIESserver.trustedProxiesIP доверенных прокси через запятую
SERVER_PROXY_HEADERserver.proxyHeaderЗаголовок для определения IP клиента (например, X-Forwarded-For)
DB_HOSTdatabase.hostХост базы данных (PostgreSQL)
DB_PORTdatabase.portПорт базы данных
DB_USERdatabase.userПользователь базы данных
DB_PASSWORDdatabase.passwordПароль базы данных
DB_NAMEdatabase.dbnameИмя базы данных
DB_TYPEdatabase.typesqlite или postgres
DB_PATHdatabase.pathПуть к файлу SQLite или строка подключения PostgreSQL
LIVEKIT_HOSTlivekit.hostВнешний URL LiveKit
LIVEKIT_INTERNAL_HOSTlivekit.internalHostВнутренний URL LiveKit
LIVEKIT_API_KEYlivekit.apiKeyAPI-ключ LiveKit (auto-generated as gen-<32hex> if empty)
LIVEKIT_API_SECRETlivekit.apiSecretAPI-секрет LiveKit (64-char hex auto-generated if empty)
JWT_SECRETauth.jwtSecretСекрет для подписи JWT-токенов
AUTH_FRONTEND_URLauth.frontendURLURL фронтенда для редиректов OAuth
AUTH_PASSKEY_CHALLENGE_TTLauth.passkeyChallengeTTLСрок действия Passkey-вызова в минутах
CORS_ALLOWED_ORIGINScors.allowedOriginsРазрешённые источники через запятую
CORS_ALLOWED_HEADERScors.allowedHeadersРазрешённые заголовки запросов
CORS_ALLOWED_METHODScors.allowedMethodsРазрешённые HTTP-методы
CORS_ALLOW_CREDENTIALScors.allowCredentialsРазрешить учётные данные (true/false)
CORS_EXPOSE_HEADERScors.exposeHeadersЗаголовки, доступные браузеру
CORS_MAX_AGEcors.maxAgeВремя кэширования preflight-запросов в секундах
RATELIMIT_AUTH_MAXrateLimit.authMaxRequestsМакс. запросов аутентификации за окно
RATELIMIT_AUTH_WINDOWrateLimit.authWindowSecsОкно ограничения аутентификации (сек)
RATELIMIT_GUEST_MAXrateLimit.guestMaxRequestsМакс. запросов гостевого входа за окно
RATELIMIT_GUEST_WINDOWrateLimit.guestWindowSecsОкно ограничения гостевого входа (сек)
LIVEKIT_CONFIG_PATHlivekit.configPathPath to external LiveKit YAML config
LIVEKIT_NODE_IPlivekit.nodeIPExplicit node IP for embedded LiveKit RTC (disables STUN)
SERVER_CERT_ALGORITHMserver.certAlgorithmKey algorithm for cert generation: ed25519, ecdsa256, rsa2048, rsa4096
SERVER_MAX_PARTICIPANTS_LIMITserver.maxParticipantsLimitHard ceiling for room capacity (default 1000)
SERVER_MAX_ROOMS_PER_USERserver.maxRoomsPerUserMax active rooms per user (default 100, 0 = unlimited)
CHAT_MAX_UPLOAD_BYTES_PER_USERchat.maxUploadBytesPerUserPer-user upload quota in bytes (default 524288000, 0 = unlimited)
CHAT_GLOBAL_DISK_THRESHOLD_BYTESchat.globalDiskThresholdBytesGlobal upload storage ceiling in bytes (default 0 = unlimited)
CHAT_MAX_MESSAGE_COUNTchat.maxMessageCountMax chat messages kept per room (default 10000, 0 = unlimited)
CHAT_MESSAGE_TTL_HOURSchat.messageTTLHoursMax age of chat messages in hours (default 2160 = 90 days, 0 = forever)
QUEUE_POLL_INTERVALqueue.pollIntervalJob poll interval in ms (default 500)
QUEUE_MAX_ATTEMPTSqueue.maxAttemptsMax job retries before marking failed (default 3)
QUEUE_CONCURRENCYqueue.concurrencyWorker goroutine count (default 1)
EMAIL_SMTP_HOSTemail.smtpHostSMTP server hostname
EMAIL_SMTP_PORTemail.smtpPortSMTP server port (default 587)
EMAIL_USERNAMEemail.usernameSMTP username
EMAIL_PASSWORDemail.passwordSMTP password
EMAIL_FROM_ADDRESSemail.fromAddressFrom email address
EMAIL_FROM_NAMEemail.fromNameFrom display name (default “Bedrud”)
EMAIL_TLS_SKIP_VERIFYemail.tlsSkipVerifySkip TLS certificate validation for self-signed SMTP certs
EMAIL_SMTPS_MODEemail.smtpsModeEnable direct TLS (SMTPS) mode for port 465

Чек-лист для production

  • Измените jwtSecret и sessionSecret на надёжные случайные значения
  • Установите logger.level в info или warn
  • Настройте TLS (через установщик или обратный прокси)
  • Установите cors.allowedOrigins на ваш production-домен
  • Настройте провайдеры OAuth при необходимости
  • Откройте диапазон портов RTC LiveKit в файрволе
  • Настройте ротацию логов для /var/log/bedrud/

Полная инструкция по настройке production см. в Руководстве по развёртыванию.