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


You need a running Postgresql database server, a dedicated user with a secure password 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 ~]$


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

[isabell@stardust ~]$ mkdir -p ~/synapse
[isabell@stardust ~]$ pip3.6 install --user jinja2
  Collecting jinja2
    Using cached
  Requirement already satisfied: MarkupSafe>=0.23 in ./synapse/env/lib/python3.6/site-packages (from jinja2) (1.1.1)
  Installing collected packages: jinja2
  Successfully installed jinja2-2.10.1
[isabell@stardust ~]$ pip3.6 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.6 install --user psycopg2
  Collecting psycopg2
    Downloading (377kB)
       |████████████████████████████████| 378kB 21.4MB/s
  Building wheels for collected packages: psycopg2
    Building wheel for psycopg2 ( ... done
    Stored in directory: /home/matrites/.cache/pip/wheels/48/06/67/475967017d99b988421b87bf7ee5fad0dad789dc349561786b
  Successfully built psycopg2
  Installing collected packages: psycopg2
  Successfully installed psycopg2-2.8.3

[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.6 -m \
  --server-name \
  --config-path homeserver.yaml \
  --generate-config \
[isabell@stardust ~]$

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

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

Setup daemon

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

command=python3.6 -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 ~]$ pip3.6 install --user -U matrix-synapse
[isabell@stardust ~]$


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 <>