Matrix Dendrite

[ ← Back Home ]

Last modified on March 21, 2023


Ports required: 80, 443, 8448

Table of Contents

The Matrix protocol’s default implementation, Synapse, is very memory and processor hungry, mostly due to it being written in the interpreted Python programming language. This means that running Synapse on less powerful servers may take a lot of resources away from other services. If you need a more efficient and less memory-intensive but still fully functional Matrix server, then Dendrite is for you.


DNS Records and Delegation

You are not required to run a Matrix server under a subdomain (like, regardless of server software. You can run your server under to ensure usernames and rooms look like and respectively.

Because Matrix uses HTTP for transport over the SSL ports (443 and 8448), you’ll have to configure NGINX for it to work. This can cause confusion, especially if you’re running both a static website and Matrix server under the same domain (like

Depending on your setup, there are 2 different configurations to achieve this:

  1. Your desired domain ( has an A DNS record that already points to your desired Matrix server, so you can configure this or add to your existing NGINX static site configuration to setup Matrix.

  2. You wish to use Matrix with your desired domain ( but this domain’s A record points to a different server, accessible through another domain (like In this case, look into delegation.

NGINX Configuration

Here’s an example configuration for a Matrix server running under

server {

        listen 80;
        listen [::]:80;

        listen 443 ssl http2 default_server;
        listen [::]:443 ssl http2 default_server;

        listen 8448 ssl http2 default_server;
        listen [::]:8448 ssl http2 default_server;

        location ~* ^(\/_matrix|\/_synapse|\/_client) {
                proxy_pass http://localhost:8008;
                proxy_set_header X-Forwarded-For $remote_addr;
                client_max_body_size 50M;

        # These sections are required for client and federation discovery
        # (AKA: Client Well-Known URI)
        location /.well-known/matrix/client {
                return 200 '{"m.homeserver": {"base_url": ""}}';
                default_type application/json;
                add_header Access-Control-Allow-Origin *;

        location /.well-known/matrix/server {
                return 200 '{"m.server": ""}';
                default_type application/json;
                add_header Access-Control-Allow-Origin *;

Let’s say you also want to run a static website under This can be achieved by adding these usual lines under the server section:

                # Basic static site configuration, like any other site
                root /var/www/;
                index index.html;

                location / {
                try_files $uri $uri/ =404;

Certbot Certificates

Finally, make sure to download and enable TLS certificates for this setup by using the certbot command:

certbot --nginx -d


Dendrite has no official distribution packages at the time of writing. To install and run it, you must first install the Go programming language and then compile the Dendrite software from source.

Installing Go

First, download the latest Go tarball:

curl -fLO "$(curl | sed 1q).linux-amd64.tar.gz"

Then, extract the contents to /usr/local, which will create the directory /usr/local/go:

tar -C /usr/local -xzfv go*.tar.gz

Then finally, make sure the /usr/local/go/bin/ path is accessible in the $PATH variable for every user by editing /etc/profile and adding the following line:

export PATH=$PATH:/usr/local/go/bin

Compiling and Installing Dendrite

Besides Go, we also need the build-essential package to compile software:

apt install build-essential

Now download the Dendrite repository using git and change directory to it:

git clone
cd dendrite

Finally, compile Dendrite using go build:

go build -o bin/ ./cmd/...

This might take a few minutes, but once the process is finished you should find the final Dendrite programs populating the bin/ directory.


To configure Dendrite, begin by coping the dendrite-sample.yaml configuration file to dendrite.yaml:

cp dendrite-sample.yaml dendrite.yaml

To configure your domain, edit the following under the global: section:


Server Signing Keys

Generate the signing keys used by your homeserver with the following command, ran from the Dendrite repository:

./bin/generate-keys --private-key matrix_key.pem

You can also import old keys from Synapse, by specifying their file path in the old_private_keys: variable in dendrite.yaml.

Database Configuration

By default, Dendrite will create SQLite databases for all its various components. On most server deployments however, it is beneficial to run Dendrite with a more efficient database backend, like PostgreSQL.

Begin by installing PostgreSQL:

apt install postgresql

Then start the daemon:

systemctl restart postgresql

Now create a user named dendrite to manage your database:

su -c "createuser --pwprompt dendrite" postgres

And finally, create the actual database:

su -c "psql -c 'CREATE DATABASE dendrite ENCODING 'UTF8' LC_COLLATE='C' LC_CTYPE='C' template=template0 OWNER dendrite;'" postgres

Now we can configure this in dendrite.yaml using the connection_string: option under the database: section:

    connection_string: postgres://dendrite:password@localhost/dendrite?sslmode=disable
    max_open_conns: 90
    max_idle_conns: 5
    conn_max_lifetime: -1

Important: If you find database: sub-sections under the individual Dendrite modules in dendrite.yaml (app_service_api, federation_api, key_server, media_api, mscs, room_server, sync_api and user_api), make sure to comment these out as these would override the global database configuration.

Voice and Video Calls

Dendrite supports native voice and video calling by connecting to a compatible TURN and STUN server.

Begin by setting up the coturn TURN server using the guide provided, setting either a shared secret or a username-password pair for authentication.

Then edit the turn: section in dendrite.yaml:

    turn_user_lifetime: "5m"

    turn_shared_secret: "your_shared_secret"

    # If your TURN server requires static credentials, then you will need to enter
    # them here instead of supplying a shared secret. Note that these credentials
    # will be visible to clients!
    # turn_username: ""
    # turn_password: ""

Directory and Ownership

Like Synapse, it’s recommended you place the Dendrite program files in /opt to keep your server organized:

mv dendrite/ /opt/

It’s also recommended you create a dendrite user, who will own the /opt/dendrite directory, so it can be used to run Dendrite as a service:

useradd dendrite -d /opt/dendrite
chown -R dendrite:dendrite /opt/dendrite

Setting up a systemd Service

Now setup a systemd service in /etc/systemd/system/dendrite.service to run Dendrite automatically for you. Make sure to set the WorkingDirectory to the directory where your Dendrite repository is located!

Description=Dendrite (Matrix Homeserver)
After=postgresql.service ## Remove this if you're not using PostgreSQL



Refresh the systemd daemon configuration by running:

systemctl daemon-reload

And finally, run Dendrite by running:

systemctl restart dendrite

Using Dendrite

Creating Users

To create users on the Dendrite server, first ensure it is running. Then, enter a secret value into the registration_shared_secret: field under the client_api section:

registration_shared_secret: "your_secret_string"

Then, use the ./bin/create-account tool located in its repository:

./bin/create-account -config dendrite.yaml -username user -admin

This will automatically prompt you for a password.

Congratulations! You’ve installed the Matrix Dendrite homeserver. Now you can login with any Matrix client you wish, and chat securely.