A distributed chat system with Matrix

Of people and messengers

People is finally understanding the real weight of Facebook misconduct. Also WhatsApp was born as an awesome application, but given recent changes to its policy, a lot of people has been looking elsewhere for alternatives.

A lot of people has been looking into Signal, but then is complaining about silly aesthetics details, when the application was not really born with that priority.

Some swarmed to Telegram, but there again some things are not perfect, and also the security has been argument of discussion.

In spite of the above panorama, a lot of people is still stuck using Whatsupp for either private or (maybe even worse) business conversations.


Given that an alternative do exist, I don't really understand how it is that. If you go for a free application, paid with the owner profiting out of the telemetry of your private life AND insights into the business one, you're really not doing anyone a favour.

Matrix has been out in a while, and it's not even a product, it is an API specification that you can reimplement yourself by means of any language, and has already a number of implementations, both server side and client-side, both mobile, web, and native.

The reference implementation is in Python, but given the clarity of the API, it is easy to imagine many others are coming.

With Matrix you can fullfil any of the following scenarios:

  • you're lazy and don't care: just open an account on matrix.org or on some othe public one
  • you're in the biz, and want to self-host your own private server: get the sources and do it!
  • you're seriously into it and you want to federate your private server with the world: that what Matrix is for!

Of course I want to self-host my data, and also I want users to be able to encrypt their communications if so they desire, with their own private keys.

There is plenty of documentation out there and the people involved is quite helpful, but still I'd like to propose a script approach, so that you can get a grasp of how you can do it.

Install Synapse

The reference implementation of Matrix is called Synapse. Some suggest you can install it with Docker... I prefer the real thing.

To install you need Python3

mkdir -p ~/synapse
pip3 install --upgrade pip
pip3 install --upgrade setuptools
pip3 install matrix-synapse

Generate config

#! /bin/bash -x


cd ~/synapse
python3 -m synapse.app.homeserver \
    --server-name ${DOMAIN_NAME} \
    --config-path homeserver.yaml \
    --generate-config \

This will generate a yaml file that you need to tweak to your needs in order to have it to work. The file is huge, but very well documented. All you need to keep in mind is that matrix needs 2 ports, one for connections by the clients, and another for the federation (if you want to be able to communicate with accounts other than your own system.

My advice is to throw in 2 high ports that are closed behind firewall, and just expose them over the internet behind an HaProxy instance that will handle TLS termination. Of course, if you don't install valid certificates, there's no way you're going to federate with the rest of the world.

If you don't like HaProxy, Nginx or an apache configured as ReverseProxy would do.

If you want to take some taste, using Sqlite as the backend would be just fine, but once you get serious traffic, you will want to switch to Postgres as backend database. Everything is actually documented in the file homeserver.yaml.

To start synapse:

#! /bin/bash -x

cd ~/synapse
~/.local/bin/synctl start

To shutdown synapse:

#! /bin/bash -x

cd ~/synapse
~/.local/bin/synctl stop

Also, from time to time you will want to update the Synapse version (development is quite active, and that currently happens quite often):

#! /bin/bash -x

pip3 install -U matrix-synapse

And given you're pausing the server before installing updates, maybe it's a good point in time for a backup of the system:

#! /bin/bash -x

DATE=$(date '+%Y%m%d')

tar cvfz ${TARGET} ~/synapse/

Once you have the server up and running, you may want to install a client, either on mobile, web, or a native one.

For mobile, I'd start by taking a look at Element on either iOS or Android.

The sources for the web version of the client, that you can choose to host yourself, are found here

You can download a copy of the scripts above from here

Paolo Lulli 2021

[python] [security] [git] [backend] [api] [certificate]