Skip to content

Creating A Matrix Server Using Ansible


Things that you will

  • Domain
  • Email address for Let's Encrypt
  • Server where Matrix services will run

The default setup of the matrix server in this runbook is the following:

Name Setting
server synapse
database postgres
workers enabled
worker template one-of-each
prometheus enabled
grafana enabled
registration token based only
base domain served by matrix server

Additional configuration options can be seen in the appendixes and resources


Install Git and Ansible


sudo apt install git ansible

If you need a newer version of ansible you will need to add the ansible ppa

sudo add-apt-repository ppa:ansible/ansible
sudo apt-get update

Setup DNS Records

Setup A records for,, and

Record Reason Service host .well-know files for federation Matrix points to synapse server Matrix points to element web client Matrix points to grafana webui Grafana

Clone Git Repo

git clone


Remove Inventory Folder from .gitignore

Remove /inventory/* from .gitignore so that your inventory will be tracked in the git repo with following command

sed -i '/\/inventory\/\*/d' .gitignore

Set Variables for Matrix Server

To configure the playbook, you need to have done the following things:

You can then follow these steps inside the playbook directory:

  1. create a directory to hold your configuration (mkdir inventory/host_vars/

  2. copy the sample configuration file (cp examples/vars.yml inventory/host_vars/

  3. edit the configuration file (inventory/host_vars/ to your liking.

Base Domain

# Base domain for matrix server i.e.


# Enable nginx proxy to serve base domain and .well-known
matrix_nginx_proxy_base_domain_serving_enabled: true


# Setting type of homeserver either synapse or dendrite
matrix_homeserver_implementation: synapse

# A secret used as a base, for generating various other 
# secrets. You can put any string here, but generating a 
# strong one is preferred (e.g. `pwgen -s 64 1`).
matrix_homeserver_generic_secret_key: "Generate-a-string-this-will-used-to-generate-other-secrets"

Prometheus and Node and Postgres Exporters

# Enable prometheus which is a time series database for 
# holding metrics
matrix_prometheus_enabled: true

# Addon to prometheus that collects generic system 
# information such as CPU, memory, filesystem, and even 
# system temperatures
matrix_prometheus_node_exporter_enabled: true

# Addon to prometheus that collects metrics about postgres
matrix_prometheus_postgres_exporter_enabled: true


# Enables grafana web interface for viewing metrics in 
# prometheus
matrix_grafana_enabled: true

# Disables anonymous access to grafana
matrix_grafana_anonymous_access: false

# Sets default credentials for grafana access
matrix_grafana_default_admin_user: "user_name"
matrix_grafana_default_admin_password: "admin_password"


# Enable token and link based account registration
matrix_registration_enabled: true

# Set admin secret for generating tokens and links
matrix_registration_admin_secret: "admin_secret_for_generating_registration_links"


# Email address for getting ssl cert from Let's Encrypt
matrix_ssl_lets_encrypt_support_email: 'email_address'


# Set postgres password
matrix_postgres_connection_password: 'postgres_password'

# Enable automatic postgres backups
matrix_postgres_backup_enabled: true

# Setup what postgres backups to keep
matrix_postgres_backup_keep_days: 3
matrix_postgres_backup_keep_weeks: 0
matrix_postgres_backup_keep_months: 0


# Set coturn auth secret
matrix_coturn_turn_static_auth_secret: 'auth_secret_for_coturn'


# Enable workers for better performance and use workers 
# preset one-of-each
matrix_synapse_workers_enabled: true
matrix_synapse_workers_preset: one-of-each

# Turn off synapse open sign ups
matrix_synapse_enable_registration: false

# Set database transaction limit
matrix_synapse_database_txn_limit: 10000

# Set allowing public rooms over federation
matrix_synapse_allow_public_rooms_over_federation: true

# Turn off presense status for better performance
matrix_synapse_presence_enabled: false

# Enable synapse admin
matrix_synapse_admin_enabled: true

# Enable guest access
matrix_synapse_allow_guest_access: true

#Enable external password provider
matrix_synapse_ext_password_provider_shared_secret_auth_enabled: true
matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret: 'randomly-generated-string'


# Disable local identity server
matrix_ma1sd_enabled: false

You may also take a look at the various roles/ROLE_NAME_HERE/defaults/main.yml files and see if there's something you'd like to copy over and override in your vars.yml configuration file.

  1. copy the sample inventory hosts file

    cp examples/hosts inventory/hosts)

  2. edit the inventory hosts file (inventory/hosts) to your liking


[matrix_servers] ansible_host=<your-server's external IP address> ansible_ssh_user=root

Replace Example

[matrix_servers] ansible_host= ansible_ssh_user=root

Run Ansible Playbook

  1. Configure Matrix Server
ansible-playbook -i inventory/hosts setup.yml --tags=setup-all

If you don't use ssh keys then you will need to --ask-pass and if you use a non-root user with sudo priviledges then you will need to --ask-become-pass

  1. Start Matrix Server
ansible-playbook -i inventory/hosts setup.yml --tags=start

Appendix 1 - .Well-known setup on external server

# Disable nginx proxy to serve base domain and .well-known
matrix_nginx_proxy_base_domain_serving_enabled: false

Role Variables


Name Description Type Default
url Whether to create a local backup on the server String
matrix Whether to disable the default site in Nginx String

Example Playbook

Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:

- hosts: servers
     - well-known-deploy

Appendix 2 - Public Registration Setup

# Turn on synapse open sign ups
matrix_synapse_enable_registration: true

By default synapse requires some verification for open public registration either email or captcha based.

# Add email based verification
matrix_synapse_registrations_require_3pid: ['email']

or if you would rather have no verification add the following

# Add allowing no verification
matrix_synapse_enable_registration_without_verification: true

Appendix 3 - Migrating Matrix Server

  1. Sync Postgres and media-store from old server to new server by running the following on the new server

    mkdir -p /matrix/postgres
    mkdir -p /matrix/synapse/storage/media-store
    rsync -avz root@old-server-ip:/matrix/postgres /matrix/postgres
    rsync -avz root@old-server-ip:/matrix/synapse/storage/media-store /matrix/synapse/storage/media-store

  2. Repeat step one until sync duration is as short as possible

  3. Run ansible playbook to stop old server

    ansible-playbook -i inventory/hosts setup.yml --tags=stop

  4. Sync Postgres and media-store from old server to new server one last time

    rsync -avz root@old-server-ip:/matrix/postgres /matrix/postgres
    rsync -avz root@old-server-ip:/matrix/synapse/storage/media-store /matrix/synapse/storage/media-store

  5. Follow setup instruction above


Last update: 2023-11-29