How To Install Matrix Synapse on Ubuntu 16.04

How To Install Matrix Synapse on Ubuntu 16.04


Matrix is an open standard for decentralized communication. It’s a collection of servers and services used for online messaging which speak a standardized API that synchronizes in real time.

Matrix uses homeservers to store your account information and chat history. They work in a similar way to how an email client connects to email servers through IMAP/SMTP. Like email, you can either use a Matrix homeserver hosted by somebody else or host your own and be in control of your own information and communications.

By following this guide you will install Synapse, the reference homeserver implementation of Matrix. When you’re finished, you will be able to connect to your homeserver via any Matrix client and communicate with others users across other Matrix federated homeservers.


Before you begin this guide you’ll need the following:

  • One Ubuntu 16.04 server set up by following this initial server setup guide, including a sudo non-root user and a firewall.

  • Nginx installed on your server (allowing for HTTPS traffic); you can do this by following this Nginx on Ubuntu 16.04 tutorial.

  • A registered domain name set up with the appropriate DNS records by following this hostname tutorial. Which DNS records you need depend on how you’re using your domain.

    • If you’re using your domain exclusively for Synapse, or if you will be using the same server to host your website and Synapse, you only need an A record with the hostname @.

    • If you will be installing Synapse on a separate server, you will need an A record with the hostname set to the subdomain you want to use, like matrix.example.com, and a SRV record with the hostname _matrix._tcp pointing to the same subdomain on port 8448, with the default priority and weights of 10 and 100 respectively. This will tell Matrix clients and homeservers where to find your Synapse installation.

Step 1 — Installing Matrix Synapse

Log in to your server as your non-root user to begin.

Before you start installing anything, make sure your local package index is up to date.

  1. sudo apt-get update

Next, add the official Matrix repository to APT.

  1. sudo add-apt-repository https://matrix.org/packages/debian/

To make sure your server remains secure, you should add the repository key. This will check to make sure any installations and updates have been signed by the developers and stop any unauthorized packages from being installed on your server.

  1. wget -qO - https://matrix.org/packages/debian/repo-key.asc | sudo apt-key add -

You’ll see the following output:


After adding the repository, update the local package index so it will include the new repository.

  1. sudo apt-get update

With the repository added, installing Synapse is as simple as running a single APT command.

  1. sudo apt-get install matrix-synapse

During the installation, you will be prompted to enter a server name, which should be your domain name. You will also be asked to choose whether or not you wish to send anonymized statistics about your homeserver back to Matrix. Then, Synapse will install.

Once complete, use systemctl to automatically start Synapse whenever your server starts up.

  1. sudo systemctl enable matrix-synapse

That command only starts Synapse when the whole server starts. Your server is already running, so use systemctl manually to start Synapse now.

  1. sudo systemctl start matrix-synapse

Synapse is now installed and running on your server, but you’ll need to create a user before you can start using it.

Step 2 — Creating a User for Synapse

Before you can start using Synapse, you will need to add a user account. Before you can add a new user, you need to set up a shared secret. A shared secret is a string that can be used by anybody who knows it to register, even if registration is disabled.

Use the following command to generate a 32-character string.

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

Copy the string you create, then open the Synapse configuration file with nano or your favorite text editor.

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

