Synapse is the reference implementation of a matrix server. Matrix is federated chat protocol aiming to replace xmpp. This guide was inspired by Jan Willhaus’s guide for Uberspace 6.


For this guide you should be familiar with the basic concepts of


All relevant legal information can be found here


If you want to run synapse with postgresql instead of sqlite you need a running Postgresql database server.


We will install synapse using pip, which makes it quite easy:

[isabell@stardust ~]$ mkdir -p ~/synapse
[isabell@stardust ~]$ pip3.9 install --user jinja2
  Collecting jinja2
    Using cached
  Requirement already satisfied: MarkupSafe>=0.23 in ./synapse/env/lib/python3.9/site-packages (from jinja2) (1.1.1)
  Installing collected packages: jinja2
  Successfully installed jinja2-2.10.1
[isabell@stardust ~]$ pip3.9 install --user matrix-synapse
  Collecting matrix-synapse
  Collecting pyasn1-modules>=0.0.7 (from matrix-synapse)
    Using cached
  Collecting Twisted>=18.7.0 (from matrix-synapse)
  Collecting urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 (from requests>=2.1.0->treq>=15.1->matrix-synapse)
    Using cached
  Installing collected packages: pyasn1, pyasn1-modules, attrs, constantly, idna, hyperlink, zope.interface, six, Automat, PyHamcrest, incremental, Twisted, msgpack, simplejson, frozendict, canonicaljson, sortedcontainers, pyyaml, pycparser, cffi, pynacl, asn1crypto, cryptography, service-identity, unpaddedbase64, signedjson, pillow, daemonize, chardet, certifi, urllib3, requests, treq, bcrypt, pymacaroons, pyopenssl, psutil, pyrsistent, jsonschema, netaddr, phonenumbers, prometheus-client, matrix-synapse
  Successfully installed Automat-0.7.0 PyHamcrest-1.9.0 Twisted-19.2.1 asn1crypto-0.24.0 attrs-19.1.0 bcrypt-3.1.6 canonicaljson-1.1.4 certifi-2019.6.16 cffi-1.12.3 chardet-3.0.4 constantly-15.1.0 cryptography-2.7 daemonize-2.5.0 frozendict-1.2 hyperlink-19.0.0 idna-2.8 incremental-17.5.0 jsonschema-3.0.1 matrix-synapse-1.0.0 msgpack-0.6.1 netaddr-0.7.19 phonenumbers-8.10.13 pillow-6.0.0 prometheus-client-0.3.1 psutil-5.6.3 pyasn1-0.4.5 pyasn1-modules-0.2.5 pycparser-2.19 pymacaroons-0.13.0 pynacl-1.3.0 pyopenssl-19.0.0 pyrsistent-0.15.2 pyyaml-5.1.1 requests-2.22.0 service-identity-18.1.0 signedjson-1.0.0 simplejson-3.16.0 six-1.12.0 sortedcontainers-2.1.0 treq-18.6.0 unpaddedbase64-1.1.0 urllib3-1.25.3 zope.interface-4.6.0
[isabell@stardust ~]$ pip3.9 install --user psycopg2-binary
  Collecting psycopg2-binary
    Downloading psycopg2_binary-2.9.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.0 MB)
       |████████████████████████████████| 3.0 MB 30.0 MB/s
  Installing collected packages: psycopg2-binary
  Successfully installed psycopg2-binary-2.9.5

[isabell@stardust ~]$


If you get a compilation error due to missing rust components in the cryptography library for python it may help to run:

[isabell@stardust ~]$ pip3.9 install --user setuptools_rust
[isabell@stardust ~]$ python3.9 -m pip install --upgrade  --user pip
[isabell@stardust ~]$


Generate standard config

Generate a config file ~/synapse/homeserver.yaml and replace with the real domain you want your matrix username to end in.

[isabell@stardust ~]$ cd ~/synapse
[isabell@stardust synapse]$  python3.9 -m \
  --server-name \
  --config-path homeserver.yaml \
  --generate-config \
[isabell@stardust ~]$

Replace the public_baseurl in the config file ~/synapse/homeserver.yaml with the url of your Synapse.


Set the Synapse to listen for federation and clients on the correct localhost without encryption in the config file ~/synapse/homeserver.yaml. To do this, locate the listeners: section and modify the entry with port: 8008:

    - port: 8008
      type: http
      tls: false
      bind_addresses: ['::','']
      x_forwarded: true
        - names: [client, federation]
          compress: false

And point the uberspace web backend on / to the listener on port 8008.

