Matrix Synapse server setup guide

posted | about 5 minutes to read

tags: self-hosting matrixchat synapse

The last few days have been A Lot. I would like to start this blog post before I go anywhere else with it with some encouragement for those who have the means to do so to donate to any or all of these bail funds for protestors or find other ways to support your local BIPOC community. It is morally correct to oppose racist, fascist police brutality and everyone reading this post should find a way to do so. If for some reason you the reader are a cop bootlicker who hasn’t yet closed this page, consider this an invitation to go fuck yourself.

Anyway, for those who are still here, I would like to take a brief moment to talk about encrypted chat. You’ve probably heard of the Signal app, which some journalists use to protect sources. It’s also a useful tool for organizing.

Let me explain that a little bit. What do you think of when you think of how to communicate with people online? Probably stuff - at least in today’s Internet - like Slack, Discord, Twitter, right? Thing about those services is that they’re hosted services. You send a message on Discord, it gets stored in Discord’s database somewhere, and if, say, someone in power wanted to crack down on dissent, they might look at subpoenaing Discord for chat logs and use those to silence protest and quash organizing efforts. And that’s not great!

With encrypted platforms, that becomes less of an issue - the message can only be read by the sender and its intended recipient. In fact, the idea is that only people who are explicitly authorized to read a message will be able to do so. I’m linking some technical details of the Matrix-specific implementation for those curious.

The neat thing about Matrix is that there’s a free server that you could actually register on, at The way that the encryption works means that this is honestly probably good enough if you’re trying to organize on a platform, but it still leaves your messages - even if they’re encrypted - in a database in someone else’s hands. If you’re concerned about that, that’s what I wrote this whole thing for - self-hosting a Matrix server so that even that database of encrypted messages is under your control and not someone else’s.

This is based on my documentation that I saved after my experiments with Synapse last month. It’s a little bit of work but once it’s done it works pretty well.

Full credit to the install guide in the Synapse repository. A lot of what I have here is either pulled from the documentation there, but since all that stuff is in a few different files I felt it would be nice to actually just show the whole dang thing in one place. All this stuff should be done in the order it appears in this guide and at the end you should have a functioning Matrix server.

I wrote this up assuming Ubuntu, but the Synapse install guide has a lot of details on what you’d need to modify for other systems. It’s pretty easy changes, and the stuff below as far as configuration post-install all should apply exactly the same way.

Set up nginx

I used a subdomain with just basic HTTP, then got a certificate via certbot certonly --webroot -w /var/www/html/chat.server.domain -d chat.server.domain. Full SSL config comes later after we set up Synapse.

Set up dovecot send only address (optional1)

doveadm pw =-s SHA512-CRYPT | cut -d '}' -f2
echo 'alias@server.domain:(password in last step)' >> /etc/dovecot/passwd
systemctl reload dovecot


sudo apt install -y lsb-release wget apt-transport-https
sudo wget -O /usr/share/keyrings/matrix-org-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/matrix-org-archive-keyring.gpg] $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/matrix-org.list
sudo apt update
sudo apt install matrix-synapse-py3
cd /etc/matrix-synapse
vim homeserver.yaml

Lines to check in homeserver.yaml:

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

      - names: [client, federation]
        compress: false
systemctl start matrix-synapse && systemctl enable matrix-synapse
source /opt/venvs/matrix-synapse/bin/activate
register_new_matrix_user -c /etc/matrix-synapse/homeserver.yaml http://localhost:8008

Follow the prompts here to make your first user using the registration_shared_secret key from above. Once this is done then you can remove the key from homeserver.yaml if you want to.

Nginx proxy

Change your vhost config for chat.server.domain to the following:

    server {
        listen 443 ssl;
        listen [::]:443 ssl;
        server_name chat.server.domain;
        ssl_certificate /etc/letsencrypt/live/chat.server.domain/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/chat.server.domain/privkey.pem;
        include /etc/nginx/snippets/ssl-params.conf;
        location /_matrix {
            proxy_pass http://localhost:8008;
            proxy_set_header X-Forwarded-For $remote_addr;
        location ^~ /.well-known/acme-challenge/ {
            root /var/www/html/chat.server.domain;
    server {
        listen 8448 ssl;
        listen [::]:8448 ssl;
        server_name chat.server.domain;
        ssl_certificate /etc/letsencrypt/live/chat.server.domain/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/chat.server.domain/privkey.pem;
        include /etc/nginx/snippets/ssl-params.conf;
        location / {
            proxy_pass http://localhost:8008;
            proxy_set_header X-Forwarded-For $remote_addr;

    server {
        listen 80;
        server_name chat.server.domain;
        return 301 https://$host$request_uri;

Delegation (optional)

  1. Synapse doesn’t currently support mailservers that do not accept TLSv1.0 or below, so you may have to open this up especially if you followed my guide to set up your mail server. ↩︎