Bedrud uses YAML configuration files for both the main server and the embedded LiveKit media server.

See also: Quick Start | Installation | Deployment Guide | Docker Guide

Minimum Production Config

Default config works for development. For production, change these values in /etc/bedrud/config.yaml:

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

Restart after changes:

sudo systemctl restart bedrud livekit

Full reference below.


Server Configuration

Location: server/config.yaml (development) or /etc/bedrud/config.yaml (production)

Full Reference

server:
  port: 8090                    # HTTP port
  host: "localhost"             # Bind address
 
database:
  type: "sqlite"                # Database type: sqlite or postgres
  path: "data.db"               # SQLite database file path
 
logger:
  level: "debug"                # Log level: debug, info, warn, error
  outputPath: ""                # Log file path (empty = stdout)
 
livekit:
  host: "http://localhost:8090/livekit"  # External LiveKit URL
  internalHost: "http://127.0.0.1:7880"  # Internal LiveKit URL
  apiKey: "devkey"              # LiveKit API key
  apiSecret: "devsecret"        # LiveKit API secret
 
auth:
  jwtSecret: "your-jwt-secret"           # Secret for signing JWT tokens
  tokenDuration: 24                       # Token expiration in hours
  sessionSecret: "your-session-secret"    # Secret for session cookies
  frontendURL: "http://localhost:8090"    # Frontend URL (for OAuth redirects)
 
  # OAuth providers (optional)
  google:
    clientId: ""
    clientSecret: ""
  github:
    clientId: ""
    clientSecret: ""
  twitter:
    clientKey: ""
    clientSecret: ""
 
cors:
  allowedOrigins: "http://localhost:8090,http://localhost:3000"  # Comma-separated
  allowedHeaders: "Origin, Content-Type, Accept, Authorization"
  allowedMethods: "GET, POST, PUT, DELETE, OPTIONS"
  allowCredentials: true

Key Settings

Database

By default, Bedrud uses SQLite with a file at the configured path. For production with higher concurrency, switch to PostgreSQL by providing a connection string instead. When using PostgreSQL, the path field holds a connection string, not a file path:

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

Authentication

The jwtSecret is used to sign access and refresh tokens. Change this from the default in production.

OAuth providers are optional. If you don’t configure them, social login buttons won’t appear in the UI. Each provider requires registering an OAuth app with the respective service and providing the client ID and secret.

CORS

The allowedOrigins string (comma-separated) must include the URL where your frontend is served. In development, this is http://localhost:3000. In production, set it to your domain (e.g., https://meet.example.com).


LiveKit Configuration

Location: server/config/livekit.yaml (development) or /etc/bedrud/livekit.yaml (production)

port: 7880                      # LiveKit HTTP/WebSocket port
 
rtc:
  port_range_start: 50000       # UDP port range start
  port_range_end: 60000         # UDP port range end
  use_external_ip: true         # Use external IP for RTC
 
turn:
  enabled: true
  domain: "localhost"
  tls_port: 5349
  udp_port: 3478
 
keys:
  devkey: "devsecret"           # Must match server config
 
logging:
  level: info
 
room:
  auto_create: true              # Auto-create rooms when participants join
  empty_timeout: 60              # Seconds before deleting empty room
  departure_timeout: 60          # Seconds to keep room after all participants leave
  max_participants: 20           # Max participants per room (0 = unlimited)
  enable_remote_unmute: true     # Allow server-side unmute of participants

The keys in livekit.yaml must match the livekit.apiKey and livekit.apiSecret in the server’s config.yaml.

RTC Port Range

LiveKit uses UDP ports for media streams. The default range 50000-60000 works for most setups. If running behind a firewall, ensure these ports are open.

See WebRTC Connectivity for architecture and troubleshooting.

TURN Server

The embedded TURN server relays media for clients behind restrictive NATs or corporate firewalls. It’s enabled by default on ports 3478 (UDP) and 5349 (TLS).