To make the application accessible from the outside, configure a web backend:

[isabell@stardust ~]$ uberspace web backend set / --http --port <port>
Set backend for / to port <port>; please make sure something is listening!
You can always check the status of your backend using "uberspace web backend list".
[isabell@stardust ~]$


To enable federation as described MatrixFederation we need to announce, that we are listening on port 443 (the reverse proxy), either via DNS or via .well-known.

Option A: DNS announcement


This is the older method, harder to implement but supporting all servers.

The port can can be announced by setting a DNS record in the following format:

_matrix._tcp.<> <ttl> IN SRV <priority> <weight> <port> <>

For example like this: 3600 IN SRV 10 5 443


this can be checked by running dig -t srv

Option B:.well-known announcement


This is the newer method, easier to implement but not supported on older servers.

Setup the directory for the next step:

[isabell@stardust ~]$ mkdir -p ~/html/.well-known/matrix
[isabell@stardust ~]$

The federation port can also be announced via a file ~/html/.well-known/matrix/server

  "m.server": ""

This has to be made available under /.well-known/matrix via the web backend:

[isabell@stardust ~]$ uberspace web backend set /.well-known/matrix --apache
Set backend for /.well-known/matrix to apache.
[isabell@stardust ~]$

Configure Database Access

Option A: Postgres

Setup a dedicated postgres user and database for synapse:

[isabell@stardust ~]$ createuser synapse -P
Enter password for new role:
Enter it again:
[isabell@stardust ~]$ createdb \
  --encoding=UTF8 \
  --lc-collate=C \
  --lc-ctype=C \
  --owner="synapse" \
  --template=template0 \
[isabell@stardust ~]$

You can verify access with:

[isabell@stardust ~]$ psql synapse synapse

Modify the config file again to give synapse access to the database:

      # The database engine name
      name: psycopg2
      # Arguments to pass to the engine
          user: "synapse"
          password: "<my super secure password>"
          database: "synapse"
          host: "/home/isabell/tmp"
          cp_min: 5
          cp_max: 10

Comment out the active sqlite database. If you are using a different port for postgres, add a port property below host.

Option B: Sqlite

For the file-based sqlite database, leave the standard config in ~/synapse/homeserver.yaml.

Setup daemon

Create ~/etc/services.d/synapse.ini with the following content:

command=python3.9 -m -c %(ENV_HOME)s/synapse/homeserver.yaml

After creating the configuration, tell supervisord to refresh its configuration and start the service:

[isabell@stardust ~]$ supervisorctl reread
SERVICE: available
[isabell@stardust ~]$ supervisorctl update
SERVICE: added process group
[isabell@stardust ~]$ supervisorctl status
SERVICE                            RUNNING   pid 26020, uptime 0:03:14
[isabell@stardust ~]$


Watch MatrixRSS to be notified of upgrades and if there is a update, use pip to update the installation:

[isabell@stardust ~]$ python3.9 -m pip install --user -U matrix-synapse
[isabell@stardust ~]$

Automate the update process with a bash script called ~/bin/synapse-update containing:

# update synapse and restart the service

python3.9 -m pip install --user -U matrix-synapse
supervisorctl restart synapse

Make it executeable:

[isabell@stardust ~]$ chmod +x ~/bin/synapse-update
[isabell@stardust ~]$


You can automate this script as a cronjob. @weekly $HOME/bin/synapse-update > $HOME/logs/synapse-update.log 2>&1 update weekly and output to log


Adding users

Users can be added from the CLI:

[isabell@stardust ~]$ cd ~/synapse
[isabell@stardust synape]$ register_new_matrix_user -c homeserver.yaml
New user localpart [isabell]: USER
Confirm password:
Make admin [no]: no
Sending registration request...
[isabell@stardust synapse]$

Password reset

Passwords can be reset using the cli; first generate the hash of the new password:

[isabell@stardust ~]$ hash_password
Confirm password:
[isabell@stardust ~]$

Then add it to the USERS table:

[isabell@stardust ~]$ psql --user synapse
Password for user synapse:
psql (9.6.10)
Type "help" for help.

synapse=> UPDATE users SET password_hash='$2b$12$yK16TMDMnvj97GFBoxF9QeP2N.U8oadindcjB0Uo9TkSI3CsgwV02' WHERE name='';
[isabell@stardust ~]$


SELECT name from users; returns a list of all usernames

Check federation

The Matrix project provides a federation checker at MatrixFederationChecker .

Tested on Uberspace via on synapse 1.0.0.

Written by: 927589452, luto <>