Skip to content

Configuration reference

Audited against b67fdde3. The examples below show embedded defaults, not a recommended public deployment. Configure only the keys you need; never edit the embedded defaults.yaml in an installed server.

Location and precedence

The home directory is selected by RELAY_HOME, then legacy THELOUNGE_HOME, then ~/.relay. Without an explicit override, standalone Relay falls back to ~/.thelounge when only the legacy location contains config.yaml. The container normally uses /var/opt/relay; see installation for the legacy entrypoint caveat.

Configuration is merged in this order (last wins):

  1. Embedded defaults.
  2. <RELAY_HOME>/config.yaml.
  3. <RELAY_HOME>/admin-overrides.json, written by Administration.
  4. Repeated CLI -c key.path=value arguments.

Objects merge recursively; arrays replace the entire earlier array. Unknown top-level keys and type mismatches produce warnings. Use YAML booleans/numbers with the types shown below. A YAML edit can appear ineffective because an administrator override still wins. Inspect both files; stop Relay and back up the override file before manually removing conflicting entries. CLI overrides win at startup; live administrator changes may update the running value, and the CLI value returns on the next start.

relay start creates a starter YAML file and users/ if absent. Protect the data directory and secret-bearing YAML/JSON. Environment variables inside YAML are not a general interpolation mechanism: supply real values through a protected configuration-generation process.

Applying changes

File edits and CLI changes require a process restart. Administration writes supported settings to admin-overrides.json; it can persist all administrator-editable values, so later YAML edits may be masked even for controls you did not just change.

Change Application
Listener, TLS, proxy trust, IRC bind, public mode, file-only settings Restart server
Structured backend and PostgreSQL connection/pool Restart server to reopen providers
Registration and required local MFA Live server policy; weaker remembered sessions must authenticate again on reconnect
Client-visible media, theme and interface capabilities Use Apply Changes when offered to reload the browser; it is not a process restart
Upload enablement UI marks this as requiring restart; restart and verify upload route/capability
YAML retention policy or upload expiration Restart to initialize cleaners with the new policy

Restart Server exits with status 0 and requires a supervisor that restarts successful exits. See Server and users. Confirm a saved value after refreshing Administration and after a restart, especially if the service supplies -c flags.

Server and access

The default web listener binds all interfaces on port 9000; bind selects the local address for outbound IRC/ident, not the web listener. maxHistory is an in-memory channel message count (−1 means unlimited), separate from database retention. registrationMaxUsers: 0 means no self-registration cap. For trusted proxies and TLS paths, see HTTPS and reverse proxies.

public: false
host: null
port: 9000
bind: null
reverseProxy: false
trustedProxies:
- 127.0.0.0/8
- ::1/128
https:
  enable: false
  key: ''
  certificate: ''
  ca: ''
allowRegistration: false
registrationMaxUsers: 0
requireSecondFactor: false
networkGroups: true
maxHistory: 10000

Public resource limits

These budgets apply in public mode: counts for sessions/connections/channels, attempts per minute, events per second, byte limits for WebSocket messages and input, and a line count for input. Every value must be positive; per-IP limits cannot exceed global limits. Invalid or excessive budgets fail startup. Public mode also requires a valid default IRC host/port and rejects SASL EXTERNAL.

publicLimits:
  maxSessions: 128
  maxSessionsPerIp: 4
  maxIrcConnections: 64
  maxIrcConnectionsPerIp: 2
  ircAttemptsPerMinute: 6
  ircAttemptBurst: 2
  eventsPerSecond: 20
  eventBurst: 40
  maxWebSocketMessageBytes: 65536
  maxInputBytes: 8192
  maxInputLines: 16
  maxChannels: 32

IRC defaults and gateways

defaults seeds new connections; it does not rewrite saved private networks. Ports are TCP port numbers, join is a channel list, and % in the nickname becomes a random digit. Server password and SASL password are distinct. Public mode always locks transport settings; lockNetwork enables that boundary in private mode. webirc maps hosts to passwords or {password, hostnamePrefix} objects. oidentd is an output-file path; useHexIp enables IP-derived usernames. Coordinate gateway values with the IRC operator.

