Configuration

Conduit is configured using a TOML file. The configuration file is loaded from the path specified by the CONDUIT_CONFIG environment variable.

Note: The configuration file is required to run Conduit. If the CONDUIT_CONFIG environment variable is not set, Conduit will exit with an error.

Note: If you update the configuration file, you must restart Conduit for the changes to take effect

Note: You can also configure Conduit by using CONDUIT_{field_name} environment variables. To set values inside a table, use CONDUIT_{table_name}_{field_name}. Example: CONDUIT_WELL_KNOWN_CLIENT="https://matrix.example.org"

Conduit's configuration file is divided into the following sections:

Global

The global section contains the following fields:

Note: The * symbol indicates that the field is required, and the values in parentheses are the possible values

FieldTypeDescriptionDefault
addressstringThe address to bind to"127.0.0.1"
portintegerThe port to bind to8000
tlstableSee the TLS configurationN/A
server_name*stringThe server nameN/A
database_backend*stringThe database backend to use ("rocksdb" recommended, "sqlite")N/A
database_path*stringThe path to the database file/dirN/A
db_cache_capacity_mbfloatThe cache capacity, in MB300.0
enable_lightning_boltbooleanAdd ⚡️ emoji to end of user's display nametrue
allow_check_for_updatesbooleanAllow Conduit to check for updatestrue
conduit_cache_capacity_modifierfloatThe value to multiply the default cache capacity by1.0
rocksdb_max_open_filesintegerThe maximum number of open files1000
pdu_cache_capacityintegerThe maximum number of Persisted Data Units (PDUs) to cache150000
cleanup_second_intervalintegerHow often conduit should clean up the database, in seconds60
max_request_sizeintegerThe maximum request size, in bytes20971520 (20 MiB)
max_concurrent_requestsintegerThe maximum number of concurrent requests100
max_fetch_prev_eventsintegerThe maximum number of previous events to fetch per request if conduit notices events are missing100
allow_registrationbooleanOpens your homeserver to public registrationfalse
registration_tokenstringThe token users need to have when registering to your homeserverN/A
allow_encryptionbooleanAllow users to enable encryption in their roomstrue
allow_federationbooleanAllow federation with other serverstrue
allow_room_creationbooleanAllow users to create roomstrue
allow_unstable_room_versionsbooleanAllow users to create and join rooms with unstable versionstrue
default_room_versionstringThe default room version ("6"-"10")"10"
allow_jaegerbooleanAllow Jaeger tracingfalse
tracing_flamebooleanEnable flame tracingfalse
proxytableSee the Proxy configurationN/A
jwt_secretstringThe secret used in the JWT to enable JWT login without it a 400 error will be returnedN/A
trusted_serversarrayThe list of trusted servers to gather public keys of offline servers["matrix.org"]
logstringThe log verbosity to use"warn"
turn_usernamestringThe TURN username""
turn_passwordstringThe TURN password""
turn_urisarrayThe TURN URIs[]
turn_secretstringThe TURN secret""
turn_ttlintegerThe TURN TTL in seconds86400
mediatableSee the media configurationSee the media configuration
emergency_passwordstringSet a password to login as the conduit user in case of emergencyN/A
well_knowntableUsed for delegationSee delegation

Media

The media table is used to configure how media is stored and where. Currently, there is only one available backend, that being filesystem. The backend can be set using the backend field. Example:

[global.media]
backend = "filesystem" # the default backend

Filesystem backend

