Will's avatar

⬅️ See more posts

Running your own Matrix homeserver

22 March 2021 (7 minute read)

🔮 This post is also available via Gemini.

100daystooffload technology selfhost

💯 100 Days to Offload

This article is one of a series of posts I have written for the 100 Days to Offload challenge. Disclaimer: The challenge focuses on writing frequency rather than quality, and so posts may not always be fully planned out!

View other posts in this series.

AI artwork of a home server.

Why use decentralised communication services

Centralised communication services, such as Telegram, Signal, and Whatsapp, offer convenient means to chat to friends and family using your personal devices. However these services also come with a number of pitfalls that are worth considering. For example;

  • Many of these services are linked to your phone number, which can affect your privacy.
  • They can be invasive with your contacts (“Jane Doe is now using Telegram!”).
  • They usually require you to use proprietary client software. If your OS/platform isn’t supported then you can’t use that service.
  • They typically require that everyone using the service has to use the same client software.
  • They can be unreliable (Whatsapp frequently has downtime).
  • They are invasive and collect data about you (particularly Whatsapp). If you don’t pay for the service, then you are the product.
  • Even though Signal is encrypted end-to-end, its servers are based in the US and are subject to the laws there. Also their open-source server-side software appears to not have been updated for some time.

There are, of course, other factors on both sides that you may want to consider. It can be hard to move away from these services - after all, there’s no point using a system that no-one else you need to talk to uses.

However, for some people, being able to avoid these issues can be important. One way to do so is to participate in a (preferably open-source) decentralised communication service in which the entire network is not owned by a single entity and where data colleciton is not the business model. This also helps prevent unstability and downtime, since there is not a single point of failure.

This is analogous to using services such as Mastodon and Pixelfed over Twitter and Instagram, respectively - the underlying software is open-source and anyone can host an “instance”. In these cases, each instance can communicate with others using the ActivityPub protocol. In this post I will talk about another protocol that offers decentralised and federated encrypted communication.

The Matrix protocol

The Matrix protocol is one example of a standard for real-time decentralised communication. Since the standard is open, anyone can build server and client software that enables end-to-end encrypted communication between two or more people. Another example of a similar protocol is XMPP, which is also very popular and has been around (in its earlier forms) since 1999.

When using Matrix, you belong to a “homeserver”. This is where your messages and some account details are stored. However, since Matrix is a federated protocol, you can use your account to communicate with others on your homeserver as well as people from other homeservers that federate with yours.

The standard was introduced back in 2014, and by now there is an established ecosystem of software available for use. In fact, you can use Element on your device and get started by joining an existing homeserver right now.

Additionally, if you don’t want the hassle of self-hosting yet another service, then Element also provides plans that allow you to run your own homeserver on managed hosting.

Self-hosting a Matrix homeserver

If you want more control over your data, you may opt to self-host your own homeserver that implements the Matrix standard. Even if you self-host you can still take advantage of the protocol’s federation features and communicate with people on other homeservers.

The resource requirement for Matrix servers is a bit on the heavier side (especially when compared to the lighter XMPP servers). However if you already run a small-ish VPS anyway (as I do for things like Nextcloud), and if you only expect one or two people to be enrolled directly on your homeserver, then you can certainly host Matrix on that same VPS without too much trouble. For reference, I have a single $10 server from Linode, which happily runs Matrix alongside a number of other services.

The Synapse project is probably one of the most robust and feature-complete homeserver implementations, and is the one I’ll talk about in this post. They also offer an officially supported Docker image, which is what I would recommend using to keep things in one place.

Homeserver name

Firstly, I’d recommend setting up a domain (either an existing one or a new one) and then updating your DNS such that the relevant entry points to your server.

It is important to think about the domain name you choose for your homeserver, since this cannot be changed later. Matrix recommends using your root domain name itself rather than a subdomain for your homeserver name. However if you already host a website using your full domain name you will need some extra configuration to make it work properly. I personally don’t, as I wanted an easier setup!

Exposing ports and preparing TLS certificates

In order to configure HTTPS, I’d recommend setting up an Nginx container or server as a reverse proxy and issuing certificates using Let’s Encrypt. The Matrix protocol uses standard port 443 for communication with clients (e.g. from an app) - known as the “client port” - and port 8448 for communication with other homeservers (the “federation port”).

You may wish to read some of the official documentation on setting up a reverse-proxy, but I’ll run through roughly what I do below.

Depending on your Nginx setup, you may need a couple of server blocks similar to the following to configure your reverse proxy (assuming your homeserver name is “example.com”):

server {
  listen      80;
  listen      [::]:80;
  server_name example.com;
  return 301  https://$host$request_uri;
} 

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

  server_name example.com;

  ssl_certificate     /path/to/fullchain.pem;
  ssl_certificate_key /path/to/privkey.pem; 

  location / {
    proxy_pass http://synapse: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;
  }
}

If you run Nginx as a Docker container remember also to expose port 8448 alongside 443.

Synapse uses port 8008 for HTTP communication, to which we forward requests received on both the secure client and federation ports. In the example above, synapse is the name of the container that runs my homeserver, as we’ll cover next. Again, depending on your setup, and whether you choose to use Docker, you may need to change this value so that your reverse proxy can route through to port 8008 on your homeserver.

Generate a configuration file

The next step is to generate your homesever config file. I recommend firstly creating a directory to hold your synapse data (e.g. mkdir synapse_data). We’ll mount this to /data on the target container in order for the configuration file to be created.

The configuration file can be generated using Docker:

docker run -it --rm \
  -v synapse_data:/data
  -e SYNAPSE_SERVER_NAME=example.com \
  -e SYNAPSE_REPORT_STATS=yes \
  matrixdotorg/synapse:latest generate

Once this completes, your synapse_data directory should contain a homeserver.yaml file. Feel free to read through this and check out the documentation for ways in which it can be modified.

Run the homeserver

Finally, we can now run the homeserver. Depending on your reverse proxy setup (and whether you are containerising anything else), you may need to configure your Docker networks, but generally you can just execute the following to get your homeserver running:

docker run -d \
  -v synapse_data:/data
  --name synapse \
  --restart always \
  matrixdotorg/synapse:latest

If everything went well (and assuming your reverse proxy is also now up and running), you should be able to use your web browser to visit your Matrix domain (we used “example.com” above) and see a page that looks like this:

Matrix homeserver confirmation page

Creating your user account

As long as your homeserver is configured to accept user registrations (via the enable_registration directive in homeserver.yaml), you should be able to download a client (or use the Element webapp) and register your first user account.

Once logged-in you can join rooms, invite people, and begin communicating with others.

Conclusion

This post aims to be a rough introduction to running your own Matrix homeserver. The Synapse software offers a variety of ways to tailor your instance, and so it is certainly worth becoming familiar with some of the documentation to ensure you have configured things the way you need.

If you want to get in touch then you can send me a message using Matrix (@wilw:matrix.wilw.dev) or on Mastodon (@wilw@fosstodon.org).

✉️ You can reply to this post via email.

📲 Subscribe to updates

If you would like to read more posts like this, then you can subscribe via RSS.