
Deploy Conduit | (Just Updated) Matrix Homeserver, Self-Hosted Chat Server, Signups Locked, Admin Preset
Conduit Matrix homeserver (Rust), token-gated signup, admin preset
Just deployed
/var/lib/matrix-conduit
Deploy and Host Conduit on Railway
Built for an LLM agent to deploy and use. The deploy form has no fields to fill: the server name is the service's own public domain, signups are locked behind a generated registration token, and the administrator account is created from a generated password at first boot. Conduit is an open-source, self-hosted Matrix homeserver written in Rust: private chat, rooms and bridges for your own team or your own agents, speaking the standard Matrix client API.
About Hosting Conduit
This template runs one service, conduit (the homeserver on one public domain, with a volume at /var/lib/matrix-conduit holding the RocksDB database), so accounts, rooms, messages and keys survive redeploys.
Locked down from boot. Upstream ships with open registration: anyone who finds the domain can create accounts on it. This template always sets CONDUIT_REGISTRATION_TOKEN and the wrapper refuses to start without one, so a new account needs the token. The first account registered on a Conduit server becomes its administrator, and nothing creates it for you; the wrapper registers the administrator admin with the generated ADMIN_PASSWORD through the token flow the moment the server answers, so it exists before anyone else can sign up. A redeploy finds it and logs already exists. The wrapper also binds Railway's injected PORT, which upstream ignores (it listens on 6167), so the healthcheck reaches the server. CONDUIT_SERVER_NAME is set to the generated domain: a Matrix server name is permanent once the first event is stored, so attach a custom domain before you invite people, or set the variable to it on the first deploy.
Using it. Point any Matrix client (Element, FluffyChat, a bot SDK) at https://YOUR_DOMAIN, sign in as admin with ADMIN_PASSWORD, and give other people CONDUIT_REGISTRATION_TOKEN to create their accounts. The server publishes /.well-known/matrix/client and /.well-known/matrix/server, so federation with other homeservers works on port 443 with no extra port. Federation is on by default; set CONDUIT_ALLOW_FEDERATION to false to run an isolated server. Upstream is Conduit v0.10.16; the project is in beta, so keep backups of the volume.
Agent contract
- Public URL:
https://RAILWAY_PUBLIC_DOMAIN(the generated domain of theconduitservice; also the Matrix server name) - Private URL:
http://conduit.railway.internal:8080 - Credentials: the variables
ADMIN_PASSWORDandCONDUIT_REGISTRATION_TOKENon theconduitservice; the administrator's user name isadmin(add anADMIN_USERNAMEvariable to change it before the first boot) - Auth:
POST /_matrix/client/v3/loginwith{"type":"m.login.password","identifier":{"type":"m.id.user","user":"admin"},"password":"$ADMIN_PASSWORD"}returns{"access_token"}; send it asAuthorization: Bearer $TOKEN. A write without a token answers401 M_MISSING_TOKENand with a wrong token401 M_UNKNOWN_TOKEN. New accounts register through them.login.registration_tokenflow withCONDUIT_REGISTRATION_TOKEN; a wrong token answers401 M_FORBIDDEN. - Health:
GET /_matrix/client/versionsreturns 200
#!/bin/sh
# needs: RAILWAY_PUBLIC_DOMAIN, ADMIN_PASSWORD (variables of the conduit service); also curl. The administrator is "admin" unless ADMIN_USERNAME is set.
B="https://$RAILWAY_PUBLIC_DOMAIN"
J="Content-Type: application/json"
U="${ADMIN_USERNAME:-admin}"
curl -s -o /dev/null -w "health: %{http_code}\n" "$B/_matrix/client/versions"
curl -s -o /dev/null -w "well-known: %{http_code}\n" "$B/.well-known/matrix/client"
TOKEN=$(curl -s -X POST -H "$J" -d "{\"type\":\"m.login.password\",\"identifier\":{\"type\":\"m.id.user\",\"user\":\"$U\"},\"password\":\"$ADMIN_PASSWORD\"}" "$B/_matrix/client/v3/login" | sed -n 's/.*"access_token":"\([^"]*\)".*/\1/p')
if [ -n "$TOKEN" ]; then echo "login: ok"; else echo "login: FAILED"; fi
R='{"name":"agent contract check"}'
curl -s -o /dev/null -w "write with token: %{http_code}\n" -X POST -H "$J" -H "Authorization: Bearer $TOKEN" -d "$R" "$B/_matrix/client/v3/createRoom"
curl -s -o /dev/null -w "write without key: %{http_code}\n" -X POST -H "$J" -d "$R" "$B/_matrix/client/v3/createRoom"
curl -s -o /dev/null -w "write with wrong key: %{http_code}\n" -X POST -H "$J" -H "Authorization: Bearer ${TOKEN}x" -d "$R" "$B/_matrix/client/v3/createRoom"
curl -s -o /dev/null -w "read without key: %{http_code}\n" "$B/_matrix/client/v3/joined_rooms"
curl -s -o /dev/null -w "read with token: %{http_code}\n" -H "Authorization: Bearer $TOKEN" "$B/_matrix/client/v3/joined_rooms"
S=$(curl -s -X POST -H "$J" -d '{"username":"intruder","password":"intruder-password-1"}' "$B/_matrix/client/v3/register" | sed -n 's/.*"session":"\([^"]*\)".*/\1/p')
curl -s -o /dev/null -w "register with wrong token: %{http_code}\n" -X POST -H "$J" -d "{\"username\":\"intruder\",\"password\":\"intruder-password-1\",\"auth\":{\"type\":\"m.login.registration_token\",\"token\":\"wrong\",\"session\":\"$S\"}}" "$B/_matrix/client/v3/register"
A fresh deploy prints health: 200, well-known: 200, login: ok, write with token: 200, write without key: 401, write with wrong key: 401, read without key: 401, read with token: 200 and register with wrong token: 401.
Why Deploy Conduit on Railway?
Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.
By deploying Conduit on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.
- Agent-ready - no deployer fields, a contract block and one script that proves login, a write, the refusal of a write without a token and the refusal of a signup with a wrong token.
- Signups locked - open registration is replaced by a generated token, and the administrator exists before anyone else can register.
- Data survives redeploys - the RocksDB database sits on a volume and the administrator is found again, not recreated.
- Pinned - the upstream image is pinned by digest and the wrapper by tag and digest.
- No per-user pricing - unlimited accounts, rooms and messages on your own domain.
Common Use Cases
- Private team chat - a Matrix server for your own team, reachable from Element or any Matrix client.
- Agent messaging hub - give bots and LLM agents accounts and rooms to talk to people and to each other.
- Bridge host - a homeserver for Matrix bridges to Slack, Discord, Telegram or IRC.
- Federated community server - join the wider Matrix network under your own domain.
Dependencies for Conduit Hosting
- The conduit service with its volume, created by the template. A custom domain is optional but should be set before the first user is invited.
Deployment Dependencies
Template Content
