Having recently dived deeper into the world of Matrix , I’ve naturally set up my own home server by installing Synapse . It’s been a fun journey! This Matrix homeserver has become my go-to for chatting with friends and family over the past few months. Sure, there have been a few hiccups here and there, but overall I’m pleased with its performance.
If you’re new to Matrix and Synapse, getting everything up and running can seem a bit daunting. This article aims to walk you through the process, so you can get to the point where you’re able to register users and start chatting away.
Think of this guide as a mishmash of the official Synapse installation docs, with beginner-friendly explanations, alongside my own experiences and suggestions for taking things further.
I’m assuming you’ve got a fair bit of tech know-how, including knowledge of domains and DNS, basic Linux terminal skills, and a rough idea of what Matrix is.
Why Synapse? I went for Synapse because it’s the most tried-and-tested Matrix server in terms of production and scaling. It gets regular updates, and offers a lot of configurability.
Specs? My setup runs on Ubuntu 22.04 LTS (Jammy), so that’s what this guide will focus on. You don’t need a super beefy machine – a couple of gigs of RAM should be plenty. But, if you’re not planning on joining massive public rooms, you could easily get by with less than 1GB.
Choose a Domain Name
First off, you’ll need a domain name. This will be your server’s identifier moving forward. Later, you’ll configure your DNS provider to direct requests for this domain to your server.
The name you pick will shape your user IDs, showing others how to reach you. In Matrix, user IDs look like @username:example.com
, with the domain name coming after the colon :
. When registering users, you can choose any username (the bit before the colon), but the domain name :example.com
is set in stone.
Installing Synapse
I installed Synapse directly on Ubuntu 22.04, using Debian packages from Element . Element is the company that founded Matrix and maintains Synapse. For other ways to install, including Docker, see here .
Add the matrix.org repository keys and install matrix-synapse-py3
& its dependencies:
sudo apt install -y lsb-release wget apt-transport-https
sudo wget -O /usr/share/keyrings/matrix-org-archive-keyring.gpg https://packages.matrix.org/debian/matrix-org-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/matrix-org-archive-keyring.gpg] https://packages.matrix.org/debian/ $(lsb_release -cs) main" |
sudo tee /etc/apt/sources.list.d/matrix-org.list
sudo apt update
sudo apt install matrix-synapse-py3
Setting Up the Database
Synapse supports both SQLite and PostgreSQL. But honestly, Synapse with PostgreSQL is better in almost every way, especially for anything beyond a demo. The Synapse team strongly recommends using PostgreSQL and thats what we’ll do.
Installing & Configuring PostgreSQL
To install PostgreSQL:
sudo apt install postgresql
sudo apt install postgresql-client-common
sudo systemctl start postgresql.service
Connect to PostgreSQL to setup a synapse_user and database for Synapse, remember to keep the synapse_user password somewhere safe!
sudo su -l postgres
createuser --pwprompt synapse_user
createdb --encoding=UTF8 --locale=C --template=template0 --owner=synapse_user synapse
Next, tell Synapse to use the synapse
database with your synapse_user
credentials.
You’ll find all Synapse’s settings in a YAML file called homeserver.yaml
. Add the following to /etc/matrix-synapse/homeserver.yaml
:
database:
name: psycopg2
args:
user: synapse_user
password: [the password you created]
database: synapse
host: 127.0.0.1
cp_min: 1
cp_max: 25
Routing
Now, we need to make sure your messaging client (more on that later) and other Matrix servers can talk to yours.
Here’s what you’ll need to do.
DNS
You’ve likely purchased a domain name for your server.
Depending on your provider (e.g., GoDaddy or Cloudflare), you’ll need to tweak the DNS settings via their portal so that your domain points to your server’s IP. This way, any requests to yourdomain.com
will reach your server and, by extension, the Synapse software we’re setting up.
Reverse Proxy & SSL
To securely direct requests to your Synapse server, set up a reverse proxy. This lets you expose Synapse’s required ports without giving it root privileges and allows SSL termination at the proxy level.
Setting up a reverse proxy can be a bit tricky. You can use popular options like Apache, Caddy, or Nginx for your reverse proxy. I had Apache already running, so it was a no-brainer for me.
I set up a new VirtualHost for my domain, forwarding the necessary URLs to Synapse: /_matrix
and /_synapse/client
.
Delegation & Ports
Matrix server to server communication operates on 8448 and client to server communication is on port 443. I made a change using Synapse’s delegation functionality to have both server-server and server-client communication on port 443 instead. This gave me the added bonus of being able to use Cloudflare’s DNS proxy setting, which hides your server’s IP address for security (Cloudflare does not support proxying traffic on 8448).
My VirtualHost file therefore listens on port 443 and looks like this:
<VirtualHost *:443>
ServerName example.com
AllowEncodedSlashes NoDecode
ServerAdmin [email protected]
ServerAlias example.com www.example.com
DocumentRoot /var/www/html/example.com
<Location /_matrix>
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
ProxyPreserveHost On
ProxyPass "http://127.0.0.1:8008/_matrix" nocanon
ProxyPassReverse "http://127.0.0.1:8008/_matrix"
</Location>
<Location /_synapse/client>
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
ProxyPreserveHost On
ProxyPass "http://127.0.0.1:8008/_synapse/client" nocanon
ProxyPassReverse "http://127.0.0.1:8008/_synapse/client"
</Location>
# Logging options
# SSL Options
</VirtualHost>
Add this to a .conf
file in your Apache2 sites-enabled
directory, then give Apache2 a restart.
For a deeper dive into reverse proxies, including setups other than Apache2, check the reverse proxy documentation from the Synapse team.
SSL
The reverse proxy should handle SSL for you. LetsEncrypt is a straightforward way to set this up.
Head over to the certbot website for instructions on installing certificates on your machine. This will automatically tweak the VirtualHost file above. After that, restart Apache2, and you should be all set for secure communication.
Configuring Synapse
Before you start Synapse for the first time, have a look at the Synapse configuration manual
to familiarise yourself with the various settings. These configuration options can be added to your homeserver.yaml
file.
Here’s a good starting configuration:
pid_file: "/var/run/matrix-synapse.pid"
registration_shared_secret: [passphrase]
listeners:
- port: 8008
tls: false
type: http
x_forwarded: true
bind_addresses: ['::1', '127.0.0.1']
resources:
- names: [client, federation, media]
compress: false
- port: 9000
type: metrics
bind_addresses: ['::1', '127.0.0.1']
database:
name: psycopg2
args:
user: synapse_user
password: [passphrase]
database: synapse
host: 127.0.0.1
cp_min: 1
cp_max: 25
log_config: "/etc/matrix-synapse/log.yaml"
media_store_path: /var/lib/matrix-synapse/media
signing_key_path: "/etc/matrix-synapse/homeserver.signing.key"
trusted_key_servers:
- server_name: "matrix.org"
user_directory:
enabled: false
search_all_users: false
prefer_local_users: false
presence:
enabled: false
enable_metrics: true
enable_media_repo: true
max_upload_size: 500M
media_retention:
local_media_lifetime: 45d
remote_media_lifetime: 45d
forgotten_room_retention_period: 7d
event_cache_size: 200K
federation_rc_concurrent: 3
federation_rc_reject_limit: 50
federation_rc_sleep_delay: 500
federation_rc_sleep_limit: 10
federation_rc_window_size: 10000
rc_message_burst_count: 10
rc_messages_per_second: 10
gc_thresholds: [1500, 20, 10]
caches:
global_factor: 5
expire_caches: true
cache_entry_ttl: 10m
cache_autotuning:
max_cache_memory_usage: 600M
target_cache_memory_usage: 400M
min_cache_ttl: 30s
per_cache_factors:
get_current_state_ids: 3
_get_joined_users_from_context: 3
get_users_in_room: 3
get_destination_retry_timings: 10
_get_joined_profile_from_event_id: 10
get_unread_event_push_actions_by_room_for_user: 20
This includes some sensible caching and tuning settings (thanks to the Tech Lead of Synapse, Erik Johnston
!) and disables presence to save on CPU. It also keeps the user directory private, with a placeholder for your registration_shared_secret
, which you’ll use to create users.
Start Synapse!
Finally go ahead and start Synapse..
systemctl restart matrix-synapse
At this point, give the Matrix Federation Tester a whirl by entering your domain name. This tool checks if your server is reachable on the expected ports. If you hit any issues, it’s likely to do with the reverse proxy or delegation setup, assuming there’s nothing amiss in the Synapse logs.
Then, create your first user and follow the prompts:
register_new_matrix_user -c /etc/matrix-synapse/homeserver.yaml
Pick a Client and Sign In
Woohoo! Your Matrix homeserver is up and running 🚀
Now, choose a client or app to log in with.
I went with the Element app from the iOS app store. It let me log into my server using the credentials from above. Element has downloads available for most platforms.
Since then, Element X has been released and I’d recommend giving it a go..
Element X is categorised as the latest generation of Matrix clients. It’s super speedy, modern, and its feature set is steadily catching up with the last generation apps.
There’s a bit of a catch – you need to set up ‘sliding sync’, another app on your server, to use Element X. The hope is that sliding sync will eventually be integrated into Synapse, making this extra step unnecessary.
For now, follow the setup instructions on the sliding-sync GitHub page , then tweak your reverse proxy settings as needed.
Using Apache2 as above and running sliding-sync on port 8009:
<Location /_matrix/client/unstable/org.matrix.msc3575/sync>
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
ProxyPreserveHost On
ProxyPass "http://127.0.0.1:8009/_matrix/client/unstable/org.matrix.msc3575/sync" nocanon
ProxyPassReverse "http://127.0.0.1:8009/_matrix/client/unstable/org.matrix.msc3575/sync"
</Location>
Now go and grab Element X from your app store and give it a go.
Message me on Matrix!
What’s Next?
The world’s your oyster, here are some next steps and improvements I made after installing Synapse.
👥 Get some pals (or make some dummy accounts) signed up and start messaging.
🏛️ Dive into some public rooms and check out the federated wonder that is Matrix. But, a heads-up – steer clear of matrix-hq:matrix.org
at first. It’s the biggest room on Matrix, and your server might struggle a bit trying to join.
🌉 Bridge the gap! With Matrix, you can chat across different platforms through something called bridges, like WhatsApp , Instagram , and Signal .
📈 For a performance boost, consider setting up Synapse Workers .
💻 Keep an eye on things by adding monitoring and alerting. I’ve enabled the Synapse metrics endpoint in the homeserver.yaml
above. Hook it up to Prometheus and set up a Grafana dashboard (heres one
from the Synapse team) for real-time insights.
🚀 Speed things up with a local DNS server. Synapse does a ton of DNS queries, especially in big public rooms. A DNS server like dnsmasq can significantly boost performance.
🛜 Lastly, the biggest bottleneck in performance I experienced was actually down to the poor specs of my ISP provided router. It couldn’t handle the number of requests that Synapse demands when you’re part of a few large rooms. Upgrading to a more business orientated router dramatically improved my overall performance and experience.