Matrix is an open source project that publishes the Matrix open standard for secure, decentralised, real-time communication, and its Apache licensed reference implementations.

I personally am super excited about a decentralised and federated real-time communication protocol. It follows the same path as email. However, as this technology is very new, the original implementation of the Matrix homeserver, Synapse, is slow and buggy. There is a work-in-progress to replace this with a newer program called Dendrite, which is written in Go. However, as this is new and there isn't much documentation on it, it may be difficult to set up and configure. Running your own homeserver and growing this community ought to be simple, so here's how to quickly get started with Matrix, Dendrite, and optionally an identity server called Sydent and a web interface called Element.


My Environment

I set all of this up on a Debian 10 machine (which also serves this website) behind Apache. The process was mostly painless, the only real issue I had was with Apache's reverse proxy.

I set up Dendrite in monolith mode (more on that later) using a PostgreSQL database backend. I also am running an Element instance for web access and my own identity server for email and phone number support (although it's not set up since I don't have my own mail server...)

I put everything under https://matrix.saggis.com, but with redirects to that with any domain under port 8448 (more on that later)

Installing Dendrite

Most of the information in this section was taken from the documentation here.

Dependencies

First, we have to install our requirements.

Installing Go is simple on Debian 10: sudo apt install go-1.15

And installing the latest PostgreSQL is easy too.

sudo apt install curl ca-certificates gnupg
curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
sudo apt update
sudo apt install postgresql-13

You also need your own SSL certificate. I'm assuming that you already have Apache or Nginx running with a combined certificate for your domain and the Matrix subdomain.

Building Dendrite

Create a new user for Dendrite that will manage everything Matrix related with adduser matrix.

As the new matrix user, download the latest tarball for Dendrite from the GitHub releases page and extract it.

As a one-time thing, append the go binaries into your path with export PATH=$PATH:/usr/lib/go-1.15/bin.

Descend into the folder and build the program with ./build.sh. This may take a while, depending on how powerful your machine is.

Configuring Dendrite and PostgreSQL

Next, we're going to set up our database. Create a Dendrite Postgres user with a strong password: sudo -u postgres createuser -P dendrite. We will be running everything in one database, since we want a small-scale setup. Create the database with sudo -u postgres createdb -O dendrite dendrite.

By now, Dendrite should have compiled. Let's create our Matrix signing keys with ./bin/generate-keys --private-key matrix_key.pem. This is a very important file, so keep it somewhere safe.

Copy the dendrite-config.yaml file to dendrite.yaml. Edit the latter.

We are going to change the following:

  • Change server_name to what you want your Matrix domain to be. In my case, I set it to saggis.com.
  • Every instance of connection_string should be your database in this format: postgres://dendrite:USERPASS@localhost/dendrite, where USERPASS is the password the new Postgres user you created.
  • If you are running your own identity server, add your Matrix domain under the trusted_third_party_id_servers section.
  • The level param under the logging section for how verbose you want your logs to be. I'd recommend setting this to warn once in production so your logs don't balloon in size.

Ensure that PostgreSQL is started and running with sudo systemctl enable --now postgresql@13-main.service.

Create a SystemD service file /etc/systemd/system/dendrite.service with the following content:

[Unit]
Description=Dendrite Matrix Server
After=network.target

[Service]
Type=simple
User=matrix
WorkingDirectory=/home/matrix/dendrite
ExecStart=/home/matrix/dendrite/bin/dendrite-monolith-server
Restart=on-abort

[Install]
WantedBy=multi-user.target

Don't start it just yet! We still have to configure Apache first.

Installing and Configuring Sydent (Optional)

Installing Sydent is much easier than installing Dendrite.

First, install the requirements: sudo apt install build-essential python3-dev libffi-dev sqlite3 libssl-dev python-virtualenv libxslt1-dev

Then, as the Matrix user, create the virtual environment

python3 -m venv sydent
source sydent/bin/activate
pip3 install matrix-sydent

Next, tie this into SystemD: create a file /etc/systemd/system/sydent.service with the following content:

[Unit]
Description=Sydent Identity Server
After=network.target

[Service]
Type=simple
User=matrix
WorkingDirectory=/home/matrix/sydent
ExecStart=/home/matrix/.sydent/bin/python3 -m sydent.sydent
Restart=on-abort

[Install]
WantedBy=multi-user.target

Enable and start the service with sudo systemctl enable --now sydent.service. Check to see if it's running with sudo systemctl status sydent.service.

Configuring Apache

First, we need to have Apache listening on port 8448 as well (open the port in the firewall, too).

Edit the file /etc/apache2/ports.conf and add Listen 0.0.0.0:8448 under all instances of Listen 0.0.0.0:443.

Next, add a file /etc/apache2/sites-available/matrix.conf with the following content (replace where needed):

<VirtualHost *:80>
    ServerName matrix.YOURDOMAIN.tld 
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/element
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =matrix.YOURDOMAIN.tld
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

<IfModule mod_ssl.c>
<VirtualHost *:443 *:8448>
    ServerName matrix.YOURDOMAIN.tld
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/element
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/YOURDOMAIN.tld/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/YOURDOMAIN.tld/privkey.pem
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
ProxyPreserveHost On
ProxyPass "/_matrix/identity" "http://localhost:8090/_matrix/identity"
ProxyPass "/_matrix" "http://localhost:8008/_matrix" nocanon
<Location /.well-known/matrix/server>
    ErrorDocument 200 '{"m.server": "matrix.YOURDOMAIN.tld"}'
    Redirect 200 /
    Header always set Content-Type application/json
    Header always set Access-Control-Allow-Origin *
</Location>
<Location /.well-known/matrix/client>
    ErrorDocument 200 '{"m.homeserver": {"base_url": "https://matrix.YOURDOMAIN.tld" } }'
    Redirect 200 /
    Header always set Content-Type application/json
    Header always set Access-Control-Allow-Origin *
</Location>
</VirtualHost>
</IfModule>

This configuration assumes that you have an SSL certificate already. If not, set up a combined certificate for YOURDOMAIN.tld and matrix.YOURDOMAIN.tld.

Next, enable the site with a2ensite matrix and reload Apache with apachectl -t && systemctl reload apache2.

Element Setup (Optional)

If you want, you can install a web interface for Matrix with Element. This is not required, but is very useful if you don't want to install a local app.

Download the tarball for Element from the GitHub releases page and extract it to /var/www/element. Edit the config.json file with the following changes:

  1. Set the default homeserver base URL to "https://matrix.YOURDOMAIN.tld/_matrix" and the server name to YOURDOMAIN.tld.
  2. Add YOURDOMAIN.tld to the list of servers for the roomDirectory.

Now, add this folder to Apache: edit /etc/apache2/apache2.conf and add the following near the bottom:

<Directory "/var/www/element">
    Options -Indexes +FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

Reload Apache with apachectl -t && systemctl reload apache2.

Final Setup and Testing

Enable and start Dendrite with sudo systemctl enable --now dendrite.service and check the status with sudo systemctl status dendrite.service. If everything went alright, the program should be running.

Put your domain into The Federation Tester to check if everything works. If not, you can see more detailed report if you go to the API directly https://federationtester.matrix.org/api/report?server_name=DOMAIN, replacing the DOMAIN with your domain.

If that's working, you can create the first user. As the Matrix user, run dendrite/bin/createuser and follow the instructions.

Join a room (perhaps #dendrite) and let it sit for a little while while it gets in contact with the rest of the federation.

If everything was done correctly, then your Matrix instance is good to go!

Good luck! Maybe another post will explore how to add bridges and bots.

Previous Post Next Post