Matrix is a decentralized messaging platform that provides a secure and privacy-focused alternative to centralized messaging services like Facebook Messenger.
Unlike (for example) Facebook, Matrix is built on a decentralized network of servers and clients, which allows users to communicate securely without relying on a central authority.
In this blog post, we’ll explore the pros and cons of Matrix, compare it with other centralized messaging platforms, and discuss its advantages for privacy and decentralization. Also, we are going to cover how to self-host matrix with docker.
Why using Matrix?
Decentralization: Matrix is built on a decentralized network of servers and clients, which means that there is no central authority controlling the network. This provides greater security and privacy, as there is no single point of failure or vulnerability. For me this is important, as some well known messages apps are having outages and leave me uncommunicated with my loved ones.
Open Source: Matrix is an open-source platform, which means that anyone can contribute to its development or audit the code for security vulnerabilities. This provides greater transparency and accountability, which is particularly important for a messaging platform.
Interoperability: Matrix is designed to be interoperable with other messaging platforms, which means that users can communicate across different platforms without having to switch between different apps.
End-to-End Encryption: Matrix provides end-to-end encryption for messages, which means that only the sender and recipient can read the messages. This provides greater security and privacy, as messages cannot be intercepted or read by third parties.
Of course there are some CONS, but after this post, we will have overcomed them:
Limited Adoption: Matrix is still a relatively new and niche platform, which means that it may not have as many users or features as more popular messaging apps.
- We are going to install it for us and our close ones.
Technical Complexity: Matrix can be more technically complex to set up and use than centralized messaging apps, which may be a barrier to adoption for some users.
- The solution: following this tutorial with Docker and Cloudflare will take you less than 5 minutes.
Dependence on Third-Party Servers: While Matrix is decentralized, users still need to rely on third-party servers to use the platform. This can create some dependency and potential vulnerabilities.
- The solution: DIY and own your matrix server.
Install Matrix with Docker
Now, let’s follow this detailed guide on how to install Matrix with Docker step by step (I wish I had this the first time I wanted to install Matrix in my home server).
We will be using the Matrix Synapse Docker Image from DockerHub.
We need to do some pre-configuration using the terminal. Follow this steps and it will work:
- Go to the desired folder with cd (change directory) - I normally have all my config files in the directory ~/Docker:
- Now, we will create a new folder in the directory that we just moved to and navigate to it:
sudo mkdir Matrix_Synapse & cd ./Matrix_Synapse
- Then, we need to generate a config file, also using the terminal (remember to use your domain, ex: https://matrix.yourdomain.com/):
sudo docker run -it --rm \ -v ~/Docker/Matrix_Synapse/data:/data \ -e SYNAPSE_SERVER_NAME=matrix.yourdomain.com \ -e SYNAPSE_REPORT_STATS=yes \ matrixdotorg/synapse:latest generate #or if the latest does not generate a proper configfile, try a previous one: #sudo docker run -it --rm -v ~/Docker/synapse/data:/data -e SYNAPSE_SERVER_NAME=matrix.yourdomain.com -e SYNAPSE_REPORT_STATS=yes #matrixdotorg/synapse:v1.60.0 generate
You will see a message like this in the terminal, indicating that it went fine:
- After this step, you will see that a new folder called data has been created and inside of it, we can further customize the Matrix server settings:
cd data ls nano homeserver.yaml
In this configuration file, you can include trusted servers, allow (or block) new registrations…
Now, we can create the configuration file for the docker container. If you want you can continue using the terminal and:
sudo nano docker-compose.yml
- You can paste there the configuration below, and execute the CLI command below (or just use Portainer with a Stack if you are tired of the terminal at this point).
sudo docker-compose up -d #to spin-up the docker matrix container
All steps up to this points are common, now you just need to choose how you want to try your matrix messaging server:
- Local access only: great for testing that everything works
- Hosted and expose with an NGINX Proxy
- Hosted and exposed with Cloudflare Tunnel: Selfhost a matrix server at home and expose it publically with Cloudflare for free, so that other people can access it securely. This is my favourite option.
Deploy Matrix Server with Docker - Locally
To try it locally, we just need to use this Docker configuration file. It will automatically pull the latest version of the Synapse Server that will run Matrix for us:
version: "3.3" services: synapse: image: "matrixdotorg/synapse:latest" container_name: "matrix_synapse" ports: - 9999:8008 volumes: - "./data:/data" #it will look at the current directory where you save the file and look for the data folder inside environment: VIRTUAL_HOST: "matrix.yourdomain.com" VIRTUAL_PORT: 8008 LETSENCRYPT_HOST: "matrix.yourdomain.com" SYNAPSE_SERVER_NAME: "matrix.yourdomain.com" SYNAPSE_REPORT_STATS: "yes"
If you apply docker-compose up -d, wait and see that the container will stop. When reading the container logs, it states that: The synapse docker image no longer supports generating a config file on-the-fly. That means, that you have to read the previous steps and generate proper Matrix server config files as expleined above with:
sudo docker run -it --rm -v ~/Docker/synapse/data:/data -e SYNAPSE_SERVER_NAME=mtg.fossengineer.com -e SYNAPSE_REPORT_STATS=yes matrixdotorg/synapse:latest generate
If the latest version of the image does not work, you can try a previous one for this matter. This happened to me and was getting confused about the source of the error (but most of the times latest will be OK).
sudo docker run -it --rm -v ~/Docker/synapse/data:/data -e SYNAPSE_SERVER_NAME=mtg.fossengineer.com -e SYNAPSE_REPORT_STATS=yes matrixdotorg/synapse:v1.60.0 generate
You can check locally that everything went OK at http://localhost:9999.
Deploy Matrix Server in Docker - Behind an NGINX Proxy
Get ready your NGINX docker container to expose service as we did during this post with a step by step guide.
Then, simply use the nginx network together during matrix docker installation:
version: "3.3" services: synapse: image: "matrixdotorg/synapse:latest" container_name: "synapse" volumes: - "./data:/data" #or specifically /home/Docker/Matrix_Synapse ports: - 9999:8008 environment: VIRTUAL_HOST: "matrix.yourdomain.com" VIRTUAL_PORT: 8008 LETSENCRYPT_HOST: "matrix.yourdomain.com" SYNAPSE_SERVER_NAME: "matrix.yourdomain.com" SYNAPSE_REPORT_STATS: "yes" networks: ["nginx_default"] networks: nginx_default: external: true
You should be able to see that Matrix is running at http://localhost:9999.
This worked for me hosting Matrix in GCP (just make sure that the firewall ports are properly configured).
Deploy and Expose Matrix Server - Through Cloudflare Tunnel
First, get familiar with the Cloudflare Docker setup, as covered during the guide to expose your services securely with Cloudflare Zero Trust Tunnel.
Once you have that ready, simply use the tunnel network that connects our matrix-synapse instance to the Cloudflare tunnel during the installation with docker-compose.
With this configuration, the Matrix Server will be exposed safely to the internet (without sharing your public IP Address):
version: "3.3" services: synapse: #service name, for cloudflare UI image: "matrixdotorg/synapse:latest" container_name: "matrix_synapse" volumes: - "./data:/data" #or specifically /home/Docker/Matrix_Synapse ports: - 9999:8008 environment: VIRTUAL_HOST: "matrix.yourdomain.com" VIRTUAL_PORT: 8008 LETSENCRYPT_HOST: "matrix.yourdomain.com" SYNAPSE_SERVER_NAME: "matrix.yourdomain.com" SYNAPSE_REPORT_STATS: "yes" networks: ["tunnel"] #make sure that tunnel is the name of your cloudflare network and adjust accordingly networks: tunnel: #adjust if needed to your Cloudflare container network's name external: true
Or alternatively, you can connect it with:
docker network connect tunnel synapse
Remember to go back to the one dash cloudflare UI:
- Add a Public Hostname in the Cloudflare web UI
- Select the desired subdomain, domain and path (where applicable)
- Then, add proxy host for example: synapse:8008 (synapse here is the name of the service as we configured it on the yml)
After this step, your service is already protected with HTTPS and accesible through the internet in the desired subdomain.yourdomain.com.
This is my favourite way of using my Matrix Server instance, as your home IP Address will be hidden thanks to Cloudflare Zero Trust Tunnel.
Clients: Connecting to Our Matrix Server
There are many flavours to connect to our Matrix Server:
Allow Registrations in Matrix Synapse Server
As per the latest matrix documentation, you will need to add the following values to the homeserver.yaml file allow registrations:
enable_registration: true enable_registration_without_verification: true
For a small public server (family, friends, colleagues) - I would recommend to disable registrations once everyone is onboard.
IMPORTANT: Make sure that you read the documentation properly and set this up according to your preferences.
Modifying the homeserver.yaml to allow registrations
- From the terminal:
cd /synapse/data nano homeserver.yaml
- From the container’s interactive terminal:
apt-get update apt-get install nano cd /data nano homeserver.yaml