Matrix is an open network for secure, decentralized communication. Run your own homeserver and you get a chat identity on your own domain that can federate with every other Matrix server in the world. Conduit is the lightweight choice for this: a single Rust binary with an embedded RocksDB database, designed for easy setup and low resource use. It is efficient enough to run on hardware as small as a Raspberry Pi, which makes it a great fit for a modest RamNode VPS serving a family, a team, or a small community.
This guide deploys Conduit on Ubuntu 24.04 LTS using the prebuilt binary, a systemd service, and a reverse proxy with the federation delegation that lets the wider Matrix network find you.
A quick word on the Conduit ecosystem
Conduit is the original project by Timo Köster, hosted at gitlab.com/famedly/conduit. A family of forks has grown around it, including Continuwuity and Tuwunel, which add features and performance work. They share a code lineage, and security fixes often land across all of them at once. This guide targets upstream Conduit. Whichever you run, the single most important operational habit is to stay current: in early 2026 the Conduit based servers shipped coordinated critical security releases, so subscribe to the project's release feed and update promptly.
Prerequisites
- A RamNode VPS running Ubuntu 24.04 LTS. 1 to 2 GB RAM handles a small server comfortably; federation with busy rooms benefits from more.
- Root or sudo access.
- A domain you control. Two names matter:
- The server name, the part after the colon in user IDs, for example
example.com. This is what users type, as in@alice:example.com. - The delegated host that actually runs Conduit, for example
matrix.example.com.
- The server name, the part after the colon in user IDs, for example
- DNS A records for both names pointing at the VPS, and ports 80 and 443 open.
The split between server name and delegated host is the standard, clean way to run Matrix: identities read nicely as @you:example.com while the service lives on a subdomain.
Step 1: Create a service user and directories
sudo useradd -r -m -d /var/lib/conduit -s /usr/sbin/nologin conduit
sudo mkdir -p /etc/conduitStep 2: Install the Conduit binary
Download the latest release binary for x86_64 and install it:
cd /tmp
wget -O conduit https://gitlab.com/famedly/conduit/-/releases/permalink/latest/downloads/conduit-linux-x86_64
sudo install -m 755 conduit /usr/local/bin/conduit
conduit --versionIf your VPS is ARM based, download the matching ARM artifact from the releases page instead. If a prebuilt binary is unavailable for your platform, you can build from source with Rust (cargo build --release), but the binary is the simplest path.
Step 3: Write the configuration
Create /etc/conduit/conduit.toml:
[global]
# The public server name in user IDs (@user:example.com)
server_name = "example.com"
# Embedded database
database_path = "/var/lib/conduit"
database_backend = "rocksdb"
# Conduit listens locally; the reverse proxy terminates TLS
address = "127.0.0.1"
port = 6167
max_request_size = 20_000_000 # 20 MB upload cap
# Lock down registration: open it briefly only when adding users,
# or use a token (see below)
allow_registration = false
allow_federation = true
allow_check_for_updates = true
# Trusted key server for federation key lookups
trusted_servers = ["matrix.org"]Set ownership so the service user owns its database:
sudo chown -R conduit:conduit /var/lib/conduit
sudo chown conduit:conduit /etc/conduit/conduit.toml
sudo chmod 600 /etc/conduit/conduit.tomlControlling registration with a token
Leaving registration fully open invites spam accounts. The cleaner pattern is a registration token: keep allow_registration off for the public, and hand a token to people you actually want to onboard. Add to the [global] section:
allow_registration = true
registration_token = "choose-a-long-random-string"Only people who enter that token in their client can register. Rotate or remove it when you are done onboarding.
Step 4: Create the systemd service
Create /etc/systemd/system/conduit.service:
[Unit]
Description=Conduit Matrix Homeserver
After=network.target
[Service]
User=conduit
Group=conduit
Environment="CONDUIT_CONFIG=/etc/conduit/conduit.toml"
ExecStart=/usr/local/bin/conduit
Restart=always
RestartSec=5
# Hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/conduit
PrivateTmp=true
[Install]
WantedBy=multi-user.targetEnable and start it:
sudo systemctl daemon-reload
sudo systemctl enable --now conduit
sudo systemctl status conduitConfirm it is listening locally:
curl http://127.0.0.1:6167/_matrix/client/versionsA JSON response listing supported client API versions means Conduit is alive.
Step 5: Reverse proxy, TLS, and federation delegation
This is the step that makes your server reachable and federating. Caddy makes it short. Install it:
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update && sudo apt install -y caddyTwo things have to be served:
- The Matrix API itself, proxied to Conduit, on the delegated host
matrix.example.com. - Two well known JSON files on the server name
example.comthat tell other servers and clients where to find your homeserver.
Set /etc/caddy/Caddyfile:
# The delegated host that actually runs Conduit
matrix.example.com {
reverse_proxy /_matrix/* 127.0.0.1:6167
}
# The server name: serve delegation well-known files
example.com {
# Server-to-server delegation (federation)
handle /.well-known/matrix/server {
header Content-Type application/json
header Access-Control-Allow-Origin *
respond `{"m.server": "matrix.example.com:443"}`
}
# Client discovery
handle /.well-known/matrix/client {
header Content-Type application/json
header Access-Control-Allow-Origin *
respond `{"m.homeserver": {"base_url": "https://matrix.example.com"}}`
}
# your normal website can be served here too
}Reload Caddy:
sudo systemctl restart caddyCaddy provisions Let's Encrypt certificates for both names automatically. The m.server delegation tells other homeservers to reach you at matrix.example.com:443, while the m.client file tells clients which base URL to log in against.
Step 6: Firewall
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enableConduit's port 6167 stays internal. Matrix federation runs over the standard HTTPS port 443 thanks to the delegation, so there is no extra federation port to open.
Step 7: Create your first user and verify
Open registration briefly or use your token, then register from a Matrix client such as Element. Point the client at the homeserver https://matrix.example.com (or just example.com, which the client well known file will redirect), and create your account.
Verify federation works using the public tester:
curl "https://federationtester.matrix.org/api/report?server_name=example.com"Look for "FederationOK": true in the response. Also sanity check your delegation files directly:
curl https://example.com/.well-known/matrix/server
curl https://example.com/.well-known/matrix/clientOnce federation is green, try joining a public room from another server, for example #matrix:matrix.org, to confirm end to end connectivity.
Performance tuning
For a busier server, add to the [global] section:
# Raise concurrency on busy servers
max_concurrent_requests = 200
# Cache sizing (bytes); 1 GB shown
cache_capacity = 1073741824Conduit's single binary, embedded database design means there are few moving parts to tune. Most small servers never need to touch these.
Backups
Stop Conduit first so the RocksDB database is consistent, copy it, then restart:
sudo systemctl stop conduit
sudo cp -a /var/lib/conduit /var/backups/conduit-$(date +%F)
sudo systemctl start conduitFor minimal downtime on a larger server, use a filesystem snapshot instead. Ship backups off the VPS and automate with cron.
Updating
Conduit security fixes can be urgent, so make updates easy:
cd /tmp
wget -O conduit https://gitlab.com/famedly/conduit/-/releases/permalink/latest/downloads/conduit-linux-x86_64
sudo systemctl stop conduit
sudo install -m 755 conduit /usr/local/bin/conduit
sudo systemctl start conduitWatch the release feed and apply security releases without delay.
Troubleshooting
- FederationOK is false. Your
.well-known/matrix/serverfile is missing, malformed, or not served over valid TLS. Re-fetch it with curl and confirm it returns exactly{"m.server": "matrix.example.com:443"}with a JSON content type. - Clients cannot find the homeserver. The
m.clientwell known file is wrong or not reachable on the bare server name. Check it directly. - Conduit will not start. Check
journalctl -u conduit. A common cause is a permissions problem on/var/lib/conduit; confirm theconduituser owns it. - Registration is refused. That is expected with
allow_registration = false. Enable it temporarily or supply the registration token in your client.
Wrap up
You now run your own federating Matrix homeserver on a RamNode VPS: a single lightweight Conduit binary with an embedded database, TLS and federation delegation handled by Caddy, registration locked behind a token, and the database under regular backup. Your community gets @name:example.com identities and can talk to anyone, anywhere on the Matrix network, on infrastructure you fully control. Keep it patched and it will quietly run for a long time.
