| @@ -1,3 +1,35 @@ | |||
| # 2026-02-21 | |||
| ## (BC Break) coturn is no longer auto-enabled by default | |||
| By default, the [coturn](./docs/configuring-playbook-turn.md) TURN server component is no longer enabled for every deployment. | |||
| This reduces resources and attach surface for deployments which: | |||
| - either don't need calls at all | |||
| - or use the modern [Matrix RTC](docs/configuring-playbook-matrix-rtc.md)/[Element Call](docs/configuring-playbook-element-call.md) stack. | |||
| Coturn is still auto-enabled when [Jitsi](./docs/configuring-playbook-jitsi.md) is enabled (`jitsi_enabled: true`), because Jitsi still depends on TURN for legacy Matrix integration. | |||
| Additionally, Coturn (when enabled) now defaults to using automatic IP detection of your server's external IP address, instead of assuming your Ansible inventory (`ansible_host`) points to a public address and using it for configuring `coturn_turn_external_ip_address`. | |||
| To restore the old behavior (needed for legacy call setups), add the following configuration to your `vars.yml`: | |||
| ```yml | |||
| coturn_enabled: true | |||
| # If you'd like explicit control over the external IP address (like before), keep this too. | |||
| coturn_turn_external_ip_address: "{{ ansible_host }}" | |||
| ``` | |||
| ## LiveKit TURN TLS is now automatically fronted by playbook-managed Traefik | |||
| For deployments that use the playbook-managed Traefik reverse-proxy, LiveKit TURN over TCP is now SSL-terminated at Traefik and passed as plain TCP to LiveKit (`turn.external_tls = true`) by default. | |||
| To disable this behavior, set `livekit_server_config_turn_external_tls: false` and the playbook will revert to the old behavior - using traefik-certs-dumper to extract SSL certificates out of Traefik and pass them to LiveKit for explicit SSL termination there. | |||
| If you are using `other-traefik-container` or [another reverse-proxy](./configuring-playbook-own-webserver.md), this change does **not** switch behavior automatically. That mode remains using certificate files in the container (Traefik certificates dumper flow) unless you explicitly set the TURN-Traefik mode variables to opt in. | |||
| # 2026-02-17 | |||
| ## (BC Break) prometheus-nginxlog-exporter role has been relocated and variable names need adjustments | |||
| @@ -74,7 +74,7 @@ Services that run on the server to make the various parts of your installation w | |||
| | Name | Default? | Description | Documentation | | |||
| | ---- | -------- | ----------- | ------------- | | |||
| | [PostgreSQL](https://www.postgresql.org/)| ✅ | Database for Synapse. [Using an external PostgreSQL server](docs/configuring-playbook-external-postgres.md) is also possible. | [Link](docs/configuring-playbook-external-postgres.md) | | |||
| | [coturn](https://github.com/coturn/coturn) | ✅ | STUN/TURN server for WebRTC audio/video calls | [Link](docs/configuring-playbook-turn.md) | | |||
| | [coturn](https://github.com/coturn/coturn) | ❌ | STUN/TURN server for WebRTC audio/video calls | [Link](docs/configuring-playbook-turn.md) | | |||
| | [Traefik](https://doc.traefik.io/traefik/) | ✅ | Web server, listening on ports 80, 443 and 8448 - standing in front of all the other services. [Using your own webserver](docs/configuring-playbook-own-webserver.md) is also possible. | [Link](docs/configuring-playbook-traefik.md) | | |||
| | [Let's Encrypt](https://letsencrypt.org/) | ✅ | Free SSL certificate, which secures the connection to all components | [Link](docs/configuring-playbook-ssl-certificates.md) | | |||
| | [Exim](https://www.exim.org/) | ✅ | Mail server, through which all Matrix services send outgoing email (can be configured to relay through another SMTP server) | [Link](docs/configuring-playbook-email.md) | | |||
| @@ -18,6 +18,9 @@ SPDX-License-Identifier: AGPL-3.0-or-later | |||
| The playbook can install and configure the [Jitsi](https://jitsi.org/) video-conferencing platform for you. | |||
| Because Jitsi still requires a TURN server, enabling Jitsi | |||
| automatically enables coturn (`coturn_enabled: true`) unless you explicitly disable it. | |||
| Jitsi is an open source video-conferencing platform. It can not only be integrated with Element clients ([Element Web](configuring-playbook-client-element-web.md)/Desktop, Android and iOS) as a widget, but also be used as standalone web app. | |||
| 💡 If you're into experimental technology, you may also be interested in trying out [Element Call](configuring-playbook-element-call.md) - a native Matrix video conferencing application. | |||
| @@ -31,8 +31,39 @@ To ensure LiveKit Server functions correctly, the following firewall rules and p | |||
| 💡 The suggestions above are inspired by the upstream [Ports and Firewall](https://docs.livekit.io/home/self-hosting/ports-firewall/) documentation based on how LiveKit is configured in the playbook. If you've using custom configuration for the LiveKit Server role, you may need to adjust the firewall rules accordingly. | |||
| ## TURN TLS handling | |||
| When `matrix_playbook_reverse_proxy_type` is `playbook-managed-traefik` (which is the default for this playbook), TURN over TCP is terminated by Traefik and forwarded to LiveKit with `turn.external_tls = true`. In this playbook default, this mode is enabled automatically when SSL is enabled and TURN is enabled. | |||
| - The playbook installs a dedicated Traefik TCP entrypoint for TURN (`matrix-livekit-turn`) by default and binds it to `tcp/5350`. | |||
| - `livekit_server_config_turn_external_tls` is automatically enabled for this setup. | |||
| - Because Traefik handles TLS, LiveKit no longer needs certificate-file paths for TURN in this mode. | |||
| To opt out and keep TURN TLS termination in LiveKit itself, set: | |||
| ```yml | |||
| livekit_server_config_turn_external_tls: false | |||
| ``` | |||
| In this playbook, certificate paths are managed automatically via `group_vars/matrix_servers` when certificate dumping is enabled. | |||
| If your setup uses `other-traefik-container` or [another reverse-proxy](./configuring-playbook-own-webserver.md), behavior is unchanged by default and still relies on certificates being available inside the container as before. | |||
| Deployments using `other-traefik-container` can opt into the same Traefik-terminated mode there, by setting: | |||
| ```yml | |||
| livekit_server_config_turn_external_tls: true | |||
| livekit_server_container_labels_turn_traefik_enabled: true | |||
| livekit_server_container_labels_turn_traefik_entrypoints: "<your-livekit-turn-traffic-entrypoint>" | |||
| ``` | |||
| and configuring their own Traefik TCP entrypoint dedicated to LiveKit TURN traffic. | |||
| ## Limitations | |||
| For some reason, LiveKit Server's TURN ports (`3479/udp` and `5350/tcp`) are not reachable over IPv6 regardless of whether you've [enabled IPv6](./configuring-ipv6.md) for your server. | |||
| LiveKit Server's TURN listener behavior depends on where TLS is terminated: | |||
| - Direct LiveKit TURN listeners (`livekit_server_config_turn_external_tls: false`) still use IPv4-only sockets for `3479/udp` and `5350/tcp`, so IPv6 connectivity to these endpoints is not possible. | |||
| - With [TURN TLS handling](#turn-tls-handling) (`livekit_server_config_turn_external_tls: true`), the playbook's dedicated `matrix-livekit-turn` TCP entrypoint can still listen on both IPv4 and IPv6. Traefik then forwards TURN/TCP to LiveKit. | |||
| It seems like LiveKit Server intentionally only listens on `udp4` and `tcp4` as seen [here](https://github.com/livekit/livekit/blob/154b4d26b769c68a03c096124094b97bf61a996f/pkg/service/turn.go#L128) and [here](https://github.com/livekit/livekit/blob/154b4d26b769c68a03c096124094b97bf61a996f/pkg/service/turn.go#L92). | |||
| It appears that LiveKit Server intentionally only listens on `udp4` and `tcp4` in direct mode, as seen [here](https://github.com/livekit/livekit/blob/154b4d26b769c68a03c096124094b97bf61a996f/pkg/service/turn.go#L128) and [here](https://github.com/livekit/livekit/blob/154b4d26b769c68a03c096124094b97bf61a996f/pkg/service/turn.go#L92). | |||
| @@ -80,6 +80,29 @@ A separate Ansible role (`matrix-synapse-reverse-proxy-companion`) and component | |||
| In case any problems occur, make sure to have a look at the [list of synapse issues about workers](https://github.com/element-hq/synapse/issues?q=workers+in%3Atitle) and your `journalctl --unit 'matrix-*'`. | |||
| ### Limit joining heavy rooms on constrained hosts | |||
| If your server is underpowered, joining heavy rooms can cause Synapse to consume a lot of resources and be unavailable for long (while it catches up). | |||
| To avoid this, Synapse can be configured to reject joins for remote rooms that are too complex before users enter them. | |||
| Complexity is computed as `current_state_events / 500` (Synapse state event count for current room state). When the resulting value is higher than `matrix_synapse_limit_remote_rooms_complexity` and `matrix_synapse_limit_remote_rooms_enabled` is `true`, Synapse blocks joining the room. | |||
| We recommend using this as a guardrail on low-resource servers: | |||
| ```yaml | |||
| matrix_synapse_limit_remote_rooms_enabled: true | |||
| # Tweak as necessary | |||
| matrix_synapse_limit_remote_rooms_complexity: 1.0 | |||
| # Uncomment and tweak if necessary | |||
| # matrix_synapse_limit_remote_rooms_complexity_error: "Your homeserver is unable to join rooms this large or complex. Please speak to your server administrator, or upgrade your instance to join this room." | |||
| # If you'd like your admins to be exempt from this limit, uncomment the line below | |||
| # matrix_synapse_limit_remote_rooms_admins_can_join: true | |||
| ``` | |||
| ### Synapse + OpenID Connect for Single-Sign-On | |||
| 💡 An alternative to setting up OIDC in Synapse is to use [Matrix Authentication Service](./configuring-playbook-matrix-authentication-service.md) (MAS). Newer clients (like Element X) only support SSO-based authentication via MAS and not via the legacy Synapse OIDC setup described below. That said, MAS is still a new experimental service which comes with its own downsides. Consult its documentation to learn if it will be a good fit for your deployment. | |||
| @@ -13,34 +13,48 @@ SPDX-License-Identifier: AGPL-3.0-or-later | |||
| # Configuring a TURN server (optional, advanced) | |||
| By default, this playbook installs and configures the [coturn](https://github.com/coturn/coturn) as a TURN server, through which clients can make audio/video calls even from [NAT](https://en.wikipedia.org/wiki/Network_address_translation)-ed networks. It also configures the Synapse chat server by default, so that it points to the coturn TURN server installed by the playbook. If that's okay, you can skip this document. | |||
| By default, the [coturn](https://github.com/coturn/coturn) TURN server component is enabled automatically only when [Jitsi](configuring-playbook-jitsi.md) is enabled. If you're not using Jitsi, coturn is not enabled by default. | |||
| If you'd like to stop the playbook installing the server, see the section [below](#disabling-coturn) to check the configuration for disabling it. | |||
| If you explicitly need coturn while not using Jitsi, enable it with: | |||
| ```yaml | |||
| coturn_enabled: true | |||
| ``` | |||
| and configure its IP-related settings in the section below. | |||
| If you'd like coturn to stay disabled even when Jitsi is enabled, or if you prefer to use an external TURN provider, see [disabling coturn](#disabling-coturn) section below. | |||
| When Coturn is not enabled, homeservers (like Synapse) would not point to TURN servers and *legacy* audio/video call functionality may fail. If you're using [Matrix RTC](configuring-playbook-rtc.md) (for [Element Call](configuring-playbook-element-call.md)), you likely don't have a need to enable coturn. | |||
| ## Adjusting firewall rules | |||
| To ensure Coturn functions correctly, the following firewall rules and port forwarding settings are required when coturn is enabled: | |||
| - `3478/tcp`: STUN/TURN over TCP | |||
| - `3478/udp`: STUN/TURN over UDP | |||
| - `5349/tcp`: TURN over TCP | |||
| - `5349/udp`: TURN over UDP | |||
| - `49152-49172/udp`: TURN/UDP relay range | |||
| 💡 Docker configures the server's internal firewall for you. In most cases, you don't need to do anything special on the host itself. | |||
| ## Adjusting the playbook configuration | |||
| ### Define public IP manually (optional) | |||
| In the `hosts` file we explicitly ask for your server's external IP address when defining `ansible_host`, because the same value is used for configuring coturn. | |||
| If you'd rather use a local IP for `ansible_host`, add the following configuration to your `vars.yml` file. Make sure to replace `YOUR_PUBLIC_IP` with the pubic IP used by the server. | |||
| If you enable coturn (either via Jitsi or manually), we recommend that you configure the public IP addresses of your server in the `vars.yml` file: | |||
| ```yaml | |||
| coturn_turn_external_ip_address: "YOUR_PUBLIC_IP" | |||
| # You can define multiple IP addresses if your server has multiple external IP addresses | |||
| coturn_turn_external_ip_addresses: ["YOUR_PUBLIC_IP"] | |||
| ``` | |||
| If you'd like to rely on external IP address auto-detection (not recommended unless you need it), set an empty value to the variable. The playbook will automatically contact an [echoip](https://github.com/mpolden/echoip)-compatible service (`https://ifconfig.co/json` by default) to determine your server's IP address. This API endpoint is configurable via the `coturn_turn_external_ip_address_auto_detection_echoip_service_url` variable. | |||
| If you'd like to rely on external IP address auto-detection (not recommended unless you need it), avoid configuring this variable. The playbook will automatically contact an [echoip](https://github.com/mpolden/echoip)-compatible service (`https://ifconfig.co/json` by default) to determine your server's IP address. This API endpoint is configurable via the `coturn_turn_external_ip_address_auto_detection_echoip_service_url` variable. | |||
| >[!NOTE] | |||
| > You can self-host the echoip service by using the [Mother-of-All-Self-Hosting (MASH)](https://github.com/mother-of-all-self-hosting/mash-playbook) Ansible playbook. See [this page](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/services/echoip.md) for the instruction to install it with the playbook. If you are wondering how to use it for your Matrix server, refer to [this page](https://github.com/mother-of-all-self-hosting/mash-playbook/blob/main/docs/setting-up-services-on-mdad-server.md) for the overview. | |||
| If your server has multiple external IP addresses, the coturn role offers a different variable for specifying them: | |||
| ```yaml | |||
| # Note: coturn_turn_external_ip_addresses is different than coturn_turn_external_ip_address | |||
| coturn_turn_external_ip_addresses: ['1.2.3.4', '4.5.6.7'] | |||
| ``` | |||
| ### Change the authentication mechanism (optional) | |||
| The playbook uses the [`auth-secret` authentication method](https://github.com/coturn/coturn/blob/873cabd6a2e5edd7e9cc5662cac3ffe47fe87a8e/README.turnserver#L186-L199) by default, but you may switch to the [`lt-cred-mech` method](https://github.com/coturn/coturn/blob/873cabd6a2e5edd7e9cc5662cac3ffe47fe87a8e/README.turnserver#L178) which [some report](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/3191) to be working better. | |||
| @@ -119,14 +133,14 @@ Take a look at: | |||
| ## Disabling coturn | |||
| If, for some reason, you'd like for the playbook to not install coturn (or to uninstall it if it was previously installed), add the following configuration to your `vars.yml` file: | |||
| Coturn is only enabled by default when [Jitsi](configuring-playbook-jitsi.md) is enabled. In most instances, you don't need to explicitly disable it. | |||
| To force the playbook to not install Coturn (even when Jitsi is enabled), add the following configuration to your `vars.yml` file: | |||
| ```yaml | |||
| coturn_enabled: false | |||
| ``` | |||
| In that case, Synapse would not point to any coturn servers and audio/video call functionality may fail. | |||
| ## Installing | |||
| After configuring the playbook, run it with [playbook tags](playbook-tags.md) as below: | |||
| @@ -305,18 +305,23 @@ See [Serving the base domain](configuring-playbook-base-domain-serving.md). | |||
| ### How do I optimize this setup for a low-power server? | |||
| For a low-power server, it's best to use an alternative homeserver implementation (other than [Synapse](configuring-playbook-synapse.md)). | |||
| You can disable some not-so-important services to save on memory. | |||
| ```yaml | |||
| # Disabling this will prevent email-notifications and other such things from working. | |||
| exim_relay_enabled: false | |||
| ``` | |||
| # You can also disable this to save more RAM, | |||
| # at the expense of audio/video calls being unreliable. | |||
| coturn_enabled: false | |||
| If you've installed [Jitsi](configuring-playbook-jitsi.md) (not installed by default), there are additional optimizations listed on its documentation page that you can perform. | |||
| # This makes Synapse not keep track of who is online/offline. | |||
| # | |||
| #### Synapse-specific optimizations | |||
| If you're using [Synapse](configuring-playbook-synapse.md), you can also consider the following optimizations: | |||
| ```yaml | |||
| # Keeping track of this and announcing such online-status in federated rooms with | |||
| # hundreds of servers inside is insanely heavy (https://github.com/matrix-org/synapse/issues/3971). | |||
| # | |||
| @@ -324,18 +329,14 @@ coturn_enabled: false | |||
| matrix_synapse_presence_enabled: false | |||
| ``` | |||
| You can also consider implementing a restriction on room complexity, in order to prevent users from joining very heavy rooms: | |||
| You can also consider [implementing a restriction on room complexity](configuring-playbook-synapse.md#limit-joining-heavy-rooms-on-constrained-hosts), in order to prevent users from joining very heavy rooms: | |||
| ```yaml | |||
| matrix_synapse_configuration_extension_yaml: | | |||
| limit_remote_rooms: | |||
| enabled: true | |||
| complexity: 1.0 # this limits joining complex (~large) rooms, can be | |||
| # increased, but larger values can require more RAM | |||
| # See: docs/configuring-playbook-synapse.md#limit-joining-heavy-rooms-on-constrained-hosts | |||
| matrix_synapse_limit_remote_rooms_enabled: true | |||
| matrix_synapse_limit_remote_rooms_complexity: 1.0 | |||
| ``` | |||
| If you've installed [Jitsi](configuring-playbook-jitsi.md) (not installed by default), there are additional optimizations listed on its documentation page that you can perform. | |||
| ### I already have Docker on my server. Can you stop installing Docker via the playbook? | |||
| Yes, we can stop installing Docker ourselves. Just use this in your `vars.yml` file: | |||
| @@ -146,6 +146,7 @@ After completing the installation, you can: | |||
| - or learn how to [maintain your server](faq.md#maintenance) | |||
| - or join some Matrix rooms: | |||
| * via the *Explore rooms* feature in Element Web or some other clients, or by discovering them using this [matrix-static list](https://view.matrix.org). **Note**: joining large rooms may overload small servers. | |||
| For tuning guidance on constrained hosts, see [Limit joining heavy rooms on constrained hosts](configuring-playbook-synapse.md#limit-joining-heavy-rooms-on-constrained-hosts). | |||
| * or come say Hi in our support room — [#matrix-docker-ansible-deploy:devture.com](https://matrix.to/#/#matrix-docker-ansible-deploy:devture.com). You might learn something or get to help someone else new to Matrix hosting. | |||
| - or help make this playbook better by contributing (code, documentation, or [coffee/beer](https://liberapay.com/s.pantaleev/donate)) | |||
| @@ -83,6 +83,8 @@ You should then be able to browse the adminer database administration GUI at htt | |||
| Synapse's presence feature which tracks which users are online and which are offline can use a lot of processing power. You can disable presence by adding `matrix_synapse_presence_enabled: false` to your `vars.yml` file. | |||
| On smaller servers, consider limiting joins to very complex rooms with [the room complexity guard](configuring-playbook-synapse.md#limit-joining-heavy-rooms-on-constrained-hosts). | |||
| If you have enough compute resources (CPU & RAM), you can make Synapse better use of them by [enabling load-balancing with workers](configuring-playbook-synapse.md#load-balancing-with-workers). | |||
| [Tuning your PostgreSQL database](maintenance-postgres.md#tuning-postgresql) could also improve Synapse performance. The playbook tunes the integrated Postgres database automatically, but based on your needs you may wish to adjust tuning variables manually. If you're using an [external Postgres database](configuring-playbook-external-postgres.md), you will also need to tune Postgres manually. | |||
| @@ -57,12 +57,7 @@ We will be using `example.com` as the domain in the following instruction. Pleas | |||
| - `80/tcp`: HTTP webserver | |||
| - `443/tcp` and `443/udp`: HTTPS webserver | |||
| - `3478/tcp`: STUN/TURN over TCP (used by [coturn](./configuring-playbook-turn.md)) | |||
| - `3478/udp`: STUN/TURN over UDP (used by [coturn](./configuring-playbook-turn.md)) | |||
| - `5349/tcp`: TURN over TCP (used by [coturn](./configuring-playbook-turn.md)) | |||
| - `5349/udp`: TURN over UDP (used by [coturn](./configuring-playbook-turn.md)) | |||
| - `8448/tcp` and `8448/udp`: Matrix Federation API HTTPS webserver. Some components like [Matrix User Verification Service](configuring-playbook-user-verification-service.md#open-matrix-federation-port) require this port to be opened **even with federation disabled**. | |||
| - the range `49152-49172/udp`: TURN over UDP | |||
| - potentially some other ports, depending on the additional (non-default) services that you enable in the **configuring the playbook** step (later on). Consult each service's documentation page in `docs/` for that. | |||
| --------------------------------------------- | |||
| @@ -1,6 +1,3 @@ | |||
| # We explicitly ask for your server's external IP address, because the same value is used for configuring coturn. | |||
| # If you'd rather use a local IP here, make sure to set up `coturn_turn_external_ip_address`. | |||
| # | |||
| # To connect using a non-root user (and elevate to root with sudo later), | |||
| # replace `ansible_ssh_user=root` with something like this: `ansible_ssh_user=username ansible_become=true ansible_become_user=root`. | |||
| # If sudo requires a password, either add `ansible_become_password=PASSWORD_HERE` to the host line | |||
| @@ -18,4 +15,4 @@ | |||
| # to the host line below. | |||
| [matrix_servers] | |||
| matrix.example.com ansible_host=<your-server's external IP address> ansible_ssh_user=root | |||
| matrix.example.com ansible_host=<your-server's domain name or IP address> ansible_ssh_user=root | |||
| @@ -53,18 +53,10 @@ devture_systemd_docker_base_ipv6_enabled: true | |||
| # The value used here must be shorter than 100 characters. | |||
| postgres_connection_password: '' | |||
| # By default, we configure coturn's external IP address using the value specified for `ansible_host` in your `inventory/hosts` file. | |||
| # If this value is an external IP address, you can skip this section. | |||
| # | |||
| # If `ansible_host` is not the server's external IP address, you have 2 choices: | |||
| # 1. Uncomment the line below, to allow IP address auto-detection to happen (more on this below) | |||
| # 2. Uncomment and adjust the line below to specify an IP address manually | |||
| # | |||
| # By default, auto-detection will be attempted using the `https://ifconfig.co/json` API. | |||
| # Default values for this are specified in `coturn_turn_external_ip_address_auto_detection_*` variables in the coturn role | |||
| # (see `roles/galaxy/coturn/defaults/main.yml`). | |||
| # | |||
| # If your server has multiple IP addresses, you may define them in another variable which allows a list of addresses. | |||
| # Example: `coturn_turn_external_ip_addresses: ['1.2.3.4', '4.5.6.7']` | |||
| # You can limit heavy room joins on constrained hosts. | |||
| # See: | |||
| # docs/configuring-playbook-synapse.md#limit-joining-heavy-rooms-on-constrained-hosts | |||
| # | |||
| # coturn_turn_external_ip_address: '' | |||
| # matrix_synapse_limit_remote_rooms_enabled: true | |||
| # matrix_synapse_limit_remote_rooms_complexity: 1.0 | |||
| # matrix_synapse_limit_remote_rooms_admins_can_join: false | |||
| @@ -246,15 +246,14 @@ matrix_addons_homeserver_systemd_services_list: | | |||
| # - so that addon services (starting later) can communicte with the homeserver via Traefik's internal entrypoint | |||
| # (see `matrix_playbook_internal_matrix_client_api_traefik_entrypoint_enabled`) | |||
| # - core services (the homeserver) get a level of ~1000 | |||
| # - services that the homeserver depends on (database, Redis, ntfy, coturn, etc.) get a lower level — between 500 and 1000 | |||
| # - coturn gets a higher priority level (= starts later) if `devture_systemd_service_manager_service_restart_mode == 'one-by-one'` to intentionally delay it, because: | |||
| # - starting services one by one means that the service manager role waits for each service to fully start before proceeding to the next one | |||
| # - services that the homeserver depends on (database, Redis, ntfy, etc.) get a lower level — between 500 and 1000 | |||
| # - coturn gets a higher priority level (= starts later) in all cases, to intentionally delay it in relation to the homeserver, because: | |||
| # - when starting services one by one, the service manager waits for each service to fully start before proceeding to the next one | |||
| # - if coturn has a lower priority than the homeserver, it would be started before it | |||
| # - since coturn is started before the homeserver, there's no container label telling Traefik to get a `matrix.example.com` certificate | |||
| # - if coturn is started before the homeserver, there'd be no container label (usually on the homeserver) telling Traefik to get a `matrix.example.com` certificate | |||
| # - thus, coturn would spin and wait for a certificate until it fails. We'd get a playbook failure due to it, but service manager will proceed to start all other services anyway. | |||
| # - only later, when the homeserver actually starts, would that certificate be fetched and dumped | |||
| # - this is not a problem with `all-at-once` (default) or `priority-batched` (services start concurrently), | |||
| # or with `clean-stop-start` (everything stops first, then starts in priority order — coturn at 900 is fine) | |||
| # - this is a problem for `one-by-one`, `clean-stop-start` (which behaves like one-by-one initially) and possibly other modes, except `all-at-once` | |||
| # - reverse-proxying services get level 3000 | |||
| # - Matrix utility services (bridges, bots) get a level of 2000/2200, so that: | |||
| # - they can start before the reverse-proxy | |||
| @@ -607,14 +606,14 @@ devture_systemd_service_manager_services_list_auto: | | |||
| + | |||
| ([{ | |||
| 'name': ('matrix-' + matrix_homeserver_implementation + '.service'), | |||
| 'priority': 1000, | |||
| 'priority': matrix_homeserver_systemd_service_manager_priority, | |||
| 'restart_necessary': true, | |||
| 'groups': ['matrix', 'homeservers', matrix_homeserver_implementation], | |||
| }] if matrix_homeserver_enabled else []) | |||
| + | |||
| ([{ | |||
| 'name': 'matrix-corporal.service', | |||
| 'priority': 1500, | |||
| 'priority': (matrix_homeserver_systemd_service_manager_priority + 500), | |||
| 'restart_necessary': (matrix_corporal_restart_necessary | bool), | |||
| 'groups': ['matrix', 'corporal'], | |||
| }] if matrix_corporal_enabled else []) | |||
| @@ -635,7 +634,7 @@ devture_systemd_service_manager_services_list_auto: | | |||
| + | |||
| ([{ | |||
| 'name': (coturn_identifier + '.service'), | |||
| 'priority': (1500 if devture_systemd_service_manager_service_restart_mode == 'one-by-one' else 900), | |||
| 'priority': (matrix_homeserver_systemd_service_manager_priority + 500), | |||
| 'restart_necessary': (coturn_restart_necessary | bool), | |||
| 'groups': ['matrix', 'coturn'], | |||
| }] if coturn_enabled else []) | |||
| @@ -3498,7 +3497,9 @@ matrix_rageshake_container_labels_traefik_tls_certResolver: "{{ traefik_certReso | |||
| # | |||
| ###################################################################### | |||
| coturn_enabled: true | |||
| # Coturn is enabled by default only when Jitsi is enabled because Jitsi still | |||
| # depends on legacy TURN integration for compatibility. | |||
| coturn_enabled: "{{ jitsi_enabled | bool }}" | |||
| coturn_identifier: matrix-coturn | |||
| @@ -3514,11 +3515,6 @@ coturn_container_image_registry_prefix_upstream: "{{ matrix_container_global_reg | |||
| coturn_container_image_self_build: "{{ matrix_architecture not in ['amd64', 'arm32', 'arm64'] }}" | |||
| # We make the assumption that `ansible_host` points to an external IP address, which may not always be the case. | |||
| # Users are free to set `coturn_turn_external_ip_address` to an empty string | |||
| # to allow auto-detection (via an echoip service) to happen at runtime. | |||
| coturn_turn_external_ip_address: "{{ ansible_host }}" | |||
| # By default, we use the official public instance. | |||
| coturn_turn_external_ip_address_auto_detection_echoip_service_url: https://ifconfig.co/json | |||
| @@ -5945,6 +5941,8 @@ traefik_additional_entrypoints_auto: | | |||
| ([matrix_playbook_public_matrix_federation_api_traefik_entrypoint_definition] if matrix_playbook_public_matrix_federation_api_traefik_entrypoint_enabled else []) | |||
| + | |||
| ([matrix_playbook_internal_matrix_client_api_traefik_entrypoint_definition] if matrix_playbook_internal_matrix_client_api_traefik_entrypoint_enabled else []) | |||
| + | |||
| ([matrix_playbook_livekit_turn_traefik_entrypoint_definition] if matrix_playbook_livekit_turn_traefik_entrypoint_enabled else []) | |||
| }} | |||
| traefik_config_providers_docker_endpoint: "{{ container_socket_proxy_endpoint if container_socket_proxy_enabled else 'unix:///var/run/docker.sock' }}" | |||
| @@ -6104,6 +6102,11 @@ livekit_server_container_image_registry_prefix_upstream: "{{ matrix_container_gl | |||
| livekit_server_container_network: "{{ matrix_addons_container_network }}" | |||
| livekit_server_container_additional_networks_auto: "{{ [matrix_playbook_reverse_proxyable_services_additional_network] if (livekit_server_container_labels_traefik_enabled and matrix_playbook_reverse_proxyable_services_additional_network) else [] }}" | |||
| # We expose LiveKit TURN/TLS via Traefik on a dedicated TCP entrypoint. | |||
| matrix_playbook_livekit_turn_traefik_entrypoint_enabled: "{{ matrix_playbook_reverse_proxy_type == 'playbook-managed-traefik' and livekit_server_config_turn_enabled and livekit_server_config_turn_external_tls and livekit_server_container_labels_traefik_enabled }}" | |||
| matrix_playbook_livekit_turn_traefik_entrypoint_port: "{{ livekit_server_config_turn_tls_port }}" | |||
| matrix_playbook_livekit_turn_traefik_entrypoint_host_bind_port: "{{ (matrix_playbook_service_host_bind_interface_prefix ~ (matrix_playbook_livekit_turn_traefik_entrypoint_port | string)) if matrix_playbook_service_host_bind_interface_prefix else (matrix_playbook_livekit_turn_traefik_entrypoint_port | string) }}" | |||
| livekit_server_container_additional_volumes_auto: | | |||
| {{ | |||
| ( | |||
| @@ -6118,7 +6121,7 @@ livekit_server_container_additional_volumes_auto: | | |||
| 'dst': livekit_server_config_turn_key_file, | |||
| 'options': 'ro', | |||
| }, | |||
| ] if (matrix_playbook_reverse_proxy_type in ['playbook-managed-traefik', 'other-traefik-container'] and traefik_certs_dumper_enabled and livekit_server_config_turn_enabled and (livekit_server_config_turn_cert_file and livekit_server_config_turn_key_file)) else [] | |||
| ] if (matrix_playbook_reverse_proxy_type in ['playbook-managed-traefik', 'other-traefik-container'] and traefik_certs_dumper_enabled and livekit_server_config_turn_enabled and not (livekit_server_config_turn_external_tls | bool) and (livekit_server_config_turn_cert_file and livekit_server_config_turn_key_file)) else [] | |||
| ) | |||
| }} | |||
| @@ -6126,6 +6129,9 @@ livekit_server_container_labels_traefik_enabled: "{{ matrix_playbook_reverse_pro | |||
| livekit_server_container_labels_traefik_docker_network: "{{ matrix_playbook_reverse_proxyable_services_additional_network }}" | |||
| livekit_server_container_labels_traefik_entrypoints: "{{ traefik_entrypoint_primary }}" | |||
| livekit_server_container_labels_traefik_tls_certResolver: "{{ traefik_certResolver_primary }}" | |||
| livekit_server_container_labels_turn_traefik_enabled: "{{ matrix_playbook_livekit_turn_traefik_entrypoint_enabled }}" | |||
| livekit_server_container_labels_turn_traefik_entrypoints: "{{ matrix_playbook_livekit_turn_traefik_entrypoint_name }}" | |||
| livekit_server_container_labels_turn_traefik_tls_certResolver: "{{ traefik_certResolver_primary }}" | |||
| livekit_server_container_labels_public_metrics_middleware_basic_auth_enabled: "{{ matrix_metrics_exposure_http_basic_auth_enabled }}" | |||
| livekit_server_container_labels_public_metrics_middleware_basic_auth_users: "{{ matrix_metrics_exposure_http_basic_auth_users }}" | |||
| @@ -6164,15 +6170,19 @@ livekit_server_config_turn_tls_port: 5350 | |||
| # Note that TURN is not enabled by default. See `livekit_server_config_turn_enabled`. | |||
| livekit_server_config_turn_udp_port: 3479 | |||
| # LiveKit's TURN implementation requires SSL certificates. | |||
| # We only enable it if we can provide them automatically via Traefik + Traefik Certs Dumper. | |||
| livekit_server_config_turn_enabled: "{{ matrix_playbook_reverse_proxy_type in ['playbook-managed-traefik', 'other-traefik-container'] and traefik_certs_dumper_enabled }}" | |||
| # In this mode, Traefik terminates TURN/TLS and forwards plaintext TCP to LiveKit's `turn.tls_port`. | |||
| # We only enable it automatically when Traefik is managed by this playbook. | |||
| livekit_server_config_turn_external_tls: "{{ matrix_playbook_reverse_proxy_type == 'playbook-managed-traefik' and matrix_playbook_ssl_enabled }}" | |||
| # TURN stays enabled for either mode: | |||
| # - external TLS termination by playbook-managed Traefik | |||
| # - in-container TLS using certificates from Traefik Certs Dumper | |||
| livekit_server_config_turn_enabled: "{{ matrix_playbook_reverse_proxy_type in ['playbook-managed-traefik', 'other-traefik-container'] and (livekit_server_config_turn_external_tls or traefik_certs_dumper_enabled) }}" | |||
| livekit_server_config_turn_cert_file: |- | |||
| {{ | |||
| { | |||
| 'playbook-managed-traefik': ('/certificate.crt' if traefik_certs_dumper_enabled else ''), | |||
| 'other-traefik-container': ('/certificate.crt' if traefik_certs_dumper_enabled else ''), | |||
| 'playbook-managed-traefik': ('/certificate.crt' if traefik_certs_dumper_enabled and not (livekit_server_config_turn_external_tls | bool) else ''), | |||
| 'other-traefik-container': ('/certificate.crt' if traefik_certs_dumper_enabled and not (livekit_server_config_turn_external_tls | bool) else ''), | |||
| 'none': '', | |||
| }[matrix_playbook_reverse_proxy_type] | |||
| }} | |||
| @@ -6180,15 +6190,15 @@ livekit_server_config_turn_cert_file: |- | |||
| livekit_server_config_turn_key_file: |- | |||
| {{ | |||
| { | |||
| 'playbook-managed-traefik': ('/privatekey.key' if traefik_certs_dumper_enabled else ''), | |||
| 'other-traefik-container': ('/privatekey.key' if traefik_certs_dumper_enabled else ''), | |||
| 'playbook-managed-traefik': ('/privatekey.key' if traefik_certs_dumper_enabled and not (livekit_server_config_turn_external_tls | bool) else ''), | |||
| 'other-traefik-container': ('/privatekey.key' if traefik_certs_dumper_enabled and not (livekit_server_config_turn_external_tls | bool) else ''), | |||
| 'none': '', | |||
| }[matrix_playbook_reverse_proxy_type] | |||
| }} | |||
| livekit_server_systemd_required_services_list_auto: | | |||
| {{ | |||
| ([traefik_certs_dumper_identifier + '-wait-for-domain@' + livekit_server_config_turn_domain + '.service'] if matrix_playbook_reverse_proxy_type in ['playbook-managed-traefik', 'other-traefik-container'] and traefik_certs_dumper_enabled and livekit_server_config_turn_enabled else []) | |||
| ([traefik_certs_dumper_identifier + '-wait-for-domain@' + livekit_server_config_turn_domain + '.service'] if matrix_playbook_reverse_proxy_type in ['playbook-managed-traefik', 'other-traefik-container'] and traefik_certs_dumper_enabled and livekit_server_config_turn_enabled and not (livekit_server_config_turn_external_tls | bool) else []) | |||
| }} | |||
| ######################################################################## | |||
| @@ -7,7 +7,7 @@ | |||
| version: v1.4.3-2.1.1-1 | |||
| name: backup_borg | |||
| - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-cinny.git | |||
| version: v4.10.3-0 | |||
| version: v4.10.5-0 | |||
| name: cinny | |||
| - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-container-socket-proxy.git | |||
| version: v0.4.2-3 | |||
| @@ -42,7 +42,7 @@ | |||
| version: v10741-0 | |||
| name: jitsi | |||
| - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-livekit-server.git | |||
| version: v1.9.11-1 | |||
| version: v1.9.11-2 | |||
| name: livekit_server | |||
| - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-ntfy.git | |||
| version: v2.17.0-1 | |||
| @@ -84,7 +84,7 @@ | |||
| version: v1.1.0-1 | |||
| name: timesync | |||
| - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-traefik.git | |||
| version: v3.6.8-4 | |||
| version: v3.6.9-0 | |||
| name: traefik | |||
| - src: git+https://github.com/mother-of-all-self-hosting/ansible-role-traefik-certs-dumper.git | |||
| version: v2.10.0-5 | |||
| @@ -92,6 +92,10 @@ matrix_homeserver_enabled: true | |||
| # Note that the homeserver implementation of a server will not be able to be changed without data loss. | |||
| matrix_homeserver_implementation: synapse | |||
| # The priority that the homeserver starts with (lower = starts earlier). | |||
| # Related to the systemd_service_manager role and `devture_systemd_service_manager_services_list*` variables. | |||
| matrix_homeserver_systemd_service_manager_priority: 1000 | |||
| # This contains a secret, which is used for generating various other secrets later on. | |||
| matrix_homeserver_generic_secret_key: '' | |||
| @@ -393,6 +397,22 @@ matrix_playbook_internal_matrix_client_api_traefik_entrypoint_definition: | |||
| host_bind_port: "{{ matrix_playbook_internal_matrix_client_api_traefik_entrypoint_host_bind_port }}" | |||
| config: "{{ matrix_playbook_internal_matrix_client_api_traefik_entrypoint_config }}" | |||
| # Controls whether to enable an additional Traefik entrypoint for LiveKit TURN/TLS (TCP) traffic. | |||
| matrix_playbook_livekit_turn_traefik_entrypoint_enabled: false | |||
| matrix_playbook_livekit_turn_traefik_entrypoint_name: matrix-livekit-turn | |||
| matrix_playbook_livekit_turn_traefik_entrypoint_port: 5350 | |||
| matrix_playbook_livekit_turn_traefik_entrypoint_host_bind_port: "{{ matrix_playbook_livekit_turn_traefik_entrypoint_port }}" | |||
| matrix_playbook_livekit_turn_traefik_entrypoint_config: "{{ (matrix_playbook_livekit_turn_traefik_entrypoint_config_default | combine(matrix_playbook_livekit_turn_traefik_entrypoint_config_auto)) | combine(matrix_playbook_livekit_turn_traefik_entrypoint_config_custom, recursive=True) }}" | |||
| matrix_playbook_livekit_turn_traefik_entrypoint_config_default: {} | |||
| matrix_playbook_livekit_turn_traefik_entrypoint_config_auto: {} | |||
| matrix_playbook_livekit_turn_traefik_entrypoint_config_custom: {} | |||
| matrix_playbook_livekit_turn_traefik_entrypoint_definition: | |||
| name: "{{ matrix_playbook_livekit_turn_traefik_entrypoint_name }}" | |||
| port: "{{ matrix_playbook_livekit_turn_traefik_entrypoint_port }}" | |||
| host_bind_port: "{{ matrix_playbook_livekit_turn_traefik_entrypoint_host_bind_port }}" | |||
| config: "{{ matrix_playbook_livekit_turn_traefik_entrypoint_config }}" | |||
| # Variables to Control which parts of our roles run. | |||
| run_postgres_import: true | |||
| run_postgres_upgrade: true | |||
| @@ -121,6 +121,10 @@ matrix_static_files_environment_variable_server_log_remote_address: false | |||
| # See: https://static-web-server.net/configuration/environment-variables/ | |||
| matrix_static_files_environment_variable_server_config_file: /config/config.toml | |||
| # Controls the SERVER_IGNORE_HIDDEN_FILES environment variable. | |||
| # See: https://static-web-server.net/configuration/environment-variables/ | |||
| matrix_static_files_environment_variable_server_ignore_hidden_files: false | |||
| # Additional environment variables. | |||
| matrix_static_files_environment_variables_additional_variables: '' | |||
| @@ -10,5 +10,6 @@ SERVER_LOG_LEVEL={{ matrix_static_files_environment_variable_server_log_level }} | |||
| SERVER_LOG_REMOTE_ADDRESS={{ 'true' if matrix_static_files_environment_variable_server_log_remote_address else 'false' }} | |||
| SERVER_CONFIG_FILE={{ matrix_static_files_environment_variable_server_config_file }} | |||
| SERVER_IGNORE_HIDDEN_FILES={{ matrix_static_files_environment_variable_server_ignore_hidden_files | to_json }} | |||
| {{ matrix_static_files_environment_variables_additional_variables }} | |||
| @@ -570,6 +570,21 @@ matrix_synapse_report_stats_endpoint: "https://matrix.org/report-usage-stats/pus | |||
| # disabling this will decrease server load significantly. | |||
| matrix_synapse_presence_enabled: true | |||
| # Controls whether remote room complexity checks are enabled when joining rooms. | |||
| # When enabled, Synapse checks a room's complexity before joining a remote room. | |||
| # Complexity is measured as `current_state_events / 500` and can prevent | |||
| # users from joining very large/active rooms on constrained servers. | |||
| matrix_synapse_limit_remote_rooms_enabled: false | |||
| # Maximum complexity allowed before join is blocked. | |||
| matrix_synapse_limit_remote_rooms_complexity: 1.0 | |||
| # Error message returned when a user attempts to join a too-complex room. | |||
| matrix_synapse_limit_remote_rooms_complexity_error: "Your homeserver is unable to join rooms this large or complex. Please speak to your server administrator, or upgrade your instance to join this room." | |||
| # Allow server admins to join rooms even when they exceed the complexity limit. | |||
| matrix_synapse_limit_remote_rooms_admins_can_join: false | |||
| # Controls whether accessing the server's public rooms directory can be done without authentication. | |||
| # For private servers, you most likely wish to require authentication, | |||
| # unless you know what list of rooms you're publishing to the world and explicitly want to do it. | |||
| @@ -452,30 +452,11 @@ admin_contact: {{ matrix_synapse_admin_contact | to_json }} | |||
| #server_context: context | |||
| # Resource-constrained homeserver settings | |||
| # | |||
| # When this is enabled, the room "complexity" will be checked before a user | |||
| # joins a new remote room. If it is above the complexity limit, the server will | |||
| # disallow joining, or will instantly leave. | |||
| # | |||
| # Room complexity is an arbitrary measure based on factors such as the number of | |||
| # users in the room. | |||
| # | |||
| limit_remote_rooms: | |||
| # Uncomment to enable room complexity checking. | |||
| # | |||
| #enabled: true | |||
| # the limit above which rooms cannot be joined. The default is 1.0. | |||
| # | |||
| #complexity: 0.5 | |||
| # override the error which is returned when the room is too complex. | |||
| # | |||
| #complexity_error: "This room is too complex." | |||
| # allow server admins to join complex rooms. Default is false. | |||
| # | |||
| #admins_can_join: true | |||
| enabled: {{ matrix_synapse_limit_remote_rooms_enabled | to_json }} | |||
| complexity: {{ matrix_synapse_limit_remote_rooms_complexity | to_json }} | |||
| complexity_error: {{ matrix_synapse_limit_remote_rooms_complexity_error | to_json }} | |||
| admins_can_join: {{ matrix_synapse_limit_remote_rooms_admins_can_join | to_json }} | |||
| # Whether to require a user to be in the room to add an alias to it. | |||
| # Defaults to 'true'. | |||