
Matrix is a set of open APIs for decentralized and end-to-end encrypted communication. It works across a collection of federation servers to deliver instant messages, Voice over IP (VoIP), and Internet of Things (IoT) communication in real time. Matrix uses homeservers to store account information and chat history, and federation works like email, so you can either use a server hosted by somebody else or host your own. Synapse is the homeserver implementation maintained by the Matrix.org team, and Element is the most widely used Matrix client.
This article explains how to run a self-hosted chat server on an Ubuntu 22.04 server. After completing the steps, you have a Synapse homeserver backed by PostgreSQL, served over HTTPS through Nginx, with a Coturn TURN server for voice and video calls and a self-hosted Element web client.
Before you begin, you need to:
matrix.example.com, element.example.com, and coturn.example.com pointing to your server's public IP address.Synapse serves both client traffic and federation traffic, and each arrives on a different port. Open those ports before installing the packages so that certificate issuance and federation succeed once the services start.
Allow HTTP traffic.
Allow HTTPS traffic.
Allow the Matrix federation port.
Review the active rules.
The output displays 80, 443, and 8448 with an ALLOW action.
Ubuntu does not package Synapse, so the packages come from the official Matrix.org APT repository. Signing the repository with a dedicated keyring restricts that key to this repository alone.
Download the repository signing key.
Add the Matrix repository and bind it to the keyring.
Update the package index.
Install Synapse.
The installer prompts for a server name. Enter your Matrix domain name, such as example.com. Enter N to decline reporting of anonymized statistics.
The server name becomes part of every user ID on the homeserver and is difficult to change after users exist. To change it later, edit the /etc/matrix-synapse/conf.d/server_name.yaml file.
Synapse uses SQLite by default, which does not perform well enough for a production homeserver. PostgreSQL is the supported production database, and Synapse expects it to be created with a specific locale and character encoding.
Install PostgreSQL.
Open the PostgreSQL shell.
Create the Synapse database role. Replace DB-PASSWORD with a strong password.
The role is created and can log in with the password you set.
Create the Synapse database owned by that role.
The database is created and owned by the Synapse role. Synapse refuses to start against a database created with any other collation.
Exit the shell.
Nginx terminates TLS and proxies client and federation requests to Synapse. Ubuntu 22.04 ships an older Nginx release, so install the current version from the official Nginx repository.
Download the Nginx signing key.
Add the Nginx repository.
Verify that the repository file exists.
The output displays the repository line. An empty result means the file was not written, and apt installs the older Ubuntu package instead.
Update the package index.
Install Nginx.
Start Nginx.
Matrix clients and federating servers both require valid TLS. Certbot issues free certificates from Let's Encrypt, and the Nginx plugin handles the HTTP challenge automatically.
Install Certbot and the Nginx plugin.
Verify the installed version.
The output displays the Certbot version.
Issue the certificate for the Matrix subdomain. Replace name@example.com with your email address and matrix.example.com with your Matrix subdomain.
Generate a Diffie-Hellman parameter file.
The command takes several minutes to complete.
Verify that automatic renewal works.
The package manager overwrites the main Synapse configuration file during updates, so production settings belong in separate files in the drop-in configuration directory. Synapse merges every file in that directory at startup, which keeps your changes safe across upgrades.
Create the database configuration file.
Add the following configuration. Replace DB-PASSWORD with the password you set in Install and Configure PostgreSQL.
Save and close the file.
name: psycopg2: Selects the PostgreSQL driver instead of the default SQLite driver.cp_min and cp_max: Set the minimum and maximum size of the database connection pool.Generate a registration shared secret.
Restart Synapse so that it connects to PostgreSQL and loads the shared secret.
Verify that Synapse is running.
Verify that the output reports Active: active (running). Synapse creates its schema in synapsedb on this first start, which takes up to a minute.
Create an administrator account. Enter a username and password when prompted, then type yes to grant administrator rights.
The output displays Success! when the account is created.
Create a registration configuration file to allow public sign-ups.
Add the following configuration to enable registration with email verification. Replace SMTP-PASSWORD with the password for the sending mailbox, and the remaining mail server values with your own.
To skip verification instead, replace the registrations_require_3pid and email blocks with the following line.
Save and close the file.
Create a presence configuration file.
Add the following configuration.
Save and close the file.
Synapse tracks each user's online status by default, which raises CPU usage on small servers. Disabling presence removes that overhead.
Restart Synapse to apply the changes.
Synapse listens only on the loopback interface and does not terminate TLS itself. Nginx accepts public traffic, handles TLS, and forwards the Matrix client and federation requests to Synapse.
Open the main Nginx configuration file.
Add the following directive inside the http block, before the include /etc/nginx/conf.d/*.conf; line.
Save and close the file.
Create the Synapse site configuration.
Add the following configuration. Replace matrix.example.com with your Matrix subdomain.
Save and close the file.
http2 on;: Enables HTTP/2 for the server block. Nginx 1.25.1 and later deprecate the older listen ... http2 form and log a warning for every listener that uses it.client_max_body_size: Raises the upload limit from the 1 MB Nginx default so that media uploads succeed.Test the configuration syntax.
The output displays syntax is ok and test is successful.
Restart Nginx.
Voice and video calls between clients behind NAT require a Traversal Using Relays around NAT (TURN) server. Coturn relays that media, and Synapse hands out short-lived credentials generated from a shared secret.
Install Coturn.
Allow the TURN control ports.
Allow the TURN TLS port.
Allow the media relay port range.
Issue a certificate for the Coturn subdomain. Replace coturn.example.com with your Coturn subdomain.
Back up the default configuration file.
Generate an authentication secret and write it to a new configuration file.
The command prints the generated secret. Copy the value, because Synapse needs it later in this section.
Open the Coturn configuration file.
Add the following configuration below the authentication secret. Replace coturn.example.com with your Coturn subdomain.
Save and close the file.
use-auth-secret: Enables the shared-secret authentication mode that Synapse expects.denied-peer-ip: Blocks relaying to private and reserved address ranges, which prevents the TURN server from reaching internal services.Restart Coturn.
Create the Synapse TURN configuration file.
Add the following configuration. Replace YOUR-STATIC-AUTH-SECRET with the static-auth-secret value from /etc/turnserver.conf, and coturn.example.com with your Coturn subdomain.
Save and close the file.
Restart Synapse to apply the configuration.
The homeserver is now reachable over HTTPS, so any Matrix client can sign in to it. Use a hosted client to confirm the deployment before setting up your own Element instance.
Open a Matrix client such as the Element web app, or install the desktop or mobile app. Other options are listed in the Matrix client directory.
Select Sign in, then edit the homeserver address and enter your Matrix subdomain.
Sign in with the administrator account you created in Configure Synapse.
Create a secure backup for your encrypted messages using a security key or passphrase when the client prompts you.
Hosting your own Element instance serves the client from your domain rather than a third-party site. Element ships as a prebuilt archive that Nginx serves as static files.
Install the JSON processor used to read the release metadata.
Create the web root for Element.
Change to the directory.
Store the latest release tag in a variable.
Verify that the variable holds a version tag.
The output displays a tag such as v1.12.25. An empty value or null means the request failed, and the download in the next step produces a broken filename.
Download the release archive.
Extract the archive.
Link the extracted directory to a stable path.
Repoint the link when you upgrade Element later, after downloading and extracting the new archive. Replace NEW-VERSION with the new release tag.
Element reads its settings from a configuration file in the web root. The shipped sample points at the public matrix.org homeserver, so you must change it to your own before the client is usable.
Change to the current directory.
Create the configuration file from the sample.
Open the configuration file.
Edit the default homeserver settings to point at your own server.
m.homeserver: Nested under the default server configuration block near the top of the file.base_url: The address Element connects to, which is your Matrix subdomain.server_name: The server name you entered when installing Synapse.Change the brand name to customize the page title.
Set disable_guests to prevent guest access.
Save and close the file.
Issue a certificate for the Element subdomain. Replace element.example.com with your Element subdomain.
Create the Element site configuration.
Add the following configuration. Replace element.example.com with your Element subdomain.
Save and close the file.
Test the configuration syntax.
The output displays syntax is ok and test is successful.
Restart Nginx.
Open your Element subdomain in a web browser and sign in with your Matrix account.
You have deployed a self-hosted Matrix chat server on Ubuntu 22.04, with Synapse storing data in PostgreSQL, Nginx serving client and federation traffic over HTTPS, Coturn relaying voice and video calls, and a self-hosted Element web client signing in against your own homeserver. For further configuration such as federation tuning, media retention, and worker processes, see the Synapse documentation and the Element web configuration reference.
0 Comments
Be the first to comment and share your perspective with the community.