In the registration section, look for the registration_shared_secret key. Update its value to the random string you copied, inserting it between quotation marks (" "). Remember to activate the key by uncommenting the line (i.e. deleting the # at the beginning of the line).

If you want to enable public registration as well, you can update the value of enable_registration to True here.

. . .

## Registration ##

# Enable registration for new users.
enable_registration: False

# If set, allows registration by anyone who also has the shared
# secret, even if registration is otherwise disabled.
registration_shared_secret: "randomly_generated_string"

. . .

Save and close the file.

After modifying the configuration, you need to restart Synapse so the changes can take effect.

  1. sudo systemctl restart matrix-synapse

Once restarted, use the command line to create a new user. The -c flag specifies the configuration file, and uses the local Synapse instance which is listening on port 8448.

  1. register_new_matrix_user -c /etc/matrix-synapse/homeserver.yaml https://localhost:8448

You will be prompted to choose a username and a password. You’ll also be asked if you want to make the user an administrator or not; it’s up to you, but an administrator isn’t necessary for this tutorial.

Once your user is created, let’s make sure the webserver is able to serve Synapse requests.

Step 3 — Configuring Nginx and SSL

Matrix clients make requests to https://example.com/_matrix/ to connect to Synapse. You’ll need to configure Nginx to listen for these requests and pass them on to Synapse, which is listening locally on port 8008. You’ll also secure your setup by using SSL backed by Let’s Encrypt.

To do this, you’ll create a custom Nginx configuration file for your website. Create this new configuration file.

  1. sudo nano /etc/nginx/sites-available/example.com

The location /_matrix block below specifies how Nginx should handle requests from Matrix clients. In addition to the request handling, the /.well-known block makes the directory of the same name available to Let’s Encrypt.

Copy and paste the following into the file.

server {
    listen 80;
    listen [::]:80;

    root /var/www/html;
    index index.html index.htm index.nginx-debian.html;

    server_name example.com www.example.com;

    location /_matrix {
        proxy_pass http://localhost:8008;

    location ~ /.well-known {
        allow all;

This Nginx server blocks tutorial has more information about how files like these work. When you have configured the server, you can save and close the file.

To enable this configuration, create a symlink for this file in the /etc/nginx/sites-enabled directory.

  1. sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com

Test your configuration file for syntax errors by running the command.

  1. sudo nginx -t

Correct the syntax based on the error output, if any. When no errors are reported, use systemctl reload Nginx so the changes take effect.

  1. sudo systemctl reload nginx

To finish securing Nginx with a Let’s Encrypt certificate, follow this Let’s Encrypt for Nginx on Ubuntu 16.04 tutorial. Remember to use /etc/nginx/sites-available/example.com instead of the default configuration file. You’ve already added the ~/.well-known block mentioned in Step 2 of that tutorial.

Once Let’s Encrypt is set up, you can move on to configuring the firewall to allow the necessary traffic for Synapse to communicate with other homeservers.

Step 4 — Allowing Synapse through the Firewall

Client traffic connects to Synapse via the HTTPS port 443, (which is already open in your firewall from the Nginx guide). However, traffic from other servers connects directly to Synapse on port 8448 without going through the Nginx proxy, so you need to allow this traffic through the firewall as well.

  1. sudo ufw allow 8448

Check the status of UFW.

  1. sudo ufw status

It should look like this:

Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere Nginx Full ALLOW Anywhere 8448 ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Nginx Full (v6) ALLOW Anywhere (v6) 8448 (v6) ALLOW Anywhere (v6)

This means that all the necessary traffic is allowed through your firewall. The last step you should take is improving Synapse’s security by updating its SSL certificates.

Now that Synapse is configured and can communicate with other homeservers, you can increase its security by using the same SSL certificates you requested from Let’s Encrypt at the end of Step 3. By default Synapse uses self signed certificates which do the job, but seeing as you already requested the Let’s Encrypt certificates it’s simple to use those and improve security.

Copy the certificates to your Synapse directory:

  1. sudo cp /etc/letsencrypt/live/example.com/fullchain.pem /etc/matrix-synapse/fullchain.pem
  2. sudo cp /etc/letsencrypt/live/example.com/privkey.pem /etc/matrix-synapse/privkey.pem

In order for these certificates to be updated when they are renewed you need to add these commands to your cron tab. Open it for editing.

  1. sudo crontab -e

And add the following lines:

crontab entry
35 2 * * 1 sudo cp /etc/letsencrypt/live/example.com/fullchain.pem /etc/matrix-synapse/fullchain.pem 35 2 * * 1 sudo cp /etc/letsencrypt/live/example.com/privkey.pem /etc/matrix-synapse/privkey.pem 36 2 * * 1 sudo systemctl restart matrix-synapse

Then save and close the file. Next, open your Synapse configuration file with nano or your favorite text editor.

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

Using the same certificate you requested from Lets Encrypt in Step 3, replace the paths in the configuration file.

. . .

tls_certificate_path: "/etc/matrix-synapse/fullchain.pem"

# PEM encoded private key for TLS
tls_private_key_path: "/etc/matrix-synapse/privkey.pem"

# PEM dh parameters for ephemeral keys
tls_dh_params_path: "/etc/ssl/certs/dhparam.pem"

. . .

Restart Synapse so the configuration changes take effect.

  1. sudo systemctl restart matrix-synapse

Everything’s set up, so now you can connect to your homeserver with any Matrix client and start communicating with others. For example, you can use the client on Matrix’s website.

Enter the following for the appropriate fields:

  • Your Matrix ID is in the format @user:server_name (e.g. @sammy:example.com). Other federated servers use this to find where your homeserver is hosted.
  • Your Password is the secure password you set when creating this user.
  • Your Home Server is the server name you chose in Step 1.

If you enabled public registration in Step 2, you can also click the Create account link to create a new account or allow others to create a new account on your homeserver.

From there, you can log into rooms and start chatting. The official support room for Matrix is #matrix:matrix.org.


In this guide, you securely installed Matrix Synapse with Nginx, backed by SSL certificates from Let’s Encrypt. There are many Matrix clients you can use to connect to your homeserver, and you can even write your own Matrix client or get involved with the project in other ways.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors

Default avatar

staff technical writer

hi! i write do.co/docs now, but i used to be the senior tech editor publishing tutorials here in the community.

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

I think in the latest release the port for the default reverse proxy installation is 8008 therefore:

register_new_matrix_user -c /etc/matrix-synapse/homeserver.yaml https://localhost:8448

fails, but

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


Step 5 is actually misleading as it is very much not the recommended, See https://github.com/matrix-org/synapse/pull/2468 && https://github.com/matrix-org/synapse/issues/2438

unable to call on a different network in the matrix synapse

Also, in the latest config file, this portion is absent.

# PEM dh parameters for ephemeral keys
tls_dh_params_path: "/etc/ssl/certs/dhparam.pem"

Registering a new user is giving me an error, seems to be connection error. Any tips?


Please add this to the tutorial: IF in any case dhparam.pem couldn’t be found, for most cases it is a problem. Add first to the tutorial that users must create a dhparam.pem before adding it. Go to the terminal and add this command to create a dhparam.pem

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

This works just fine!

Then open in sudo nano /etc/matrix-synapse/homeserver.yaml and edit the line


PEM dh parameters for ephemeral keys

tls_dh_params_path: “/etc/ssl/certs/dhparam.pem” …***

Save and finish.

This should work fine!

Thank you for this tutorial. I just it in parts to set up my first matrix home server. I would like to point out a few things that re not correct though:

  • Part 5 - it is not recommended to use the short lived lets-encrypt certificates for federation.
  • In the nginx config file should include this line proxy_set_header X-Forwarded-For $remote_addr; and set bind_addresses: [‘’] and x_forwarded: true for port 8008 in homeserver.yaml to ensure that client IP addresses are recorded correctly. See https://github.com/matrix-org/synapse#using-a-reverse-proxy-with-synapse

Just adding a note, in the article you say the official support room is #matrix:matrix.org, #synapse-community:matrix.org is actually a better room for support with synapse servers. Here is a clickable link: https://matrix.to/#/#synapse-community:matrix.org.

Thank you for your nice tutorial. I followed all your steps except step5. Yet when I try to access the room #matrix-dev:matrix.org, it puts me a 502: Bad Gateway error.

Here are my logs:

2018-03-08 14:37:37,434 - root - 188 - WARNING - GET-201- Error retrieving alias
2018-03-08 14:37:37,435 - synapse.http.server - 127 - ERROR - GET-201- 502: Bad Gateway
Traceback (most recent call last):
  File "/root/.synapse/lib/python2.7/site-packages/synapse/http/server.py", line 117, in wrapped_request_handler
    yield request_handler(self, request, request_metrics)
  File "/root/.synapse/lib/python2.7/site-packages/twisted/internet/defer.py", line 1384, in _inlineCallbacks
    result = result.throwExceptionIntoGenerator(g)
  File "/root/.synapse/lib/python2.7/site-packages/twisted/python/failure.py", line 408, in throwExceptionIntoGenerator
    return g.throw(self.type, self.value, self.tb)
  File "/root/.synapse/lib/python2.7/site-packages/synapse/http/server.py", line 263, in _async_render
    callback_return = yield callback(request, **kwargs)
  File "/root/.synapse/lib/python2.7/site-packages/twisted/internet/defer.py", line 1384, in _inlineCallbacks
    result = result.throwExceptionIntoGenerator(g)
  File "/root/.synapse/lib/python2.7/site-packages/twisted/python/failure.py", line 408, in throwExceptionIntoGenerator
    return g.throw(self.type, self.value, self.tb)
  File "/root/.synapse/lib/python2.7/site-packages/synapse/rest/client/v1/directory.py", line 50, in on_GET
    res = yield dir_handler.get_association(room_alias)
  File "/root/.synapse/lib/python2.7/site-packages/twisted/internet/defer.py", line 1384, in _inlineCallbacks
    result = result.throwExceptionIntoGenerator(g)
  File "/root/.synapse/lib/python2.7/site-packages/twisted/python/failure.py", line 408, in throwExceptionIntoGenerator
    return g.throw(self.type, self.value, self.tb)
  File "/root/.synapse/lib/python2.7/site-packages/synapse/handlers/directory.py", line 185, in get_association
  File "/root/.synapse/lib/python2.7/site-packages/twisted/internet/defer.py", line 1384, in _inlineCallbacks
    result = result.throwExceptionIntoGenerator(g)
  File "/root/.synapse/lib/python2.7/site-packages/twisted/python/failure.py", line 408, in throwExceptionIntoGenerator
    return g.throw(self.type, self.value, self.tb)
  File "/root/.synapse/lib/python2.7/site-packages/synapse/federation/transport/client.py", line 188, in make_query
  File "/root/.synapse/lib/python2.7/site-packages/twisted/internet/defer.py", line 1384, in _inlineCallbacks
    result = result.throwExceptionIntoGenerator(g)
  File "/root/.synapse/lib/python2.7/site-packages/twisted/python/failure.py", line 408, in throwExceptionIntoGenerator
    return g.throw(self.type, self.value, self.tb)
  File "/root/.synapse/lib/python2.7/site-packages/synapse/http/matrixfederationclient.py", line 442, in get_json
  File "/root/.synapse/lib/python2.7/site-packages/twisted/internet/defer.py", line 1386, in _inlineCallbacks
    result = g.send(result)
  File "/root/.synapse/lib/python2.7/site-packages/synapse/http/matrixfederationclient.py", line 247, in _request
    response.code, response.phrase, body
HttpResponseException: 502: Bad Gateway

Any help is appreciated…

Is it possible to install Matrix on matrix.example.com only, without any changes to example.com (apart from name server entries)? The rationale: My webserver at example.com is quite a complex beast. More separation between different services would help to reduce complexity.

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Featured on Community

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel