Setting up your own Matrix Synapse service on VPS

For the past one month, I’ve been digging around the internet about the decentralized fediverse community.  Platforms like Mastodon, Matrix Synapse, Pixelfed etc are the open-source implementations of twitter, IMs like telegram Signal and instagram, and more importantly these platforms are all decentralized, which means your posts/pics/blog/account belongs to yourself, and won’t be deleted by those BIG companies for no reason, especially those stupid companies in China like weibo, bilibili, douyin etc. Ad-free, no user privacy tracking/leaking are also advantages of the fediverse platforms.

Up to now, I’ve tried my hand on Soapbox FE, Matrix Synapse and got them successfully running on my VPS. This post mainly focuses on the installation of Matrix Synapse which was written in Python. There is a Go version of Matrix – Dendrite. It’s more efficient and maybe the VPS hardware requirements aren’t that high. But it’s still in the beta version, not recommended for the  production environment.

Minimal VPS Specs: 1-core vCPU, 1G of RAM, here is the utilization of Synapse running on my VPS(just 1 user), 2G RAM is recommended for users less than 20. The OS is Ubuntu 20.04.

I’ve made a test video call between my 2 phones, the CPU ( Intel(R) Xeon(R) CPU E5-2690 v4 @ 2.60GHz ) usage is around 25%, so a 2-core CPU is recommended.

I want to use the base domain as part of the user name, like, instead of which is the actual server address. In this case, you can host other websites (like Mastodon) with the base domain

Let’s get rolling!

Install matrix synapse package

sudo apt update 
sudo apt upgrade -y
sudo apt install lsb-release wget apt-transport-https -y

// add the gpg keys
sudo wget -qO /usr/share/keyrings/matrix-org-archive-keyring.gpg 
sudo echo "deb [signed-by=/usr/share/keyrings/matrix-org-archive-keyring.gpg] $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/matrix-org.list

// install matrix-synapse package
sudo apt update 
sudo apt upgrade 
sudo apt install matrix-synapse-py3

One window will pop up, enter the base domain name, NOT, it’s very important. Hit <OK> and  <NO>.


sudo systemctl enable matrix-synapse 
sudo systemctl start matrix-synapse 
sudo systemctl status matrix-synapse

Go through the log file if synapse is not running:

sudo tail -f /var/log/matrix-synapse/homeserver.log

Make sure again by typing:

sudo netstat -lnpt | grep :8008

Change the configurations:

Generate the Matrix Synapse registration secret:

cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1

Edit the synapse config file:

sudo nano /etc/matrix-synapse/homeserver.yaml

Press Ctrl+w to find registration_shared_secret: uncomment it and change the value with the random string generated above.

Find the following lines and change the value correspondingly:

enable_registration: false
allow_public_rooms_without_auth: false
allow_public_rooms_over_federation: false

Press Ctrl+o to save the file and Ctrl+x to exit. Then restart the synapse service:

sudo systemctl restart matrix-synapse

Again, if anything goes wrong, check out the log file.

sudo more /var/log/matrix-synapse/homeserver.log

Install Nginx and certbot:

sudo apt install nginx certbot python3-certbot-nginx -y

Generate the SSL certificates:

sudo systemctl stop nginx
sudo certbot certonly -d -d

Create Nginx config file of the base domain:

cd /etc/nginx/sites-available
sudo nano

Change to your domain name:

