---
date: "2021-03-22T11:50:00Z"
title: "Running your own Matrix homeserver"
description: "A rough guide on how to run your own Matrix homeserver."
tags: [100daystooffload, technology, selfhost]
---

# 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](https://github.com/signalapp/Signal-Server) 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](https://en.wikipedia.org/wiki/ActivityPub) protocol. In this post I will talk about another protocol that offers decentralised and federated encrypted communication.

# The Matrix protocol

The [Matrix protocol](https://www.matrix.org) 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](https://en.wikipedia.org/wiki/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](https://element.io/get-started) 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](https://element.io/matrix-services) 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](https://www.linode.com), which happily runs Matrix alongside a number of other services.

The [Synapse project](https://github.com/matrix-org/synapse) 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](https://hub.docker.com/r/matrixdotorg/synapse), 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](https://github.com/matrix-org/synapse/blob/master/INSTALL.md#choosing-your-server-name) 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](https://github.com/matrix-org/synapse/blob/master/docs/reverse_proxy.md) 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](https://github.com/matrix-org/synapse) 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](/media/blog/matrix.png)

## 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](https://matrix.org/clients) (or use the [Element webapp](https://app.element.io)) 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](https://github.com/matrix-org/synapse) 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](https://fosstodon.org/@wilw)).