defaults:
  name: OUCHnet
  host: irc.ouch.chat
  port: 6697
  password: ''
  tls: true
  rejectUnauthorized: true
  nick: relay%%
  username: relay
  realname: ''
  join: '#relay'
  leaveMessage: ''
  sasl: ''
  saslAccount: ''
  saslPassword: ''
lockNetwork: false
leaveMessage: Relay - https://git.thc420.dev/ouch/relay
useHexIp: false
webirc: null
identd:
  enable: false
  port: 113
oidentd: null

History and retention

Use one structured primary backend (sqlite or postgres) plus optional text. Logging also requires the account logging flag. Connection pool values are counts; lifetime is minutes. Retention age is days, with statusOnly or everything deletion policy. See Storage and retention.

messageStorage:
- sqlite
- text
postgres:
  connectionString: ''
  maxOpenConns: 10
  maxIdleConns: 5
  connMaxLifetimeMinutes: 60
storagePolicy:
  enabled: false
  maxAgeDays: 7
  deletionPolicy: statusOnly

Media, files and redirects

Image/search/upload/avatar/DCC size limits are KiB (the UI labels these KB); prefetchTimeout is milliseconds. Expiration is hours. Upload file size below one means unlimited. Upload/share expiration below one disables expiration; short links use zero for no expiry. DCC requires positive size, concurrency, expiration and free-space budgets before enabling: minFreeSpace is MiB. shortLink.minLength and codeLength are character counts. fileUpload.baseUrl and shortLink.baseUrl are optional URL strings (empty means the normal origin), omitted from the defaults below. Keep internal-address prefetch off unless you deliberately need it. See Media and files.

prefetch: false
disableMediaPreview: false
inlineVideoEmbeds: false
prefetchStorage: false
prefetchMaxImageSize: 2048
prefetchMaxSearchSize: 50
prefetchTimeout: 5000
prefetchAllowInternalAddresses: false
fileUpload:
  enable: false
  maxFileSize: 10240
  expirationTime: 24
avatars:
  enable: false
  maxFileSize: 2048
dcc:
  enable: false
  randomizeDownloadUrl: true
  listenAddress: 0.0.0.0:0
  advertiseAddress: ''
  maxFileSize: 0
  maxConcurrent: 0
  expirationTime: 0
  minFreeSpace: 0
shortLink:
  enable: false
  minLength: 100
  expirationTime: 720
  path: /s/
  codeLength: 6

Authentication providers

webauthn.rpId is a hostname, not a URL; an empty value derives it from the request. Use a stable HTTPS origin for keys. SMTP secure: true selects implicit TLS; false upgrades with STARTTLS when the SMTP server offers it. Scope is a space-separated string; username claim can be a nested claim path. See Authentication before enabling providers.

webauthn:
  rpId: ''
  rpName: Relay
smtp:
  enable: false
  host: localhost
  port: 587
  secure: false
  user: ''
  password: ''
  from: Relay <noreply@example.com>
oidc:
  enable: false
  issuer: ''
  clientId: ''
  clientSecret: ''
  scope: openid profile email
  usernameClaim: preferred_username

Appearance and integrations

themeColor is an optional browser theme-color string (empty by default). Logo URLs fall back to built-in branding when empty. Jitsi and KLIPY are disabled until configured; partyline is an instance-local synthetic network. Debug raw IRC output can include sensitive content. See Integrations and branding.

theme: terminal
branding:
  logoEnabled: true
  logoUrl: ''
  logoInvertedUrl: ''
jitsi:
  enable: false
  serverUrl: https://ji.zrgw.dev
klipy:
  enable: false
  apiKey: ''
partyline:
  enable: false
  networkName: Relay
  name: '#partyline'
stats:
  commandEnable: true
  commandTemplate: '$nick IRC stats: Networks - $usernetworks || Channels - $userchannels
    || Total messages logged - $messageslogged || Storage - $storagebytes || Database
    - $databasebytes || Uptime - $uptime || Relay - $relayversion || OS - $os || Go
    - $go'
debug:
  ircFramework: false
  raw: false

desktop is an internal native-client capability marker; YAML and CLI overrides cannot enable it. Socket.IO transports is not supported by the Go backend, which uses /ws.