This article very briefly describes the process of installing Synapse on CentOS 8. Why would you want to do this is totally up to you.

#3Installing libs and dependencies

First of all, install necessary libs.

sudo dnf install libtiff-devel libjpeg-devel libzip-devel freetype-devel \
  lcms2 libwebp-devel tcl-devel tk-devel redhat-rpm-config \
  python36 virtualenv libffi-devel openssl-devel
sudo dnf group install "Development Tools"

#3Installing Synapse server

Next, install the Synapse server itself. I prefer to keep it under opt, you might have other preferences though.

mkdir -p /opt/synapse
virtualenv -p python3 /opt/synapse/env
source /opt/synapse/env/bin/activate
pip install --upgrade pip virtualenv six packaging appdirs
pip install --upgrade setuptools
pip install matrix-synapse

#3Configuring Synapse server

Now, let's generate some default config. Please, use your actual server domain name in place of the mock

source /opt/synapse/env/bin/activate
pip install -U matrix-synapse
cd /opt/synapse
python -m \
  --server-name \
  --config-path homeserver.yaml \
  --generate-config \

The output should be looking like this: A config file has been generated in 'homeserver.yaml' for server name ''. Please review this file and customise it to your needs.

#3Install and configure database

Synapse supports different kinds of databases. In this case, I use PostgreSQL.

  name: psycopg2
    user: synapse_user
    database: synapse
    host: localhost
    port: 5432
    cp_min: 5
    cp_max: 10

#3Install and configure Nginx with TLS

Install Nginx web server if you haven't. Actually, you can use any other web server (e.g. Apache), but I prefer Nginx and os examples refer to it.

sudo dnf install nginx

Now you need TLS certificate for your domain. You can use Letsencrypt free certificate or you can buy it. Anyway, here I presume that you already have the certificate.

Generate SSL dhparam: openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

edit /opt/synapse/homeserver.yaml

find this section and make it looking as below:

  - port: 8008
    tls: false
    bind_addresses: ['']
    type: http
    x_forwarded: true

edit /etc/nginx/conf.d/matrix.conf

server {
    ssl on;
    listen 443 ssl http2;
    charset utf-8;
    keepalive_timeout   70;
    ssl_certificate /etc/letsencrypt/live/;
    ssl_certificate_key /etc/letsencrypt/live/;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers AESGCM:HIGH:!aNULL:!MD5;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 24h;
    ssl_buffer_size 1400;
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver valid=300s;
    resolver_timeout 10s;
    add_header Strict-Transport-Security max-age=63072000;
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;

    location / {
        proxy_pass http://localhost:8008;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $host;
        client_max_body_size 50M;

server {
    listen 8448 ssl default_server;
    listen [::]:8448 ssl default_server;

    ssl on;
    ssl_certificate /etc/letsencrypt/live/;
    ssl_certificate_key /etc/letsencrypt/live/;
    location / {
        proxy_pass http://localhost:8008;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $host;
        client_max_body_size 50M;

server {
    listen 80;
    keepalive_timeout   70;
    add_header X-Frame-Options DENY;
    location / {
      return 301$request_uri;

Don't forget to change to the actual domain name you use for the server.

Run nginx

sudo systemctl restart nginx
sudo systemctl enable nginx

#3Run Synapse server

Create /etc/systemd/system/synapse.service

Put the following text into the file:

Description=Matrix Synapse service

ExecStart=/opt/synapse/env/bin/synctl start
ExecStop=/opt/synapse/env/bin/synctl stop
ExecReload=/opt/synapse/env/bin/synctl restart


Run the Synapse server

sudo systemctl enable synapse
sudo systemctl start synapse

Now navigate to and make sure that you can see a web page with "It works! Synapse is running" - it means everything goes well.

#3Registering a new user

Let's register a new user on the Snapse server. Also, this first user probably should have admin permissions.

register_new_matrix_user -c homeserver.yaml http://localhost:8008

It will ask you for the user name, user password, and if the user should be admin.

#3Configure the client

Now go to and download the client. Use the server URL (e.g. and the user/password combination to log in.

Now you can use your own private messaging server, but it still can't serve audio/video calls.

If everything is good, you might want to lower the log severity to save some disk space. Edit /opt/synapse/ and change all LEVEL entries to ERROR.

#3Installing TURN server

TURN server is necessary for audio/video calls. So, if you're not planning to make calls then you can skip this part.

sudo yum install coturn

edit /etc/coturn/turnserver.conf

Generate or buy TLS certificates for the domain name. Basically, you can use same certificates as you used for Synapse above if the TRUN server and the Synapse server share same domain name. Below is what is important in the config.


Now let's add TURN support to the Synapse server. Edit /opt/synapse/homeserver.yaml

  - ""
  - ""
  - ""
  - ""

turn_shared_secret: "YOUR_SECRET_KEY"
sudo systemctl restart coturn
sudo systemctl enable coturn
sudo systemctl restart synapse

#3Possible issue with Letsencrypt certificate and TURN server

It might happen that the encrypted TURN communication is not working and then you probably can see this message in coturn logs: session 002000000000000001: closed (2nd stage), user <> realm <> origin <>, local, remote, reason: TLS/TCP socket buffer operation error (callback)

I have an impression that this error appears only if you use certificates from Letsencrypt. Probably, non-free certificates should mitigate this issue, but I haven't checked this idea yet.

So, as a temporary solution you can disable TLS on the coturn server (e.g. comment out the tls-listening-port=5349 line) and also disable encrypted TURN communication on Synapse server (e.g. comment out all turns URIs leaving only turn ones). You would need to restart both coturn and synapse servers then, but after that it should start working. Keep in mind that it means that all audio/video calls are not unencrypted (the text messaging is still encrypted though).