This post serves as a reference for a project. I will go over the steps taken to setup a self-hosted Matrix homeserver, running Dendrite on AWS Lightsail with minimal resources.

The Matrix protocol

Matrix is:

An open network for secure, decentralised communication

Essentailly, anyone can run their own homeserver, which federates with other homeservers in a decentralised manner - similar to P2P or blockchain networks - creating a fediverse. One well-known social media use case of this technology is Mastodon. I decided on this project as I believe it has a great potential future, decentralising cloud native architecture increases reliability and resilience. As an open network, you are in control of your own privacy and security - not the case with a centralised company that stores millions of user data on servers under their control.

High level overview

Components:

  • Dendrite second gen homeserver
    • small memory footprint - better for deploying on virtual instances
    • scalable - can run on multiple machines/instances
    • sqlite built in - easy deployment
      • can be more efficient with postgresql
  • 1 Amazon Lightsail instance - an easy VPS service, less scalable than EC2 but great for a small project
    • $5 plan (3 months free, perfect for the duration of the course)
      • 1 GB memory (minimum requirement for the server installation)
      • 2 vCPUs
      • 40 GB SSD storage
      • 1 TB data transfer

Getting a new domain name

Straightforward, bought a new domain name for this project. Configuring DNS records will come after creating an instance, as I describe in the next step.

AWS Lightsail instance

I chose to use Lightsail over EC2 after comparing the pros and cons here. We’re not hosting any enterprise grade applications here, and it’s really a dev/test environment for the duration of the course, so it’s the better option.

I select Debian for the OS with no additional applications, which allows me to configure the server from scratch. Steps taken:

  • generate keypair for SSH access
  • add a firewall rule for HTTPS traffic over port 443
  • SSH into the server
  • sudo apt update && sudo apt upgrade
  • disable root login via SSH

Configuring DNS records

All that’s needed in the DNS configuration is an A record that points to the public IP of my instance. I went with matrix for the hostname/subdomain.

Installation planning

Dependencies:

  • Go 1.20+ (apt repo version is 1.15)
  • reverse proxy (nginx)
  • I will use the Docker container for a monolith installation for test purposes

Docker preparation

First need to setup apt to get the correct Docker packages:

# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Add the repository to Apt sources:
echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

After installing Docker and running a hello world container test to make sure it’s all good, I need pull the image and generate a private key for Dendrite:

mkdir -p ./config
sudo docker run --rm --entrypoint="/usr/bin/generate-keys" \
  -v $(pwd)/config:/mnt \
  matrixdotorg/dendrite-monolith:latest \
  -private-key /mnt/matrix_key.pem

Next generate a config:

mkdir -p ./config
sudo docker run --rm --entrypoint="/bin/sh" \
  -v $(pwd)/config:/mnt \
  matrixdotorg/dendrite-monolith:latest \
  -c "/usr/bin/generate-config \
    -dir /var/dendrite/ \
    -db postgres://dendrite:itsasecret@postgres/dendrite?sslmode=disable \
    -server YourDomainHere > /mnt/dendrite.yaml"

In the config I set disable_federation to true, for test purposes. I left disable_registration set to true, because enabling registration without a secondary verification method such as captcha significantly increases risk of spam and abuse on the server. At this stage I won’t be enabling a captcha.

After this I copy the docker-compose file and give it a test run. All seems good, time to setup nginx and TLS with certbot.

sudo apt install -y nginx snapd
sudo snap install --classic certbot

# ensure certbot command can be run
sudo ln -s /snap/bin/certbot /usr/bin/certbot

After packages are installed, I configure nginx. Firstly create the site config file in sites-available:

cd /etc/nginx/sites-available
ln -s /etc/nginx/sites-available/<sitename> /etc/nginx/sites-enabled/<sitename>

Then use certbot –nginx to generate SSL certs and edit the nginx config file to serve over HTTPS.

Testing deployment

Using the federation tester I did a check on my domain name, which was a success.