How to Self-Host Conduit with Docker Compose

What Is Conduit?

Conduit is a lightweight Matrix homeserver written in Rust. It implements the Matrix protocol with a fraction of the resources Synapse requires — running comfortably on 70-200 MB of RAM instead of 1-2+ GB. If you want a federated chat server that can run on a Raspberry Pi or a $5 VPS, Conduit is the answer. Official site.

Prerequisites

  • A Linux server (Ubuntu 22.04+ recommended)
  • Docker and Docker Compose installed (guide)
  • 1 GB of free disk space
  • 512 MB of RAM (minimum)
  • A domain name (required for Matrix federation)
  • Reverse proxy with SSL (guide)

Docker Compose Configuration

Create a docker-compose.yml file:

services:
  conduit:
    image: matrixconduit/matrix-conduit:v0.10.12
    container_name: conduit
    restart: unless-stopped
    ports:
      - "6167:6167"
    volumes:
      - conduit-data:/var/lib/matrix-conduit/
    environment:
      # Your homeserver domain — cannot change after first run
      CONDUIT_SERVER_NAME: "matrix.example.com"
      # RocksDB is faster and recommended over SQLite
      CONDUIT_DATABASE_BACKEND: "rocksdb"
      CONDUIT_DATABASE_PATH: "/var/lib/matrix-conduit/"
      # Internal port Conduit listens on
      CONDUIT_PORT: "6167"
      # Bind to all interfaces (required in Docker)
      CONDUIT_ADDRESS: "0.0.0.0"
      # Maximum upload size in bytes (20 MB)
      CONDUIT_MAX_REQUEST_SIZE: "20000000"
      # Disable open registration — create users via admin API
      CONDUIT_ALLOW_REGISTRATION: "false"
      # Enable federation with other Matrix servers
      CONDUIT_ALLOW_FEDERATION: "true"
      # Enable end-to-end encryption
      CONDUIT_ALLOW_ENCRYPTION: "true"
      # Trusted servers for federation key verification
      CONDUIT_TRUSTED_SERVERS: '["matrix.org"]'
      # Maximum concurrent outgoing federation requests
      CONDUIT_MAX_CONCURRENT_REQUESTS: "100"
      # Database cache size in MB — increase for better performance
      CONDUIT_DB_CACHE_CAPACITY_MB: "300"
      # Logging level: warn, info, debug, trace
      CONDUIT_LOG: "warn"

volumes:
  conduit-data:

Start the stack:

docker compose up -d

Initial Setup

1. Set Up .well-known Delegation

Matrix clients and other servers need to discover your homeserver. Create these files on your web server or reverse proxy:

/.well-known/matrix/server (federation discovery):

{
  "m.server": "matrix.example.com:443"
}

/.well-known/matrix/client (client discovery):

{
  "m.homeserver": {
    "base_url": "https://matrix.example.com"
  }
}

2. Create Your First User

With registration disabled, create users via the admin API:

# Register a user via the admin API
curl -X POST "http://localhost:6167/_matrix/client/r0/register" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "admin",
    "password": "your-strong-password-here",
    "auth": {
      "type": "m.login.dummy"
    }
  }'

Alternatively, temporarily set CONDUIT_ALLOW_REGISTRATION: "true", register through Element, then disable it again.

3. Connect with Element

Open Element Web or install the Element desktop/mobile app. On the login screen, click “Edit” next to the homeserver URL and enter https://matrix.example.com. Log in with the user you created.

Configuration

Registration Token

Instead of open registration, require a token:

environment:
  CONDUIT_ALLOW_REGISTRATION: "true"
  CONDUIT_REGISTRATION_TOKEN: "your-secret-token-here"

Users must provide this token during registration. Share it privately with people you want to invite.

Federation Controls

VariableDefaultPurpose
CONDUIT_ALLOW_FEDERATIONfalseEnable/disable federation
CONDUIT_TRUSTED_SERVERS["matrix.org"]Servers trusted for key verification
CONDUIT_MAX_CONCURRENT_REQUESTS100Outgoing federation request limit

Performance Tuning

VariableDefaultEffect
CONDUIT_DB_CACHE_CAPACITY_MB300RocksDB cache size — increase for more rooms
CONDUIT_MAX_REQUEST_SIZE20000000Upload limit in bytes
CONDUIT_LOGwarnSet to info for more detail

Reverse Proxy

