Synapse - selfhosted, decentralised and federated messaging service
Intro
Matrix is an open standard for decentralised communication, which securely distributes persistent chatrooms over an open federation of servers preventing any single points of control or failure. 1
What is synapse?
Synapse is an open-source Matrix homeserver written and maintained by the Matrix.org Foundation. 2
Because the open-source concept of Matrix and Synapse there are many projects to extend the default functionalities. We cloud use so called bridges to connect an bot to our synpase server which can forward messages from WhatsApp, Signal, Telegram, Instagram or Discord to our private chatroom. 3
basic docker deployment
This deployment just include the bare minimium an synapse instance could run. We are using the original docker image and running a postgres database for storing data. With this setup you can only register users via CLI. You also will need an client to connect to your synaps matrix server. I would recommend fluffychat or element. With these settings only local (users on your instance) can chat. Federation will not work. Also please don’t run this in any serious/productive type of use-case. All packages getting send via http, so completely unencryted. Later we will use an reverse proxy manager to encrypt the traffic.
requirement:
- web domain with an subdomain (something like
matrix.foryourdomain.com
) - access to dns records of the web domain
docker
anddocker-compose
installed on the server you want to host your synapse instance
Setup an A-record for example matrix.foryourdomain.com
and the ip address from your server.
Define some environment variables in ./synapsedb.env
POSTGRES_USER=YOUR_POSTGRES_USERNAME
POSTGRES_PASSWORD=YOUR_POSTGRES_PASSWORD
POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=C --lc-ctype=C
Next just run the following docker-compose file with docker-compose up -d
.
version: '3'
services:
synapse:
container_name: synapse
image: docker.io/matrixdotorg/synapse:latest
restart: unless-stopped
environment:
- SYNAPSE_CONFIG_PATH=/data/homeserver.yaml
volumes:
- ./synapse:/data
depends_on:
- synapse-db
networks:
- matrix
- postgres
ports:
- 8008:8008/tcp
healthcheck:
test: ["CMD", "curl", "-fSs", "http://localhost:8008/health"]
interval: 15s
timeout: 5s
retries: 3
start_period: 5s
runtime: runc
synapse-db:
image: docker.io/postgres:12-alpine
container_name: synapse-db
# Change that password, of course!
env_file:
- synapsedb.env
volumes:
- ./db/schemas:/var/lib/postgresql/data
networks:
- postgres
healthcheck:
test: ["CMD", "pg_isready", "-U", "synapse"]
interval: 15s
timeout: 5s
runtime: runc
networks:
matrix:
postgres:
After the first run you should stop the container with docker compose stop synapse
and adjust the parameter of your homeserver.yaml
under ./synapse/homeserver.yaml
.
Here is my base configuration as an example:
server_name: "matrix.foryourdomain.com"
pid_file: /data/homeserver.pid
# i'm using an reverse proxy so this should be fine
listeners:
- port: 8008
tls: false
type: http
x_forwarded: true
resources:
- names: [client]
compress: false
database:
name: psycopg2
args:
user: YOUR_POSTGRES_USERNAME # please change
password: YOUR_POSTGRES_PASSWORD # please change
database: YOUR_POSTGRES_USERNAME # please change in the most cases the username == the postgres database names
host: synapse-db
cp_min: 5
cp_max: 10
log_config: "/data/matrix.foryourdomain.com.log.config"
media_store_path: /data/media_store
registration_shared_secret: "AUTOGENERATED_SECRET"
report_stats: true
enable_metrics: true
macaroon_secret_key: "AUTOGENERATED_SECRET"
form_secret: "AUTOGENERATED_SECRET"
signing_key_path: "/data/matrix.foryourdomain.com.signing.key"
trusted_key_servers:
- server_name: "matrix.org"
to register a new user you could run the following commands:
docker exec -it synapse /bin/bash
register_new_matrix_user -u user1 -p p@ssword -a -c /data/homeserver.yaml
this will register a new user with administrator permissions.
lets secure our traffic with an reverse proxy
Next we will use an reverse proxy to encrypt the http traffic so we could achive an secured connection between our clients and the server. I’m using nginx proxy manager there are also alternatives like haproxy, traefik or caddy. There is a nice guide how to setup nginx proxy manager on linode.com.
So I will asume you have an working reverse proxy with SSL certificates and also managed to route the traffic to the reverse proxy. Also you have to establish a encrypted connection between the synapse server and the server the reverse proxy is running on, likely an VPN connection. I’m running the reverse proxy and the synapse server on the same machine so I don’t have to mind secured connections between multiple servers.
Acording to the text about the docker-compose.yml
should now look something like this:
version: "3"
services:
synapse:
container_name: synapse
image: docker.io/matrixdotorg/synapse:latest
restart: unless-stopped
environment:
- SYNAPSE_CONFIG_PATH=/data/homeserver.yaml
volumes:
- ./synapse:/data
depends_on:
- synapse-db
networks:
- matrix
- postgres
ports:
- 8008:8008/tcp
healthcheck:
test: ["CMD", "curl", "-fSs", "http://localhost:8008/health"]
interval: 15s
timeout: 5s
retries: 3
start_period: 5s
runtime: runc
synapse-db:
image: docker.io/postgres:12-alpine
container_name: synapse-db
# Change that password, of course!
env_file:
- synapsedb.env
volumes:
- ./db/schemas:/var/lib/postgresql/data
networks:
- postgres
healthcheck:
test: ["CMD", "pg_isready", "-U", "synapse"]
interval: 15s
timeout: 5s
runtime: runc
npm:
image: 'jc21/nginx-proxy-manager:latest'
container_name: nginxproxymanager
restart: unless-stopped
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
ports:
- '80:80'
- '443:443'
- '81:81'
networks:
- proxy
networks:
matrix:
postgres:
proxy:
TODO
- create proxy entry
- test connection
- add additional settings
monitoring
When running services in production a common-practice is to use some monitoring software to identify problems quickly. The synapse documentation recommends the grafana monitoring stack which we will also use. TODO: add link to grafana/synapse documentation Also the synapse team is providing us a very useful dashboard.
- grafana
optimizations
- storage data
- fast storage for databases and uploads