Skip to content

Matrix, the new era of open-source instant messaging

  • by

Speaking of instant messaging, you may think about WhatsApp, Telegram, Signal, etc. But those apps are stealing your privacy for business reasons, which is sad, especially when you are discussing some indescribable topics with your friends. You may run into trouble at any time. So that’s when Matrix comes in!

According to their website,

Matrix is an open-source project that publishes the
Matrix open standard for secure, decentralized, real-time communication, and its Apache licensed
reference implementations.

Maintained by the non-profit Foundation, we aim
to create an open platform that is as independent, vibrant, and evolving as the Web itself… but for communication.

As of June 2019, Matrix is out of beta, and the protocol is entirely suitable for production usage.

So today, I am going to teach you how to self-host your Matrix server.

We are going to use Synapse as our server and use Coturn as our TURN server. (a TURN server is used to overcome NAT restrictions and do P2P Audio/Video calls.

What you will need

  1. An amd64/arm64-based server, 1 vCPU, 1 GB RAM, and as much bigger disk as possible since you’ll need to store all your chat history and files by yourself. In this case, we will use Ubuntu 22.04 LTS Jammy. (any OS with apt should be ok, if you are using yum, Pacman, yay, DNF, etc., you’ll need to figure out which command you’ll need to use by yourself.
  2. A domain name, we will need 3 subdomains later.
  3. A working PC/Tablet/Mobile, for us to SSH into the server


SSH into your server, and use the following command to install Docker.

curl -fsSL | bash
sudo apt update
sudo apt install docker-compose

If you are not using root account, then please use the following command to configure rootless.

sudo apt update
sudo apt install -y uidmap install

Now, open your Shell RC file with your favorite editors like Vim or Nano. (Usually ~/.bashrc or ~/.profile) and insert these three lines at the end of the file.

export PATH=/usr/bin:$PATH
export PATH=/home/$(whoami)/.local/bin:$PATH
export DOCKER_HOST=unix:///run/user/1001/docker.sock

Congrats! Now Docker is installed, now we can install Synapse.

Use the following command to create a folder.

mkdir -p synapse
cd synapse

Okay, now use your favorite text editor to make a new file, named docker-compose.yml. Open the following link, replace the critical arguments and paste them into your new file.


Now point your domain to your server’s IP. We will need 3 subdomains. We will make our example domain.

Point to your server, this will be the front end (FRONT_END_URL). Point to your server, this will be the back end (BACK_END_URL). Point to your server, this will be the TURN server domain(TURN_SERVER_DOMAIN).

If you are using Cloudflare, the front end and back end need to be ‘Proxied’ and the TURN needs to be ‘DNS Only’.

Run the following command to initialize. Replace BACK_END_URL as your back-end URL

docker-compose run --rm -e SYNAPSE_SERVER_NAME=BACK_END_URL -e SYNAPSE_REPORT_STATS=yes synapse generate

Now check if there’s a file called homeserver.yaml at ./synapse/data/

Open the file, we will change some critical arguments, and add some critical parameters as well.

Refer to my example configuration:


Here are a few notes, just in case you didn’t notice my remarks in the config.

A few parameters you need to change and do not need to change but I have remarked.
server_name, default is BACK_END, replace it to FRONT_END.
public_baseurl, replace BACK_END_URL, but please add a 'https://' before it.
password UNDER database, replace DATABASE_PASSWORD to the password you have set in docker-compose.yml
****log_config, registration_shared_secret, macaroon_secret_key, form_secret, signing_key_path: all of these should be generated automatically, no need to change, don't copy.****

i.e. Lines you need to change: 12, 13, 29, 50, 51

Then you will need to configure reCAPTCHA.

Go to and create a reCAPTCHA v2. Add three domains. Your front end, your back end, and, which act as our client. Uncheck the checkbox of ‘Verify the source of the reCAPTCHA solution’. And click create.

You will get two strings, replace ‘RECAPTCHA_V2_PUBLIC_KEY’ and ‘RECAPTCHA_V2_PRIVATE_KEY’ with your Public Key and Private Key you have just got.

Now it’s time to configure our domain reverse proxy. Use the following command to install Nginx.

sudo apt update
sudo apt install nginx
cd /etc/nginx/conf.d

We suggest you use Cloudflare Origin CA (Origin Server) as your certificate and change your SSL/TLS mode to ‘Full (Strict)’.

You can use ‘Flexible’, but you will need to delete the TLS-related lines by yourself.

We will need two configs. One is named ‘frontend.conf’ and the other is named ‘backend.conf’

Use the following command to create a directory for your certificate.

sudo mkdir -p /etc/nginx/cert

And then copy your certificate to /etc/nginx/cert, the certificate must be renamed to ‘cert.crt’ and the private key must be renamed to ‘cert.key’.

It doesn’t matter if they are all ‘.pem’ files before, you can just rename them by using ‘mv’.

Copy my configs to your two files and replace some necessary parameters.

frontend.conf: (need to be changed: Line 5, 28, 34)

backend.conf: (need to be changed: Line 5)

Then use the following command to reload and enable Nginx on startup.

sudo nginx -s reload
sudo systemctl enable nginx
sudo systemctl start nginx

Then go to and test if your Synapse server is working. (Enter the FRONT-END URL)

Now go back to your SSH session, and change the directory back to the Synapse folder, there should be one folder and one file in it. Named ‘synapse’ and ‘docker-compose.yml’. Execute the following command to get into the Synapse Container Shell.

docker-compose exec synapse /bin/bash

Now we are going to create a new user. Execute the following command in the container to create your first user.

cd data 
register_new_matrix_user -c homeserver.yaml http://localhost:8008

Remember to choose ‘y’ when they ask you to Make admin.


Now your Synapse server is up and running. You can go to to log in to your server. Remember to change the default server to your own server. The server domain is your BACK_END DOMAIN, NOT FRONT_END!!!

About TURN server: It took me three hours to write this article and I don’t think I have the patience to write the guide on how to set up the TURN server. I will post the guide later.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.