TURN is a last-resort relay - most clients (~80%) connect directly via UDP and never use it. When TURN activates, the server carries all relayed media bandwidth.

TLS requirement: TURN/TLS (port 5349) needs a valid TLS certificate. For production, set turn.tls_port: 443 and point cert_file/key_file to your certificate, or place a Layer 4 load balancer in front with external_tls: true.

See the TURN Server Guide for architecture, config details, bandwidth calculations, and troubleshooting.

Room Settings

The room: section controls meeting room behavior:

  • auto_create - Automatically create rooms when participants join (default: true)
  • empty_timeout - Seconds before deleting a room that was never joined (default: 60)
  • departure_timeout - Seconds to keep room active after all participants leave (default: 60)
  • max_participants - Maximum participants per room. Set to 0 for no limit (default: 20)
  • enable_remote_unmute - Allow server-side muting/unmuting of participants (default: true)

Tuning for capacity:

  • Small team meetings: max_participants: 10-20
  • Large webinars: max_participants: 100 (or 0 for unlimited)
  • Resource-constrained servers: Lower max_participants to reduce CPU/memory usage

Environment Variables

Configuration values can be overridden with environment variables. The naming follows a per-section prefix convention:

For Docker deployments, see the Docker Guide.

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

Full Environment Variable Reference

Env VarYAML PathDescription
SERVER_PORTserver.portHTTP listening port
SERVER_ENABLE_TLSserver.enableTLSEnable HTTPS (true/false)
SERVER_CERT_FILEserver.certFilePath to TLS certificate
SERVER_KEY_FILEserver.keyFilePath to TLS private key
SERVER_DOMAINserver.domainDomain name
SERVER_EMAILserver.emailEmail for Let’s Encrypt
SERVER_USE_ACMEserver.useACMEEnable automatic Let’s Encrypt (true/false)
SERVER_TRUSTED_PROXIESserver.trustedProxiesComma-separated trusted proxy IPs
SERVER_PROXY_HEADERserver.proxyHeaderHeader to read client IP from (e.g., X-Forwarded-For)
DB_HOSTdatabase.hostDatabase host (PostgreSQL)
DB_PORTdatabase.portDatabase port
DB_USERdatabase.userDatabase user
DB_PASSWORDdatabase.passwordDatabase password
DB_NAMEdatabase.dbnameDatabase name
DB_TYPEdatabase.typesqlite or postgres
DB_PATHdatabase.pathSQLite file path or PostgreSQL connection string
LIVEKIT_HOSTlivekit.hostExternal LiveKit URL
LIVEKIT_INTERNAL_HOSTlivekit.internalHostInternal LiveKit URL
LIVEKIT_API_KEYlivekit.apiKeyLiveKit API key
LIVEKIT_API_SECRETlivekit.apiSecretLiveKit API secret
JWT_SECRETauth.jwtSecretSecret for signing JWT tokens
AUTH_FRONTEND_URLauth.frontendURLFrontend URL for OAuth redirects
CORS_ALLOWED_ORIGINScors.allowedOriginsComma-separated allowed origins
CORS_ALLOWED_HEADERScors.allowedHeadersAllowed request headers
CORS_ALLOWED_METHODScors.allowedMethodsAllowed HTTP methods
CORS_ALLOW_CREDENTIALScors.allowCredentialsAllow credentials (true/false)
CORS_EXPOSE_HEADERScors.exposeHeadersHeaders exposed to the browser
CORS_MAX_AGEcors.maxAgePreflight cache duration in seconds

Production Checklist

  • Change jwtSecret and sessionSecret to strong random values
  • Set logger.level to info or warn
  • Configure TLS (via installer or reverse proxy)
  • Set cors.allowedOrigins to your production domain
  • Configure OAuth providers if needed
  • Open LiveKit RTC port range in your firewall
  • Set up log rotation for /var/log/bedrud/

For complete production setup, see the Deployment Guide.