server {
        root /var/www/; # You can host another website here or do a reverse proxy.

        # Add index.php to the list if you are using PHP
        index index.html index.htm index.nginx-debian.html;


        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;

    location /.well-known/matrix/client {
# pay attention here, help client like element to find the actual address. return 200 '{"m.homeserver": {"base_url": ""}}'; default_type application/json; add_header Access-Control-Allow-Origin *; } location /.well-known/matrix/server { return 200 '{"m.server": ""}'; default_type application/json; add_header Access-Control-Allow-Origin *; } listen [::]:443 ssl ipv6only=on; # managed by Certbot listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } server { if ($host = { return 301 https://$host$request_uri; } # managed by Certbot listen 80; listen [::]:80; server_name; return 404; # managed by Certbot }

Create the config file:

sudo nano

Change the content to:

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

# make your synapse instance federated. listen 8448 ssl http2; listen [::]:8448 ssl http2; server_name; ssl_certificate /etc/letsencrypt/live/; ssl_certificate_key /etc/letsencrypt/live/; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384; ssl_session_timeout 10m; ssl_session_cache shared:SSL:10m; ssl_session_tickets on; ssl_stapling on; ssl_stapling_verify on; location ~ ^(/_matrix|/_synapse/client) { # note: do not add a path (even a single /) after the port in proxy_pass, # otherwise nginx will canonicalise the URI and cause signature verification # errors. proxy_pass; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $host; # Nginx by default only allows file uploads up to 1M in size # Increase client_max_body_size to match max_upload_size defined in homeserver.yaml
# support file size up to 200MB. client_max_body_size 200M; }
# make your synapse instance federated. location / { proxy_pass http://localhost:8008; proxy_set_header X-Forwarded-For $remote_addr; } } server { if ($host = { return 301 https://$host$request_uri; } # managed by Certbot listen 80; listen [::]:80; server_name; return 404; # managed by Certbot }

Link the config files to sites-enabled folder and restart nginx

ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/
ln -s /etc/nginx/sites-available/ etc/nginx/sites-enabled/

nginx -t
systemctl restart nginx

Setting up Postgres

Issue the following commands:

sudo apt install postgresql postgresql-contrib
sudo -i -u postgres
# Create an user and password, you shoud change the Password CREATE USER "synapseuser" WITH PASSWORD 'Password'; CREATE DATABASE synapse ENCODING 'UTF8' LC_COLLATE='C' LC_CTYPE='C' template=template0 OWNER "synapseuser"; exit
exit # exit the current user sudo apt install python3-psycopg2

Edit synapse config file:

sudo nano /etc/matrix-synapse/homeserver.yaml

Since I’ll use PostgreSQL instead of sqlite3, comment out the following lines:

#  name: sqlite3
#  args:
#    database: /path/to/homeserver.db

Uncomment the following lines:

  name: psycopg2
  txn_limit: 10000
    user: synapseuser  
# enter the username and password created above. password: password database: synapse host: localhost port: 5432 cp_min: 5 cp_max: 10

Looks like this:

Change public_baseurl to the real domain (IMPORTANT!):

Find and change maximum file size to 200M

max_upload_size: 200M

Since the file size has been changed in the nginx config file of, there is 1 more place to change:

sudo nano /etc/nginx/nginx.conf

Add the following line in http section:

client_max_body_size 200M;

Save & exit. Restart synapse & nginx:

sudo systemctl restart matrix-synapse
sudo nginx -t
sudo systemctl restart nginx

Enable ports:

ufw allow OpenSSH
ufw allow 'Nginx Full'
ufw allow 8448

Visit, you’ll get this page:

Visit , enter the base domain to test if everything is OK.

Create the admin account

register_new_matrix_user -c /etc/matrix-synapse/homeserver.yaml http://localhost:8008

Type name & password, and then type yes when asked if make it admin.

Visit to login. Click Edit at the upper-right corner of the page, and then fill in the actual synapse address:

Hit Continue and then enter the username and password you just created. You might see something like this as well🤣🤣🤣

Of course, you can find many other clients for you PC, Mac, iphone etc at


Upgrading synapse to the latest version is just like upgrading other softwares on ubuntu, Executing apt full-upgrade would do the job. But before doing that, make sure to backup your homeserver.yaml and then press n when asked wheather or not to replace the config file.


It’s not very complicated, but you can use ansible to deploy matrix which is much easier, especially when you want to bridge other IM tools like telegram or discord etc.

Leave a reply:

Your email address will not be published.