This tutorial assumes the following:
Completed the first-instance Ansible tutorial
Comfortable using SSH to access an instance and run commands.
Have an instance set up already to host your chat server, with port 8448 open in addition to ports 80 and 443.
A domain with an A record with the hostname @
on the instance OR
A sub-domain with an A record with the hostname set to the subdomain and a
SRV record with the hostname _matrix._tcp
pointing to port
8448
on the target instance.
Matrix is an open source, decentralized, and encrypted communication protocol. Data is not necessarily stored on a single server but in all servers participating in a particular room. The goal is to make it as easy to communicate as sending an email, meaning there is no requirement on using a particular device or application, just support for the Matrix protocol.
Servers in matrix can be federated, allowing your server to communicate with other servers and your identity can be stored on your own homeserver, whilst allowing that identity to be used elsewhere.
Matrix also has support for bridging to other protocols (such as IRC!), however that is outside of the scope of this tutorial. If you’re interested you can find more information at matrix.org/docs/guides/faq.html
We’re going to use Ansible to automatically install Synapse, the reference server implementation of the Matrix protocol. It is implemented in Python and, at the time of writing, is the most installed Matrix homeserver implementation. We’re not going set up an instance on Catalyst Cloud as this has already been covered by the first-instance tutorials.
We want to begin by adding our hostname so that Ansible knows what to do with
it. Open /etc/ansible/hosts
on your machine in your preferred text
editor (this will require sudo/root access) and add the following block to
the end:
[chatservers]
mydomain.com ansible_user:ubuntu
This will tell Ansible which set of hosts to run our playbook on. If we wanted to deploy to multiple hosts they could all be added to the chatservers host group and the same playbook would run on them also.
To begin with we’re going to create a new file and save it as
matrixchat-playbook.yml
In this file we’ll create our play for installing Synapse. To begin with we need to make sure that Python 2 is installed on the target machine because Ansible relies on it. Then we’ll let it go through the setup stage of gathering gathering facts about the machine.
- name: Setup the Matrix Server
hosts: chatservers
become: yes
gather_facts: no
vars:
server_name: "{{ inventory_hostname }}"
pre_tasks:
- name: 'Install Python 2'
raw: sudo apt-get update && sudo apt-get -y install python-minimal
- action: setup
We’re going to want to use HTTPS later so we’ll add the repository for certbot.
tasks:
- name: Add certbot repo for Let's Encrypt Certs
apt_repository:
validate_certs: no
repo: 'ppa:certbot/certbot'
state: present
- name: update aptitude cache
apt:
update_cache: yes
We’re going to install and build Synapse. To do this we’ll need a few dependencies. We’re also doing to install nginx configured as a reverse proxy to enable web access to the built in matrix client.
- name: Install Synapse Prerequisites and Nginx
action: apt pkg={{ item }} state=present
with_items:
- nginx
- python2.7-dev
- build-essential
- libffi-dev
- python-pip
- python-setuptools
- sqlite3
- libssl-dev
- python-virtualenv
- libjpeg-dev
- libxslt1-dev
- python-certbot-nginx
- name: Install Synapse
shell: |
pip install --upgrade pip
pip install --upgrade setuptools
pip install https://github.com/matrix-org/synapse/tarball/master
Before our system can do anything, we need to configure it. We’re going to point our server at port 8008 as this is the port our matrix client runs at. We don’t need to configure an SSL certificate or anything like that just yet, we’ll do that later. We also need to enable the configuration and restart nginx.
- name: Configure Nginx
copy:
dest: "/etc/nginx/sites-available/matrixchat"
content: |
server {
listen 80;
listen [::]:80;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name {{ server_name }};
location / {
return 302 https://$server_name/_matrix/client/;
}
location /_matrix {
proxy_pass http://localhost:8008;
}
location ~ /.well-known {
allow all;
}
}
- name: Enable nginx configuration
file:
src: "/etc/nginx/sites-available/matrixchat"
dest: "/etc/nginx/sites-enabled/matrixchat"
state: link
notify:
- Restart nginx
We’ll also need to start synapse, generate the keys and configuration and also modify the configuration to allow registration.
- name: Create Synapse Directory
file:
path: /home/ubuntu/.synapse
state: directory
- name: Start Synapse
shell: |
python -m synapse.app.homeserver \
--server-name {{ server_name }} \
--config-path /home/ubuntu/.synapse/homeserver.yaml \
--generate-config \
--report-stats=no
- name: Enable Registration
lineinfile:
path: /home/ubuntu/.synapse/homeserver.yaml
regexp: '^enable_registration: False'
line: 'enable_registration: True'
notify:
- Restart Synapse
- Restart nginx
Once you’ve reached this point, and hopefully you’ve been following along
and saving each block of code as we go, should be able to run the playbook like
this: ansible-playbook matrixchat-playbook.yml
from a terminal.
Hopefully nothing breaks and you should be able to go navigate a web browser to
http://yourdomain.com/_matrix/client/
and see the login for the
default matrix client. This is served over http and currently HTTPS will fail.
We’ll set that up next.
We want to secure communication between users and our server, so to do so we’ll get an SSL certificate. Earlier when we were installing dependencies and software, we also installed an nginx certbot package. Certbot is a tool for getting Let’s Encrypt certificates without too much hassle.
To begin, SSH into your compute instance and run the following command:
$ certbot --nginx -d www.example.com -d example.com
You’ll be greeted by a couple of prompts that you’ll want to read and answer. This automatically modifies the nginx configuration we created earlier. Once this is done we need to restart nginx:
$ systemctl restart nginx.service
Navigate to https://yourdomain.com
and you should see the exact same
thing as before.
Our server needs users, you can register a user via the web client, or you can create one using the command below. This will also prompt if you would like the user you are creating to become an admin (for this server) as well.
$ register_new_matrix_user -c ~/.synapse/homeserver.yaml https://localhost:8448
Once you’ve created a user, attempt to login. If you’d like, we can test server federation by navigating to another client such as Riot, located at https://riot.im/app/
Check the radio button to use a custom server and adjust both server fields to your homeservers address and attempt to login with your credentials. If this works, then your server is federated and you can go and participate on other servers with your personal identity.