Definitive guide for self hosting matrix
There are lots of guides on the web about hosting a matrix server but none of them are complete or atleast up to date.
For that reason, I want to make a simple to follow guide for self hosting a matrix server using docker.
Some background
Matrix usernames are very similar to that of an email. Something like @user:example.org
. Now, if your TLD is already occupied, it cannot be used to host the synapse server. For that reason, we will host it on a subdomain and still use TLD.
Two important things to consider.
-
First is that we will be working with two domains. One, which is
server_name
that will be displayed alongside your username like this if you choosehcrypt.net
asserver_name
:@user:hcrypt.net
. -
And second is a subdomain (
matrix.hcrypt.net
) which will be used to host the synapse server.
Note: For the rest of the guide, we will use those addresses (
hcrypt.net
andmatrix.hcrypt.net
) in the configuration.
For those unaware, federation is how other servers talk to each other so that you can join any public room
The next thing is that for the federation to work, we need something called as delegate.
Delegation is a Matrix feature allowing a homeserver admin to retain a server_name of example.com so that user IDs, room aliases, etc continue to look like *:example.com, whilst having federation traffic routed to a different server and/or port (e.g. synapse.example.com:443).
For that, we want https://hcrypt.net/.well-known/matrix/server
to respond with something like this:
{
"m.server": "matrix.hcrypt.net:443"
}
We can add this using a reverse proxy such as nginx or caddy.
Configure server
First, we need to generate homeserver.yaml
config file. For that, create a directory:
mkdir matrix
cd matrix
After that, generate the config:
docker run -it --rm -v "./data:/data" \
-e SYNAPSE_SERVER_NAME=hcrypt.net -e SYNAPSE_REPORT_STATS=no \
matrixdotorg/synapse:latest generate
We won’t be changing it because the default config is good enough. We will stick to sqlite as our database because I think it’s very solid even for heavy production use.
After that, in the same folder, create element-config.json
and paste this:
{
"default_server_name": "hcrypt.net",
"default_server_config": {
"m.homeserver": {
"base_url": "https://matrix.hcrypt.net"
},
"m.identity_server": {
"base_url": "https://vector.im"
}
},
"uisi_autorageshake_app": "element-auto-uisi",
"show_labs_settings": true,
"room_directory": {
"servers": ["matrix.org", "gitter.im"]
},
"enable_presence_by_hs_url": {
"https://matrix.org": false,
"https://matrix-client.matrix.org": false
}
}
We are pretty much done. Now, use the following compose file:
services:
element:
image: vectorim/element-web:latest
container_name: element
restart: unless-stopped
ports:
- "127.0.0.1:8080:80"
volumes:
- ./matrix/element-config.json:/app/config.json
synapse:
image: matrixdotorg/synapse:latest
container_name: synapse
restart: unless-stopped
ports:
- "127.0.0.1:8008:8008"
- "127.0.0.1:8448:8448"
volumes:
- ./matrix/data:/data
And then spin up the containers:
docker compose up -d
Now, if you are using caddy or nginx or NPM, create the domains accordingly.
synapse:8008
will point tomatrix.hcrypt.net
as mentioned earlier.element:80
will point toelement.hcrypt.net
.
Create user
To create the user, we get a shell inside the container:
sudo docker exec -it synapse /bin/bash
And then run:
register_new_matrix_user -c /data/homeserver.yaml
You can now start using matrix! Let’s make sure federation is working.
Federation
Now, we need to create delegation as mentioned in the beginning.
For NPM users, you can paste this in Advanced Settings
of your TLD proxy host:
add_header Access-Control-Allow-Origin *;
location /.well-known/matrix/server {
return 200 '{"m.server": "matrix.hcrypt.net:443"}';
default_type application/json;
add_header Access-Control-Allow-Origin *;
}
location /_synapse/metrics{
try_files $uri = 404;
}
For normal nginx, you can paste the same thing under the server block.
After that, restart the containers and check the federation at https://federationtester.matrix.org (use your server_name
for testing). If everything is correct, you should see a success message.