The filesystem backend has the following fields:

  • path: The base directory where all the media files will be stored (defaults to ${database_path}/media)
  • directory_structure: This is a table, used to configure how files are to be distributed within the media directory. It has the following fields:
    • depth: The number sub-directories that should be created for files (default: 2)
    • length: How long the name of these sub-directories should be (default: 2) For example, a file may regularly have the name 98ea6e4f216f2fb4b69fff9b3a44842c38686ca685f3f55dc48c5d3fb1107be4 (The SHA256 digest of the file's content). If depth and length were both set to 2, this file would be stored at ${path}/98/ea/6e4f216f2fb4b69fff9b3a44842c38686ca685f3f55dc48c5d3fb1107be4. If you want to instead have all media files in the base directory with no sub-directories, just set directory_structure to be empty, as follows:
    [global.media]
    backend = "filesystem"
    
    [global.media.directory_structure]
    
Example:
[global.media]
backend = "filesystem"
path = "/srv/matrix-media"

[global.media.directory_structure]
depth = 4
length = 2

Retention policies

Over time, the amount of media will keep growing, even if they were only accessed once. Retention policies allow for media files to automatically be deleted if they meet certain crietia, allowing disk space to be saved.

This can be configured via the retention field of the media config, which is an array with "scopes" specified

  • scope: specifies what type of media this policy applies to. If unset, all other scopes which you have not configured will use this as a default. Possible values: "local", "remote", "thumbnail"
  • accessed: the maximum amount of time since the media was last accessed, in the form specified by humantime::parse_duration (e.g. "240h", "1400min", "2months", etc.)
  • created: the maximum amount of time since the media was created after, in the same format as accessed above.
  • space: the maximum amount of space all of the media in this scope can occupy (if no scope is specified, this becomes the total for all media). If the creation/downloading of new media, will cause this to be exceeded, the last accessed media will be deleted repetitively until there is enough space for the new media. The format is specified by ByteSize (e.g. "10000MB", "15GiB", "1.5TB", etc.)

Media needs to meet all the specified requirements to be kept, otherwise, it will be deleted. This means that thumbnails have to meet both the "thumbnail", and either "local" or "remote" requirements in order to be kept.

If the media does not meet the accessed or created requirement, they will be deleted during a periodic cleanup, which happens every 1/10th of the period of the shortest retention time, with a maximum frequency of every minute, and a minimum of every 24 hours. For example, if I set my accessed time for all media to "2months", but override that to be "48h" for thumbnails, the cleanup will happen every 4.8 hours.

Example
# Total of 40GB for all media
[[global.media.retention]] # Notice the double "[]", due to this being a table item in an array
space = "40G"

# Delete remote media not accessed for 30 days, or older than 90 days
[[global.media.retention]]
scope = "remote"
accessed = "30d"
created = "90days" # you can mix and match between the long and short format

# Delete local media not accessed for 1 year
[[global.media.retention]]
scope = "local"
accessed = "1y"

# Only store 1GB of thumbnails
[[global.media.retention]]
scope = "thumbnail"
space = "1GB"

TLS

The tls table contains the following fields:

  • certs: The path to the public PEM certificate
  • key: The path to the PEM private key

Example

[global.tls]
certs = "/path/to/cert.pem"
key = "/path/to/key.pem"

Proxy

You can choose what requests conduit should proxy (if any). The proxy table contains the following fields

Global

The global option will proxy all outgoing requests. The global table contains the following fields:

  • url: The URL of the proxy server
Example
[global.proxy.global]
url = "https://example.com"

By domain

An array of tables that contain the following fields:

  • url: The URL of the proxy server
  • include: Domains that should be proxied (assumed to be ["*"] if unset)
  • exclude: Domains that should not be proxied (takes precedent over include)

Both include and exclude allow for glob pattern matching.

Example

In this example, all requests to domains ending in .onion and matrix.secretly-an-onion-domain.xyz will be proxied via socks://localhost:9050, except for domains ending in .myspecial.onion. You can add as many by_domain tables as you need.

[[global.proxy.by_domain]]
url = "socks5://localhost:9050"
include = ["*.onion", "matrix.secretly-an-onion-domain.xyz"]
exclude = ["*.clearnet.onion"]

Example

Note: The following example is a minimal configuration file. You should replace the values with your own.

[global]
# YOU NEED TO EDIT THIS
#server_name = "your.server.name"

database_backend = "rocksdb"
# This is the only directory where Conduit will save its data
database_path = "/var/lib/matrix-conduit/"

# The port Conduit will be running on. You need to set up a reverse proxy in
# your web server (e.g. apache or nginx), so all requests to /_matrix on port
# 443 and 8448 will be forwarded to the Conduit instance running on this port
# Docker users: Don't change this, you'll need to map an external port to this.
port = 6167

# Max size for uploads
max_request_size = 20_000_000 # in bytes

# Enables registration. If set to false, no users can register on this server.
allow_registration = true

# A static registration token that new users will have to provide when creating
# an account. YOU NEED TO EDIT THIS.
# - Insert a password that users will have to enter on registration
# - Start the line with '#' to remove the condition
registration_token = ""

allow_check_for_updates = true
allow_federation = true

# Enable the display name lightning bolt on registration.
enable_lightning_bolt = true

# Servers listed here will be used to gather public keys of other servers.
# Generally, copying this exactly should be enough. (Currently, Conduit doesn't
# support batched key requests, so this list should only contain Synapse
# servers.)
trusted_servers = ["matrix.org"]

#max_concurrent_requests = 100 # How many requests Conduit sends to other servers at the same time

# Controls the log verbosity. See also [here][0].
#
# [0]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives
#log = "..."

address = "127.0.0.1" # This makes sure Conduit can only be reached using the reverse proxy
#address = "0.0.0.0" # If Conduit is running in a container, make sure the reverse proxy (ie. Traefik) can reach it.

[global.well_known]
# Conduit handles the /.well-known/matrix/* endpoints, making both clients and servers try to access conduit with the host
# server_name and port 443 by default.
# If you want to override these defaults, uncomment and edit the following lines accordingly:
#server = your.server.name:443
#client = https://your.server.name