Your reverse proxy must forward two paths to Conduit’s port 6167:

  • /_matrix/* — Matrix client and federation API
  • /.well-known/matrix/* — Server discovery

Nginx Proxy Manager: Create a proxy host for matrix.example.com pointing to conduit:6167. Enable SSL. Add custom location /_matrix/http://conduit:6167.

Caddy:

matrix.example.com {
    reverse_proxy conduit:6167
}

For federation, port 8448 must also reach Conduit. The .well-known/server delegation lets you use port 443 instead, which is simpler.

See Reverse Proxy Setup for full configuration guides.

Backup

Back up the Conduit data volume:

# Stop Conduit before backing up the database
docker compose stop conduit
docker run --rm -v conduit-data:/data -v $(pwd):/backup alpine \
  tar czf /backup/conduit-backup-$(date +%Y%m%d).tar.gz -C /data .
docker compose start conduit

The /var/lib/matrix-conduit/ directory contains the RocksDB database with all rooms, messages, and media. This is the only directory you need to back up.

See Backup Strategy for automated backup approaches.

Troubleshooting

Federation Not Working

Symptom: Other Matrix servers can’t reach yours, or you can’t join rooms on remote servers.

Fix: Verify your .well-known/matrix/server file returns the correct JSON. Test with:

curl https://matrix.example.com/.well-known/matrix/server

Also check the Matrix Federation Tester with your domain. Ensure your reverse proxy forwards /_matrix/ paths correctly.

High Memory Usage

Symptom: Conduit using more RAM than expected.

Fix: Reduce the database cache:

CONDUIT_DB_CACHE_CAPACITY_MB: "100"

Leave resource-heavy rooms (rooms with thousands of members like #matrix:matrix.org consume significant memory for state resolution).

Users Can’t Register

Symptom: Registration fails with “Registration is disabled.”

Fix: Either set CONDUIT_ALLOW_REGISTRATION: "true" or provide a CONDUIT_REGISTRATION_TOKEN and share it with users. After creating accounts, disable open registration.

Database Permission Errors

Symptom: Conduit crashes on startup with permission errors.

Fix: The data volume must be writable by the container. If using bind mounts instead of named volumes:

sudo chown -R 1000:1000 ./conduit-data

Element Shows “Server Not Found”

Symptom: Element can’t connect to your homeserver.

Fix: Verify the .well-known/matrix/client file is accessible and returns valid JSON. CORS headers must allow Element’s origin. Check your reverse proxy configuration.

Resource Requirements

  • RAM: 70-200 MB idle (vs 1-2+ GB for Synapse)
  • CPU: Minimal — consistently under 1% for small deployments
  • Disk: ~500 MB after a week of active use (vs 100+ GB for Synapse over a year)
Deployment SizeRAMCPU
1-5 users70-150 MB< 1%
10-50 users200-500 MB1-2%
100+ users500 MB - 1 GB2-5%

The Fork Ecosystem

Conduit has spawned several forks worth knowing about:

  • Conduwuit — Performance-focused fork with additional features. Dropped SQLite support (RocksDB only). More aggressive development pace.
  • Tuwunel — Official successor to Conduwuit. Sponsored development. Binary-compatible drop-in replacement.

All forks share the same data format and Docker setup patterns. Start with Conduit for stability, consider the forks if you need bleeding-edge features.

Verdict

Conduit is the best choice for running a Matrix homeserver on limited hardware. It uses 10-20x less RAM than Synapse, requires no external database, and deploys in minutes. The trade-off is that it’s still in beta (v0.10.x) — some Matrix features may be incomplete. For a personal server or small community (under 50 users), Conduit is excellent. For large organizations or full Matrix spec compliance, stick with Synapse.

Frequently Asked Questions

How does Conduit compare to Synapse?

Conduit is a lightweight Matrix homeserver written in Rust that uses 10-20x less RAM than Synapse (Python). Conduit requires no external database (uses embedded RocksDB), while Synapse needs PostgreSQL. The trade-off: Conduit is still in beta and doesn’t support the full Matrix spec. For personal servers or small communities, Conduit is excellent. For organizations needing full spec compliance, use Synapse.

Does Conduit support federation?

Yes. Conduit supports Matrix federation out of the box — users on your server can communicate with users on any other Matrix server (including matrix.org). You need a valid domain name with proper DNS and a reverse proxy serving on port 443 with TLS for federation to work.

Which Matrix clients work with Conduit?

All standard Matrix clients work: Element (web/desktop/mobile), FluffyChat, SchildiChat, Nheko, and others. Conduit implements the Matrix Client-Server API, so any client that follows the spec connects without issues. Element is the most popular and well-tested client for Conduit.

Can I migrate from Synapse to Conduit?

Not easily. There’s no official migration tool. Conduit uses a different database format (RocksDB) than Synapse (PostgreSQL). Migration would require exporting room history and state from Synapse and importing it into Conduit — a process that’s not well-supported. For new setups, choose one and stick with it. If you’re already on Synapse with significant history, the migration effort likely isn’t worth it.

What are Conduwuit and Tuwunel?

They’re active forks of Conduit. Conduwuit is a performance-focused fork with additional features and a more aggressive development pace (dropped SQLite, RocksDB only). Tuwunel is the official successor to Conduwuit with sponsored development. Both share the same data format and Docker setup patterns. Start with Conduit for stability; try the forks if you want bleeding-edge features.

How many users can Conduit handle?

Conduit handles personal servers and small communities (under 50 users) comfortably on minimal hardware (256 MB RAM, single core). Performance degrades with large rooms (1,000+ members) and heavy federation activity. For communities of 50-200 users, monitor RAM and CPU usage. For 200+ users, Synapse with PostgreSQL is more proven at scale despite higher resource requirements.

Comments