This is a complete guide on setting up Matrix (Synapse) and Element on a fresh Ubuntu 22.04.
Need a server? Try one of this two 🙂
Scaleway
Hetzner (20€ Free Credits)
What is Matrix?
Matrix is an open standard and communication protocol for real-time communication. It aims to make real-time communication work seamlessly between different service providers, just like standard Simple Mail Transfer Protocol email does now for store-and-forward email service, by allowing users with accounts at one communications service provider to communicate with users of a different service provider via online chat, voice over IP, and videotelephony. Such protocols have been around before such as XMPP but Matrix is not based on that or another communication protocol. From a technical perspective, it is an application layer communication protocol for federated real-time communication. It provides HTTP APIs and open source reference implementations for securely distributing and persisting messages in JSON format over an open federation of servers. It can integrate with standard web services via WebRTC, facilitating browser-to-browser applications.
Server Setup
Update your OS and make sure everything is ready
sudo apt update && sudo apt upgrade
UFW Firewall
Lets make sure ports 80 and 443 are open on UFW
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
Install Docker & Docker-Compose
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
apt-get install python3 python3-pip -y
pip3 install docker-compose
Prepare our compose file
Create a matrix
folder, in this folder create a docker-compose.yml
file with the following contents:
version: '2.3'
services:
postgres:
image: postgres:14
restart: unless-stopped
volumes:
- ./postgresdata:/var/lib/postgresql/data
# These will be used in homeserver.yaml later on
environment:
- POSTGRES_DB=synapse
- POSTGRES_USER=synapse
- POSTGRES_PASSWORD=STRONGPASSWORD
element:
image: vectorim/element-web:latest
restart: unless-stopped
volumes:
- ./element-config.json:/app/config.json
synapse:
image: matrixdotorg/synapse:latest
restart: unless-stopped
volumes:
- ./synapse:/data
Don’t forget to change the Postgres password on this file to a secure password.
Now on the same folder create a config file for the elements clients, named element-config.json
.
Copy the example file from Elements.io into your own config file, and adjust the following settings:
Add our own homeserver at the top of the file:
"default_server_config": {
"m.homeserver": {
"base_url": "https://matrix.example.com",
"server_name": "matrix.example.com"
},
"m.identity_server": {
"base_url": "https://vector.im"
}
},
Generate Synapse config
Now its time to generate the initial config of our synapse server, run the following command to do so:
sudo docker run -it --rm \
-v "$HOME/matrix/synapse:/data" \
-e SYNAPSE_SERVER_NAME=matrix.example.com \
-e SYNAPSE_REPORT_STATS=yes \
matrixdotorg/synapse:latest generate
Configuring Synapse
Now lets adjust the freshly generated synapse config to our needs
Edit the synapse/homeserver.yaml
file as follows:
Comment-out the SQLite database:
#database:
# name: sqlite3
# args:
# database: /data/homeserver.db
And now add our Postgres database:
database:
name: psycopg2
args:
user: synapse
password: STRONGPASSWORD
database: synapse
host: postgres
cp_min: 5
cp_max: 10
Spin it up!
Time to get things moving, spin-up your docker stack:
sudo docker-compose up -d
Create our first (admin) user
sudo docker exec -it matrix_synapse_1 bash
register_new_matrix_user -c /data/homeserver.yaml http://localhost:8008
Follow the on-screen instructions to create your first user
Install Caddy Reverse Proxy
Caddy will be used for the reverse proxy. This will handle incomming HTTPS connections and forward them to the correct docker containers. It a simple setup process and Caddy will automatically fetch and renew Let’s Encrypt certificates for us!
First head over to our user directory
cd ~
Install Caddy:
sudo apt install caddy -y
Create a Caddy file:
sudo nano Caddyfile
Paste the following config:
matrix.example.com {
reverse_proxy /_matrix/* 10.10.10.4:8008
reverse_proxy /_synapse/client/* 10.10.10.4:8008
header {
X-Content-Type-Options nosniff
Referrer-Policy strict-origin-when-cross-origin
Strict-Transport-Security "max-age=63072000; includeSubDomains;"
Permissions-Policy "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=(), interest-cohort=()"
X-Frame-Options SAMEORIGIN
X-XSS-Protection 1
X-Robots-Tag none
-server
}
}
element.example.com {
encode zstd gzip
reverse_proxy 10.10.10.3:80
header {
X-Content-Type-Options nosniff
Referrer-Policy strict-origin-when-cross-origin
Strict-Transport-Security "max-age=63072000; includeSubDomains;"
Permissions-Policy "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=(), interest-cohort=()"
X-Frame-Options SAMEORIGIN
X-XSS-Protection 1
X-Robots-Tag none
-server
}
}
Don’t forget to adjust the IPs and the domain names!
Reload Caddy
caddy reload
You are done, were you looking for more?
Head to your element domain and login!