Free Small Matrix Server

Canonical version of this article at https://gitlab.com/ptman/matrix-docs/tree/master/free-matrix-server

Ingredients:

  • Domain
  • Server
  • Software
  • Configuration

Free domain name

Get one from Freenom for free or any other place you wish. Freenom only gives free domains for a year. A Matrix server cannot be migrated from one domain to another, so you might want to get a longer-lived one.

You also need to specify subdomains (which is why most dynamic dns services aren't sufficient). To do this I added the domain on the free Cloudflare plan. You can also use freenom dns management if you prefer.

Get a free server

Comparison of free cloud offerings (2019/10):

VendorTime-limitCountRAM (GB)Storage (GB)Transfer (GB)
AWS12 months1 t2.micro13015
Azure12 months1 B1S12x 6415
GCPno limit1 f1-micro0.6301
Oracleno limit2 VM.Standard.E2.1.Micro110010000

If you choose to, register on Oracle Cloud (requires credit card for verification) and create a free VM:

  1. Create a VM instance
  2. Give it a name
  3. OS/image: Canonical Ubuntu 18.04 Minimal
  4. Show Shape, Network and Storage Options -> Assign a public IP address
  5. Add SSH key (generate one using ssh-keygen if you don't have one)
  6. Show advanced options. I removed monitoring, since I'll remove the monitoring agent later.

View resources and make sure the instance and boot volume are "Always Free" if you don't intent to pay for them.

Make sure you can ssh to the server (using the ssh key you generated/picked) using the user 'ubuntu' and can use sudo.

Open firewall

TURN/STUN and coturn

TURN/STUN is used for audio and video stream NAT/firewall traversal. coturn implements the protocol. If you don't need 1-on-1 video/audio calls, or if you're sure NAT and firewall won't be a problem (e.g. you only do calls on networks where you're sure traffic can flow) you can disable coturn to save some more RAM. Generally using coturn gives you much more reliable audio/video calls.

Oracle Cloud Security lists

View resources -> Instances -> Select instance -> Virtual Cloud Network -> Public Subnet -> Security Lists -> Default -> Ingress

Open incoming for CIDR 0.0.0.0/0:

  • 22/tcp for SSH (should be open already)
  • 80/tcp for HTTP
  • 443/tcp for HTTPS
  • 8448/tcp for Matrix federation
  • 3478/tcp, 5349/tcp, 3478/udp, 5349/udp, 49152-49172/udp for TURN/STUN

Ubuntu iptables

The Oracle Cloud Ubuntu images come with somewhat restrictive iptables rules by default. Docker manages the instance firewall and we have the Oracle Cloud firewall in front, so let's remove the current firewall to avoid trouble:

apt purge netfilter-persistent iptables-persistent

Remove useless stuff (optional)

Oracle cloud includes a somewhat heavy monitoring daemon. We have better use for that memory since current versions of Synapse, the Matrix homeserver, can be memory hungry.

snap remove oracle-cloud-agent
apt remove snapd open-iscsi lxd lxcfs

Tune server (optional)

I suggest enabling swap, since there's only 1 GB of RAM.

dd if=/dev/zero of=/swap bs=1M count=1k
chmod 0600 /swap
mkswap /swap
swapon /swap
echo '/swap none swap sw 0 0' >> /etc/fstab

Point domain at server

Assuming you're using a new domain only for this you need the following DNS records:

  • A record $domain pointing to $instance_external_ip_address
  • CNAME record matrix.$domain pointing to $domain
  • CNAME record riot.$domain pointing to $domain

Use matrix-docker-ansible-deploy

Follow the guide, with some tweaks:

Guide in a nutshell, TL;DR

git clone https://github.com/spantaleev/matrix-docker-ansible-deploy/
cd matrix-docker-ansible-deploy
mkdir inventory/host_vars/matrix.$domain
cp examples/host-vars inventory/host_vars/matrix.$domain/vars.yaml
cp examples/hosts inventory/hosts
$EDITOR inventory/hosts
$EDITOR inventory/host_vars/matrix.$domain/vars.yaml
# you'll need to rerun setup-all and start tags again if you edit vars later
ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start
ansible-playbook -i inventory/hosts setup.yml --tags=self-check
ansible-playbook -i inventory/hosts setup.yml -e username=$user -e password=$pass -e admin=yes --tags=register-user

Serve the base domain as well (unless you already have something serving it)

matrix_nginx_proxy_base_domain_serving_enabled: true

Disable all extras because of RAM

matrix_mxisd_enabled: false
matrix_mailer_enabled: false
matrix_coturn_enabled: true # disable to save more RAM

Configure the public IP address for coturn

matrix_coturn_turn_external_ip_address: $instance_external_ip_address

Limit rooms because of limited RAM

matrix_synapse_configuration_extension_yaml: |
  limit_remote_rooms:
    enabled: true
    complexity: 1.0 # this limits joining complex (~large) rooms, can be
                    # increased, but larger values can require more RAM

Done!

Point your browser to https://riot.$domain or use another client.

Maintenance

Remember to keep your VM up to date!

apt update
apt upgrade
reboot # e.g. kernel,dbus,systemd updates

To keep the matrix services upgraded, start by reading the maintenance docs, but really, take a brief look at all the documentation.

Come join #synapse:matrix.org to discuss homeservers. Or say hi to @ptman:ptman.name, who wrote this guide.