mirror of
https://github.com/spantaleev/matrix-docker-ansible-deploy.git
synced 2026-05-19 20:38:02 +00:00
matrix-tuwunel: add Tuwunel homeserver role (#5200)
Tuwunel is a Matrix homeserver maintained by the matrix-construct organisation. See https://matrix-construct.github.io/tuwunel/. The rendered TOML emits only keys exposed as Ansible variables; the rest fall back to tuwunel's upstream defaults. Anything not surfaced can be set via the TUWUNEL_* env extension or by overriding the template path. Popular features Tuwunel adds variables for: - OAuth2/OIDC identity providers (a list of `[[global.identity_provider]]` blocks; brand-aware defaults for Google, GitHub, Keycloak, MAS, etc) - LDAP and JWT authentication - Media storage providers (native local and S3 with multipart upload) - RocksDB tuning (compression, direct_io, parallelism, online backups) - Native TLS dual-protocol mode - Blurhashing, Sentry crash reporting Auto-wired from existing playbook globals: well-known client URL, TURN/coturn, MatrixRTC LiveKit URL, federation. The `tuwunel-migrate-from-conduwuit` tag performs a binary-swap migration. Migration from any other Conduit derivative is unsupported and would corrupt the database. Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
@@ -84,7 +84,7 @@ matrix_monitoring_container_network: matrix-monitoring
|
||||
matrix_homeserver_enabled: true
|
||||
|
||||
# This will contain the homeserver implementation that is in use.
|
||||
# Valid values: synapse, dendrite, conduit, continuwuity
|
||||
# Valid values: synapse, dendrite, conduit, continuwuity, tuwunel
|
||||
#
|
||||
# By default, we use Synapse, because it's the only full-featured Matrix server at the moment.
|
||||
#
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
- name: Fail if invalid homeserver implementation
|
||||
ansible.builtin.fail:
|
||||
msg: "You need to set a valid homeserver implementation in `matrix_homeserver_implementation`"
|
||||
when: "matrix_homeserver_implementation not in ['synapse', 'dendrite', 'conduit', 'continuwuity']"
|
||||
when: "matrix_homeserver_implementation not in ['synapse', 'dendrite', 'conduit', 'continuwuity', 'tuwunel']"
|
||||
|
||||
- name: (Deprecation) Catch and report renamed settings
|
||||
ansible.builtin.fail:
|
||||
|
||||
315
roles/custom/matrix-tuwunel/defaults/main.yml
Normal file
315
roles/custom/matrix-tuwunel/defaults/main.yml
Normal file
@@ -0,0 +1,315 @@
|
||||
# SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
# SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
---
|
||||
# Tuwunel is a Matrix homeserver, the official successor to conduwuit.
|
||||
# Project source code URL: https://github.com/matrix-construct/tuwunel
|
||||
# See: https://matrix-construct.github.io/tuwunel/
|
||||
|
||||
matrix_tuwunel_enabled: true
|
||||
|
||||
matrix_tuwunel_hostname: ''
|
||||
|
||||
# renovate: datasource=docker depName=ghcr.io/matrix-construct/tuwunel
|
||||
matrix_tuwunel_version: latest
|
||||
|
||||
matrix_tuwunel_container_image: "{{ matrix_tuwunel_container_image_registry_prefix }}matrix-construct/tuwunel:{{ matrix_tuwunel_container_image_tag }}"
|
||||
matrix_tuwunel_container_image_tag: "{{ matrix_tuwunel_version }}"
|
||||
matrix_tuwunel_container_image_registry_prefix: "{{ matrix_tuwunel_container_image_registry_prefix_upstream }}"
|
||||
matrix_tuwunel_container_image_registry_prefix_upstream: "{{ matrix_tuwunel_container_image_registry_prefix_upstream_default }}"
|
||||
matrix_tuwunel_container_image_registry_prefix_upstream_default: ghcr.io/
|
||||
|
||||
matrix_tuwunel_base_path: "{{ matrix_base_data_path }}/tuwunel"
|
||||
matrix_tuwunel_config_path: "{{ matrix_tuwunel_base_path }}/config"
|
||||
matrix_tuwunel_data_path: "{{ matrix_tuwunel_base_path }}/data"
|
||||
|
||||
matrix_tuwunel_config_port_number: 6167
|
||||
|
||||
matrix_tuwunel_tmp_directory_size_mb: 500
|
||||
|
||||
# List of systemd services that matrix-tuwunel.service depends on
|
||||
matrix_tuwunel_systemd_required_services_list: "{{ matrix_tuwunel_systemd_required_services_list_default + matrix_tuwunel_systemd_required_services_list_auto + matrix_tuwunel_systemd_required_services_list_custom }}"
|
||||
matrix_tuwunel_systemd_required_services_list_default: "{{ [devture_systemd_docker_base_docker_service_name] if devture_systemd_docker_base_docker_service_name else [] }}"
|
||||
matrix_tuwunel_systemd_required_services_list_auto: []
|
||||
matrix_tuwunel_systemd_required_services_list_custom: []
|
||||
|
||||
# List of systemd services that matrix-tuwunel.service wants
|
||||
matrix_tuwunel_systemd_wanted_services_list: "{{ matrix_tuwunel_systemd_wanted_services_list_default + matrix_tuwunel_systemd_wanted_services_list_auto + matrix_tuwunel_systemd_wanted_services_list_custom }}"
|
||||
matrix_tuwunel_systemd_wanted_services_list_default: []
|
||||
matrix_tuwunel_systemd_wanted_services_list_auto: []
|
||||
matrix_tuwunel_systemd_wanted_services_list_custom: []
|
||||
|
||||
# Controls how long to sleep for after starting the matrix-tuwunel container,
|
||||
# so that subsequent services that depend on it can start after the homeserver
|
||||
# is fully up.
|
||||
#
|
||||
# Set to 0 to remove the delay.
|
||||
matrix_tuwunel_systemd_service_post_start_delay_seconds: 3
|
||||
|
||||
# The base container network. It will be auto-created by this role if it doesn't exist already.
|
||||
matrix_tuwunel_container_network: ""
|
||||
|
||||
# A list of additional container networks that the container would be connected to.
|
||||
# The role does not create these networks, so make sure they already exist.
|
||||
# Use this to expose this container to another reverse proxy, which runs in a different container network.
|
||||
matrix_tuwunel_container_additional_networks: "{{ matrix_tuwunel_container_additional_networks_auto + matrix_tuwunel_container_additional_networks_custom }}"
|
||||
matrix_tuwunel_container_additional_networks_auto: []
|
||||
matrix_tuwunel_container_additional_networks_custom: []
|
||||
|
||||
# matrix_tuwunel_container_labels_traefik_enabled controls whether labels to assist a Traefik reverse-proxy will be attached to the container.
|
||||
# See `../templates/labels.j2` for details.
|
||||
#
|
||||
# To inject your own other container labels, see `matrix_tuwunel_container_labels_additional_labels`.
|
||||
matrix_tuwunel_container_labels_traefik_enabled: true
|
||||
matrix_tuwunel_container_labels_traefik_docker_network: "{{ matrix_tuwunel_container_network }}"
|
||||
matrix_tuwunel_container_labels_traefik_entrypoints: web-secure
|
||||
matrix_tuwunel_container_labels_traefik_tls_certResolver: default # noqa var-naming
|
||||
|
||||
# Controls whether labels will be added for handling the root (/) path on a public Traefik entrypoint.
|
||||
matrix_tuwunel_container_labels_public_client_root_enabled: true
|
||||
matrix_tuwunel_container_labels_public_client_root_traefik_hostname: "{{ matrix_tuwunel_hostname }}"
|
||||
matrix_tuwunel_container_labels_public_client_root_traefik_rule: "Host(`{{ matrix_tuwunel_container_labels_public_client_root_traefik_hostname }}`) && Path(`/`)"
|
||||
matrix_tuwunel_container_labels_public_client_root_traefik_priority: 0
|
||||
matrix_tuwunel_container_labels_public_client_root_traefik_entrypoints: "{{ matrix_tuwunel_container_labels_traefik_entrypoints }}"
|
||||
matrix_tuwunel_container_labels_public_client_root_traefik_tls: "{{ matrix_tuwunel_container_labels_public_client_root_traefik_entrypoints != 'web' }}"
|
||||
matrix_tuwunel_container_labels_public_client_root_traefik_tls_certResolver: "{{ matrix_tuwunel_container_labels_traefik_tls_certResolver }}" # noqa var-naming
|
||||
matrix_tuwunel_container_labels_public_client_root_redirection_enabled: false
|
||||
matrix_tuwunel_container_labels_public_client_root_redirection_url: ""
|
||||
|
||||
# Controls whether labels will be added that expose the Client-Server API on a public Traefik entrypoint.
|
||||
matrix_tuwunel_container_labels_public_client_api_enabled: true
|
||||
matrix_tuwunel_container_labels_public_client_api_traefik_hostname: "{{ matrix_tuwunel_hostname }}"
|
||||
matrix_tuwunel_container_labels_public_client_api_traefik_path_prefix: /_matrix
|
||||
matrix_tuwunel_container_labels_public_client_api_traefik_rule: "Host(`{{ matrix_tuwunel_container_labels_public_client_api_traefik_hostname }}`) && PathPrefix(`{{ matrix_tuwunel_container_labels_public_client_api_traefik_path_prefix }}`)"
|
||||
matrix_tuwunel_container_labels_public_client_api_traefik_priority: 0
|
||||
matrix_tuwunel_container_labels_public_client_api_traefik_entrypoints: "{{ matrix_tuwunel_container_labels_traefik_entrypoints }}"
|
||||
matrix_tuwunel_container_labels_public_client_api_traefik_tls: "{{ matrix_tuwunel_container_labels_public_client_api_traefik_entrypoints != 'web' }}"
|
||||
matrix_tuwunel_container_labels_public_client_api_traefik_tls_certResolver: "{{ matrix_tuwunel_container_labels_traefik_tls_certResolver }}" # noqa var-naming
|
||||
|
||||
# Controls whether labels will be added that expose the Client-Server API on the internal Traefik entrypoint.
|
||||
matrix_tuwunel_container_labels_internal_client_api_enabled: false
|
||||
matrix_tuwunel_container_labels_internal_client_api_traefik_path_prefix: "{{ matrix_tuwunel_container_labels_public_client_api_traefik_path_prefix }}"
|
||||
matrix_tuwunel_container_labels_internal_client_api_traefik_rule: "PathPrefix(`{{ matrix_tuwunel_container_labels_internal_client_api_traefik_path_prefix }}`)"
|
||||
matrix_tuwunel_container_labels_internal_client_api_traefik_priority: "{{ matrix_tuwunel_container_labels_public_client_api_traefik_priority }}"
|
||||
matrix_tuwunel_container_labels_internal_client_api_traefik_entrypoints: ""
|
||||
|
||||
# Controls whether labels will be added that expose the Server-Server (Federation) API on a public Traefik entrypoint.
|
||||
matrix_tuwunel_container_labels_public_federation_api_enabled: "{{ matrix_tuwunel_config_allow_federation }}"
|
||||
matrix_tuwunel_container_labels_public_federation_api_traefik_hostname: "{{ matrix_tuwunel_hostname }}"
|
||||
matrix_tuwunel_container_labels_public_federation_api_traefik_path_prefix: /_matrix
|
||||
matrix_tuwunel_container_labels_public_federation_api_traefik_rule: "Host(`{{ matrix_tuwunel_container_labels_public_federation_api_traefik_hostname }}`) && PathPrefix(`{{ matrix_tuwunel_container_labels_public_federation_api_traefik_path_prefix }}`)"
|
||||
matrix_tuwunel_container_labels_public_federation_api_traefik_priority: 0
|
||||
matrix_tuwunel_container_labels_public_federation_api_traefik_entrypoints: ''
|
||||
# TLS is force-enabled because the spec (https://spec.matrix.org/latest/server-server-api/#tls) requires the federation API use HTTPS.
|
||||
matrix_tuwunel_container_labels_public_federation_api_traefik_tls: true
|
||||
matrix_tuwunel_container_labels_public_federation_api_traefik_tls_certResolver: "{{ matrix_tuwunel_container_labels_traefik_tls_certResolver }}" # noqa var-naming
|
||||
|
||||
# Additional Docker container labels (multiline string) appended verbatim to the label file.
|
||||
# See `../templates/labels.j2`.
|
||||
matrix_tuwunel_container_labels_additional_labels: ''
|
||||
|
||||
# Extra arguments for the Docker container
|
||||
matrix_tuwunel_container_extra_arguments: []
|
||||
|
||||
# Specifies which template files to use when configuring tuwunel.
|
||||
# To override the rendered config wholesale, copy the template into your inventory and point this at it:
|
||||
# matrix_tuwunel_template_tuwunel_config: "{{ playbook_dir }}/inventory/host_vars/matrix.example.com/tuwunel.toml.j2"
|
||||
matrix_tuwunel_template_tuwunel_config: "{{ role_path }}/templates/tuwunel.toml.j2"
|
||||
|
||||
# The pretty server name used as a suffix on user/room IDs. Cannot be changed after first start without a database wipe.
|
||||
matrix_tuwunel_config_server_name: "{{ matrix_domain }}"
|
||||
|
||||
# Max size for uploads, in bytes
|
||||
matrix_tuwunel_config_max_request_size: 20000000
|
||||
|
||||
# Enables open registration. If false, no users can register on this server.
|
||||
matrix_tuwunel_config_allow_registration: false
|
||||
|
||||
# When registration is enabled, set a strong token to protect the endpoint from abuse.
|
||||
# Generate one with e.g. `pwgen -s 64 1`. If left empty AND `allow_registration` is true,
|
||||
# you must explicitly opt in via the open-registration acknowledgement variable below.
|
||||
matrix_tuwunel_config_registration_token: ''
|
||||
|
||||
# Acknowledgement required to allow registration with no token.
|
||||
# Maps to tuwunel's `yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse`.
|
||||
matrix_tuwunel_config_yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse: false
|
||||
|
||||
# Suffix appended to new-user displaynames upon registration. Empty disables it.
|
||||
# Upstream defaults to a flag glyph; we keep MDAD homeserver behavior consistent and leave this empty.
|
||||
matrix_tuwunel_config_new_user_displayname_suffix: ""
|
||||
|
||||
# Emergency password to grant access to the admin user when locked out. Empty disables.
|
||||
matrix_tuwunel_config_emergency_password: ''
|
||||
|
||||
# Trusted notary servers used for key verification.
|
||||
matrix_tuwunel_config_trusted_servers:
|
||||
- "matrix.org"
|
||||
|
||||
# Logging directives in `tracing-subscriber` env-filter syntax.
|
||||
matrix_tuwunel_config_log: "info,state_res=warn"
|
||||
|
||||
# TURN integration
|
||||
matrix_tuwunel_config_turn_uris: []
|
||||
matrix_tuwunel_config_turn_secret: ''
|
||||
matrix_tuwunel_config_turn_username: ''
|
||||
matrix_tuwunel_config_turn_password: ''
|
||||
|
||||
# Self-check toggles
|
||||
matrix_tuwunel_self_check_validate_certificates: true
|
||||
|
||||
# Encryption / room creation policy
|
||||
matrix_tuwunel_config_allow_encryption: true
|
||||
matrix_tuwunel_config_allow_room_creation: true
|
||||
|
||||
# Default room version newly created rooms will use.
|
||||
matrix_tuwunel_config_default_room_version: '12'
|
||||
|
||||
# Rooms newly registered users will be auto-joined to.
|
||||
# Must be rooms this server has joined at least once and that are public.
|
||||
matrix_tuwunel_config_auto_join_rooms: []
|
||||
|
||||
# (De)federation toggles
|
||||
matrix_tuwunel_config_allow_federation: true
|
||||
matrix_tuwunel_config_allowed_remote_server_names: []
|
||||
matrix_tuwunel_config_forbidden_remote_server_names: []
|
||||
matrix_tuwunel_config_forbidden_remote_room_directory_server_names: []
|
||||
matrix_tuwunel_config_prevent_media_downloads_from: []
|
||||
|
||||
# Outgoing presence is heavy on CPU and network and almost no clients use it. Off by default.
|
||||
matrix_tuwunel_config_allow_outgoing_presence: false
|
||||
|
||||
# URL preview gating
|
||||
matrix_tuwunel_config_url_preview_domain_contains_allowlist: []
|
||||
matrix_tuwunel_config_url_preview_domain_explicit_allowlist: []
|
||||
matrix_tuwunel_config_url_preview_check_root_domain: false
|
||||
|
||||
# Well-known overrides
|
||||
# Maps to `[global.well_known] client = "..."` and `server = "host:port"`.
|
||||
matrix_tuwunel_config_well_known_client: ''
|
||||
matrix_tuwunel_config_well_known_server: ''
|
||||
matrix_tuwunel_config_well_known_support_page: ''
|
||||
matrix_tuwunel_config_well_known_support_email: ''
|
||||
matrix_tuwunel_config_well_known_support_mxid: ''
|
||||
|
||||
# MatrixRTC foci served via /_matrix/client/v1/rtc/transports (MSC4143)
|
||||
matrix_tuwunel_config_well_known_livekit_url: ''
|
||||
|
||||
# RocksDB tuning. Empty values let tuwunel auto-pick.
|
||||
matrix_tuwunel_config_rocksdb_compression_algo: 'zstd' # one of: zstd, lz4, bz2, none
|
||||
matrix_tuwunel_config_rocksdb_compression_level: ''
|
||||
matrix_tuwunel_config_rocksdb_bottommost_compression_level: ''
|
||||
matrix_tuwunel_config_rocksdb_direct_io: false
|
||||
matrix_tuwunel_config_rocksdb_parallelism_threads: 0
|
||||
matrix_tuwunel_config_rocksdb_max_log_file_size: ''
|
||||
matrix_tuwunel_config_rocksdb_log_time_to_roll: ''
|
||||
matrix_tuwunel_config_database_backup_path: ''
|
||||
matrix_tuwunel_config_database_backups_to_keep: 1
|
||||
|
||||
# Cache sizing. Empty values let tuwunel auto-pick (scaled by CPU count).
|
||||
matrix_tuwunel_config_cache_capacity_modifier: ''
|
||||
matrix_tuwunel_config_db_cache_capacity_mb: ''
|
||||
matrix_tuwunel_config_db_write_buffer_capacity_mb: ''
|
||||
|
||||
# Admin room
|
||||
matrix_tuwunel_config_create_admin_room: true
|
||||
matrix_tuwunel_config_federate_admin_room: false
|
||||
matrix_tuwunel_config_grant_admin_to_first_user: true
|
||||
|
||||
# Sentry crash/error reporting (off by default)
|
||||
matrix_tuwunel_config_sentry_enabled: false
|
||||
matrix_tuwunel_config_sentry_endpoint: ''
|
||||
matrix_tuwunel_config_sentry_send_server_name: false
|
||||
matrix_tuwunel_config_sentry_traces_sample_rate: 0.15
|
||||
|
||||
# Blurhashing for image previews
|
||||
matrix_tuwunel_config_blurhashing_enabled: true
|
||||
matrix_tuwunel_config_blurhashing_components_x: 4
|
||||
matrix_tuwunel_config_blurhashing_components_y: 3
|
||||
matrix_tuwunel_config_blurhashing_max_raw_size: 33554432
|
||||
|
||||
# Native TLS (use only when reverse-proxying is not desired)
|
||||
matrix_tuwunel_config_tls_certs: ''
|
||||
matrix_tuwunel_config_tls_key: ''
|
||||
matrix_tuwunel_config_tls_dual_protocol: false
|
||||
|
||||
# LDAP authentication ([global.ldap] in tuwunel.toml).
|
||||
# See: https://matrix-construct.github.io/tuwunel/authentication/providers.html
|
||||
matrix_tuwunel_config_ldap_enabled: false
|
||||
matrix_tuwunel_config_ldap_uri: ''
|
||||
matrix_tuwunel_config_ldap_base_dn: ''
|
||||
matrix_tuwunel_config_ldap_bind_dn: ''
|
||||
matrix_tuwunel_config_ldap_bind_password_file: ''
|
||||
matrix_tuwunel_config_ldap_filter: '(objectClass=*)'
|
||||
matrix_tuwunel_config_ldap_uid_attribute: 'uid'
|
||||
matrix_tuwunel_config_ldap_name_attribute: 'givenName'
|
||||
matrix_tuwunel_config_ldap_admin_base_dn: ''
|
||||
matrix_tuwunel_config_ldap_admin_filter: ''
|
||||
|
||||
# JWT authentication ([global.jwt] in tuwunel.toml).
|
||||
matrix_tuwunel_config_jwt_enabled: false
|
||||
matrix_tuwunel_config_jwt_key: ''
|
||||
matrix_tuwunel_config_jwt_format: 'HMAC' # one of: HMAC, B64HMAC, ECDSA, EDDSA
|
||||
matrix_tuwunel_config_jwt_algorithm: 'HS256'
|
||||
matrix_tuwunel_config_jwt_register_user: true
|
||||
matrix_tuwunel_config_jwt_audience: []
|
||||
matrix_tuwunel_config_jwt_issuer: []
|
||||
matrix_tuwunel_config_jwt_require_exp: false
|
||||
matrix_tuwunel_config_jwt_require_nbf: false
|
||||
matrix_tuwunel_config_jwt_validate_exp: true
|
||||
matrix_tuwunel_config_jwt_validate_nbf: true
|
||||
|
||||
# OAuth2/OIDC identity providers.
|
||||
#
|
||||
# Each entry becomes a `[[global.identity_provider]]` block. Only fields you set are emitted;
|
||||
# tuwunel applies brand-aware defaults for known providers (Google, GitHub, Keycloak, MAS, etc).
|
||||
#
|
||||
# Example:
|
||||
# matrix_tuwunel_config_identity_providers:
|
||||
# - brand: keycloak
|
||||
# client_id: matrix
|
||||
# client_secret: '...'
|
||||
# issuer_url: https://sso.example.com/realms/matrix
|
||||
# callback_url: https://matrix.example.com/_matrix/client/unstable/login/sso/callback/matrix
|
||||
# trusted: true
|
||||
# - brand: github
|
||||
# client_id: '...'
|
||||
# client_secret: '...'
|
||||
#
|
||||
# See: https://matrix-construct.github.io/tuwunel/authentication/providers.html
|
||||
matrix_tuwunel_config_identity_providers: []
|
||||
|
||||
# Media storage providers.
|
||||
#
|
||||
# Each entry maps an ID to a backend. `kind` is `local` or `s3`; remaining keys map directly
|
||||
# to fields under `[global.storage_provider.<ID>.<kind>]`.
|
||||
#
|
||||
# Examples:
|
||||
# matrix_tuwunel_config_storage_providers:
|
||||
# - id: primary
|
||||
# kind: local
|
||||
# base_path: /var/lib/tuwunel/media
|
||||
# - id: archive
|
||||
# kind: s3
|
||||
# url: s3://my-bucket/media
|
||||
# region: us-east-1
|
||||
# key: AKIA...
|
||||
# secret: '...'
|
||||
#
|
||||
# See: https://matrix-construct.github.io/tuwunel/media/storage.html
|
||||
matrix_tuwunel_config_storage_providers: []
|
||||
|
||||
# Additional environment variables to pass to the container, one per line.
|
||||
# Environment variables override the rendered config file.
|
||||
#
|
||||
# Example:
|
||||
# matrix_tuwunel_environment_variables_extension: |
|
||||
# TUWUNEL_REQUEST_TIMEOUT=60
|
||||
# TUWUNEL_DNS_CACHE_SIZE=131072
|
||||
matrix_tuwunel_environment_variables_extension: ''
|
||||
|
||||
# matrix_tuwunel_restart_necessary controls whether the service will be restarted (when true)
|
||||
# or merely started (when false) by the systemd service-manager role when conditional restart
|
||||
# is enabled. Computed during installation based on whether config / unit / image changed.
|
||||
matrix_tuwunel_restart_necessary: false
|
||||
76
roles/custom/matrix-tuwunel/tasks/install.yml
Normal file
76
roles/custom/matrix-tuwunel/tasks/install.yml
Normal file
@@ -0,0 +1,76 @@
|
||||
# SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
# SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
---
|
||||
|
||||
- name: Ensure tuwunel config path exists
|
||||
ansible.builtin.file:
|
||||
path: "{{ matrix_tuwunel_config_path }}"
|
||||
state: directory
|
||||
mode: '0750'
|
||||
owner: "{{ matrix_user_name }}"
|
||||
group: "{{ matrix_group_name }}"
|
||||
|
||||
- name: Ensure tuwunel data path exists
|
||||
ansible.builtin.file:
|
||||
path: "{{ matrix_tuwunel_data_path }}"
|
||||
state: directory
|
||||
mode: '0770'
|
||||
owner: "{{ matrix_user_name }}"
|
||||
group: "{{ matrix_group_name }}"
|
||||
|
||||
- name: Ensure tuwunel configuration installed
|
||||
ansible.builtin.template:
|
||||
src: "{{ matrix_tuwunel_template_tuwunel_config }}"
|
||||
dest: "{{ matrix_tuwunel_config_path }}/tuwunel.toml"
|
||||
mode: '0644'
|
||||
owner: "{{ matrix_user_name }}"
|
||||
group: "{{ matrix_group_name }}"
|
||||
register: matrix_tuwunel_config_result
|
||||
|
||||
- name: Ensure tuwunel support files installed
|
||||
ansible.builtin.template:
|
||||
src: "{{ role_path }}/templates/{{ item }}.j2"
|
||||
dest: "{{ matrix_tuwunel_base_path }}/{{ item }}"
|
||||
mode: '0640'
|
||||
owner: "{{ matrix_user_name }}"
|
||||
group: "{{ matrix_group_name }}"
|
||||
with_items:
|
||||
- labels
|
||||
- env
|
||||
register: matrix_tuwunel_support_files_result
|
||||
|
||||
- name: Ensure tuwunel container network is created
|
||||
community.general.docker_network:
|
||||
enable_ipv6: "{{ devture_systemd_docker_base_ipv6_enabled }}"
|
||||
name: "{{ matrix_tuwunel_container_network }}"
|
||||
driver: bridge
|
||||
driver_options: "{{ devture_systemd_docker_base_container_networks_driver_options }}"
|
||||
|
||||
- name: Ensure tuwunel container image is pulled
|
||||
community.docker.docker_image_pull:
|
||||
name: "{{ matrix_tuwunel_container_image }}"
|
||||
pull: always
|
||||
register: matrix_tuwunel_container_image_pull_result
|
||||
retries: "{{ devture_playbook_help_container_retries_count }}"
|
||||
delay: "{{ devture_playbook_help_container_retries_delay }}"
|
||||
until: matrix_tuwunel_container_image_pull_result is not failed
|
||||
|
||||
- name: Ensure matrix-tuwunel.service installed
|
||||
ansible.builtin.template:
|
||||
src: "{{ role_path }}/templates/systemd/matrix-tuwunel.service.j2"
|
||||
dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-tuwunel.service"
|
||||
mode: '0644'
|
||||
register: matrix_tuwunel_systemd_service_result
|
||||
|
||||
- name: Determine whether tuwunel needs a restart
|
||||
ansible.builtin.set_fact:
|
||||
matrix_tuwunel_restart_necessary: >-
|
||||
{{
|
||||
matrix_tuwunel_config_result.changed | default(false)
|
||||
or matrix_tuwunel_support_files_result.changed | default(false)
|
||||
or matrix_tuwunel_systemd_service_result.changed | default(false)
|
||||
or matrix_tuwunel_container_image_pull_result.changed | default(false)
|
||||
}}
|
||||
40
roles/custom/matrix-tuwunel/tasks/main.yml
Normal file
40
roles/custom/matrix-tuwunel/tasks/main.yml
Normal file
@@ -0,0 +1,40 @@
|
||||
# SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
# SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
---
|
||||
|
||||
- tags:
|
||||
- setup-all
|
||||
- setup-tuwunel
|
||||
- install-all
|
||||
- install-tuwunel
|
||||
block:
|
||||
- when: matrix_tuwunel_enabled | bool
|
||||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml"
|
||||
|
||||
- when: matrix_tuwunel_enabled | bool
|
||||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/install.yml"
|
||||
|
||||
- tags:
|
||||
- setup-all
|
||||
- setup-tuwunel
|
||||
block:
|
||||
- when: not matrix_tuwunel_enabled | bool
|
||||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/uninstall.yml"
|
||||
|
||||
- tags:
|
||||
- self-check
|
||||
block:
|
||||
- when: matrix_tuwunel_enabled | bool
|
||||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/self_check_client_api.yml"
|
||||
|
||||
- when: matrix_tuwunel_enabled | bool
|
||||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/self_check_federation_api.yml"
|
||||
|
||||
- tags:
|
||||
- tuwunel-migrate-from-conduwuit
|
||||
block:
|
||||
- when: matrix_tuwunel_enabled | bool
|
||||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/migrate_from_conduwuit.yml"
|
||||
83
roles/custom/matrix-tuwunel/tasks/migrate_from_conduwuit.yml
Normal file
83
roles/custom/matrix-tuwunel/tasks/migrate_from_conduwuit.yml
Normal file
@@ -0,0 +1,83 @@
|
||||
# SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
# SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
---
|
||||
|
||||
# Migrates from the conduwuit server implementation (`/matrix/conduwuit`) to tuwunel (`/matrix/tuwunel`).
|
||||
# Tuwunel is the official successor to conduwuit and reads conduwuit's RocksDB layout directly.
|
||||
# We back up the freshly generated tuwunel directory, copy conduwuit's data into it,
|
||||
# rename the config file, restore tuwunel's labels file, and start the new service.
|
||||
|
||||
- name: Check existence of conduwuit directory
|
||||
ansible.builtin.stat:
|
||||
path: "{{ matrix_base_data_path }}/conduwuit"
|
||||
register: matrix_removed_conduwuit_directory_stat
|
||||
|
||||
- name: Check existence of tuwunel directory
|
||||
ansible.builtin.stat:
|
||||
path: "{{ matrix_base_data_path }}/tuwunel"
|
||||
register: matrix_tuwunel_directory_stat
|
||||
|
||||
- when: >
|
||||
matrix_removed_conduwuit_directory_stat.stat.exists | bool and
|
||||
matrix_tuwunel_directory_stat.stat.exists | bool
|
||||
block:
|
||||
- name: Ensure matrix-tuwunel.service systemd service is stopped
|
||||
ansible.builtin.systemd:
|
||||
name: matrix-tuwunel
|
||||
state: stopped
|
||||
enabled: false
|
||||
daemon_reload: true
|
||||
|
||||
- name: Ensure tuwunel directory is backed up
|
||||
ansible.builtin.command:
|
||||
cmd: "mv {{ matrix_base_data_path }}/tuwunel {{ matrix_base_data_path }}/tuwunel_old"
|
||||
creates: "{{ matrix_base_data_path }}/tuwunel_old"
|
||||
removes: "{{ matrix_base_data_path }}/tuwunel"
|
||||
|
||||
- name: Ensure conduwuit directory contents are copied to tuwunel
|
||||
ansible.builtin.copy:
|
||||
src: "{{ matrix_base_data_path }}/conduwuit/"
|
||||
dest: "{{ matrix_base_data_path }}/tuwunel"
|
||||
remote_src: true
|
||||
mode: preserve
|
||||
|
||||
- name: Ensure conduwuit.toml file is renamed
|
||||
ansible.builtin.command:
|
||||
cmd: "mv {{ matrix_base_data_path }}/tuwunel/config/conduwuit.toml {{ matrix_base_data_path }}/tuwunel/config/tuwunel.toml"
|
||||
removes: "{{ matrix_base_data_path }}/tuwunel/config/conduwuit.toml"
|
||||
|
||||
- name: Ensure tuwunel labels are restored
|
||||
ansible.builtin.copy:
|
||||
src: "{{ matrix_base_data_path }}/tuwunel_old/labels"
|
||||
dest: "{{ matrix_base_data_path }}/tuwunel/labels"
|
||||
remote_src: true
|
||||
force: true
|
||||
mode: preserve
|
||||
|
||||
- name: Ensure directories ownership is set
|
||||
block:
|
||||
- name: Set tuwunel ownership
|
||||
ansible.builtin.file:
|
||||
path: "{{ matrix_base_data_path }}/tuwunel"
|
||||
state: directory
|
||||
owner: "{{ matrix_user_name }}"
|
||||
group: "{{ matrix_group_name }}"
|
||||
recurse: true
|
||||
|
||||
- name: Set tuwunel_old ownership
|
||||
ansible.builtin.file:
|
||||
path: "{{ matrix_base_data_path }}/tuwunel_old"
|
||||
state: directory
|
||||
owner: "{{ matrix_user_name }}"
|
||||
group: "{{ matrix_group_name }}"
|
||||
recurse: true
|
||||
|
||||
- name: Ensure matrix-tuwunel.service systemd service is started
|
||||
ansible.builtin.systemd:
|
||||
name: matrix-tuwunel
|
||||
state: started
|
||||
enabled: true
|
||||
daemon_reload: true
|
||||
28
roles/custom/matrix-tuwunel/tasks/self_check_client_api.yml
Normal file
28
roles/custom/matrix-tuwunel/tasks/self_check_client_api.yml
Normal file
@@ -0,0 +1,28 @@
|
||||
# SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
# SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
---
|
||||
|
||||
- name: Check Matrix Client API
|
||||
ansible.builtin.uri:
|
||||
url: "{{ matrix_tuwunel_client_api_url_endpoint_public }}"
|
||||
follow_redirects: none
|
||||
validate_certs: "{{ matrix_tuwunel_self_check_validate_certificates }}"
|
||||
register: result_matrix_tuwunel_client_api
|
||||
ignore_errors: true
|
||||
check_mode: false
|
||||
when: matrix_tuwunel_enabled | bool
|
||||
delegate_to: 127.0.0.1
|
||||
become: false
|
||||
|
||||
- name: Fail if Matrix Client API not working
|
||||
ansible.builtin.fail:
|
||||
msg: "Failed checking Matrix Client API is up at `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ matrix_tuwunel_client_api_url_endpoint_public }}`). Is tuwunel running? Is port 443 open in your firewall? Full error: {{ result_matrix_tuwunel_client_api }}"
|
||||
when: "matrix_tuwunel_enabled | bool and (result_matrix_tuwunel_client_api.failed or 'json' not in result_matrix_tuwunel_client_api)"
|
||||
|
||||
- name: Report working Matrix Client API
|
||||
ansible.builtin.debug:
|
||||
msg: "The Matrix Client API at `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ matrix_tuwunel_client_api_url_endpoint_public }}`) is working"
|
||||
when: matrix_tuwunel_enabled | bool
|
||||
@@ -0,0 +1,33 @@
|
||||
# SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
# SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
---
|
||||
|
||||
- name: Check Matrix Federation API
|
||||
ansible.builtin.uri:
|
||||
url: "{{ matrix_tuwunel_federation_api_url_endpoint_public }}"
|
||||
follow_redirects: none
|
||||
validate_certs: "{{ matrix_tuwunel_self_check_validate_certificates }}"
|
||||
register: result_matrix_tuwunel_federation_api
|
||||
ignore_errors: true
|
||||
check_mode: false
|
||||
when: matrix_tuwunel_enabled | bool
|
||||
delegate_to: 127.0.0.1
|
||||
become: false
|
||||
|
||||
- name: Fail if Matrix Federation API not working
|
||||
ansible.builtin.fail:
|
||||
msg: "Failed checking Matrix Federation API is up at `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ matrix_tuwunel_federation_api_url_endpoint_public }}`). Is tuwunel running? Is port {{ matrix_federation_public_port }} open in your firewall? Full error: {{ result_matrix_tuwunel_federation_api }}"
|
||||
when: "matrix_tuwunel_enabled | bool and matrix_tuwunel_config_allow_federation | bool and (result_matrix_tuwunel_federation_api.failed or 'json' not in result_matrix_tuwunel_federation_api)"
|
||||
|
||||
- name: Fail if Matrix Federation API unexpectedly enabled
|
||||
ansible.builtin.fail:
|
||||
msg: "Matrix Federation API is up at `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ matrix_tuwunel_federation_api_url_endpoint_public }}`) despite being disabled."
|
||||
when: "matrix_tuwunel_enabled | bool and not matrix_tuwunel_config_allow_federation | bool and not result_matrix_tuwunel_federation_api.failed"
|
||||
|
||||
- name: Report working Matrix Federation API
|
||||
ansible.builtin.debug:
|
||||
msg: "The Matrix Federation API at `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ matrix_tuwunel_federation_api_url_endpoint_public }}`) is working"
|
||||
when: "matrix_tuwunel_enabled | bool and matrix_tuwunel_config_allow_federation | bool"
|
||||
8
roles/custom/matrix-tuwunel/tasks/setup_install.yml
Normal file
8
roles/custom/matrix-tuwunel/tasks/setup_install.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
# SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
# SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
---
|
||||
|
||||
- ansible.builtin.include_tasks: "{{ role_path }}/tasks/install.yml"
|
||||
8
roles/custom/matrix-tuwunel/tasks/setup_uninstall.yml
Normal file
8
roles/custom/matrix-tuwunel/tasks/setup_uninstall.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
# SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
# SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
---
|
||||
|
||||
- ansible.builtin.include_tasks: "{{ role_path }}/tasks/uninstall.yml"
|
||||
24
roles/custom/matrix-tuwunel/tasks/uninstall.yml
Normal file
24
roles/custom/matrix-tuwunel/tasks/uninstall.yml
Normal file
@@ -0,0 +1,24 @@
|
||||
# SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
# SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
---
|
||||
|
||||
- name: Check existence of matrix-tuwunel service
|
||||
ansible.builtin.stat:
|
||||
path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-tuwunel.service"
|
||||
register: matrix_tuwunel_service_stat
|
||||
|
||||
- when: matrix_tuwunel_service_stat.stat.exists | bool
|
||||
block:
|
||||
- name: Ensure matrix-tuwunel is stopped
|
||||
ansible.builtin.systemd:
|
||||
name: matrix-tuwunel
|
||||
state: stopped
|
||||
daemon_reload: true
|
||||
|
||||
- name: Ensure matrix-tuwunel.service doesn't exist
|
||||
ansible.builtin.file:
|
||||
path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-tuwunel.service"
|
||||
state: absent
|
||||
44
roles/custom/matrix-tuwunel/tasks/validate_config.yml
Normal file
44
roles/custom/matrix-tuwunel/tasks/validate_config.yml
Normal file
@@ -0,0 +1,44 @@
|
||||
# SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
# SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
---
|
||||
|
||||
- name: Fail if required tuwunel settings not defined
|
||||
ansible.builtin.fail:
|
||||
msg: >-
|
||||
You need to define a required configuration setting (`{{ item.name }}`).
|
||||
when: "item.when | bool and lookup('vars', item.name, default='') | string | length == 0"
|
||||
with_items:
|
||||
- {'name': 'matrix_tuwunel_hostname', when: true}
|
||||
- {'name': 'matrix_tuwunel_container_network', when: true}
|
||||
- {'name': 'matrix_tuwunel_container_labels_internal_client_api_traefik_entrypoints', when: "{{ matrix_tuwunel_container_labels_internal_client_api_enabled }}"}
|
||||
|
||||
- name: Fail if registration is enabled without a token or explicit acknowledgement
|
||||
ansible.builtin.fail:
|
||||
msg: >-
|
||||
`matrix_tuwunel_config_allow_registration` is true, but neither
|
||||
`matrix_tuwunel_config_registration_token` nor
|
||||
`matrix_tuwunel_config_yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse`
|
||||
is set. Set a registration token (recommended) or explicitly opt in to open registration.
|
||||
when: >-
|
||||
matrix_tuwunel_config_allow_registration | bool
|
||||
and (matrix_tuwunel_config_registration_token | length == 0)
|
||||
and not (matrix_tuwunel_config_yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse | bool)
|
||||
|
||||
- name: Fail if a storage provider is missing required fields
|
||||
ansible.builtin.fail:
|
||||
msg: >-
|
||||
Storage provider `{{ item.id | default('?') }}` is missing required fields.
|
||||
Each entry must define both `id` and `kind` (one of: local, s3).
|
||||
when: "(item.id | default('') | length == 0) or (item.kind | default('') not in ['local', 's3'])"
|
||||
with_items: "{{ matrix_tuwunel_config_storage_providers }}"
|
||||
|
||||
- name: Fail if an identity provider is missing required fields
|
||||
ansible.builtin.fail:
|
||||
msg: >-
|
||||
Identity provider entry is missing both `client_id` and `brand`.
|
||||
At minimum one of these is required for tuwunel to identify the provider.
|
||||
when: "(item.client_id | default('') | length == 0) and (item.brand | default('') | length == 0)"
|
||||
with_items: "{{ matrix_tuwunel_config_identity_providers }}"
|
||||
1
roles/custom/matrix-tuwunel/templates/env.j2
Normal file
1
roles/custom/matrix-tuwunel/templates/env.j2
Normal file
@@ -0,0 +1 @@
|
||||
{{ matrix_tuwunel_environment_variables_extension }}
|
||||
4
roles/custom/matrix-tuwunel/templates/env.j2.license
Normal file
4
roles/custom/matrix-tuwunel/templates/env.j2.license
Normal file
@@ -0,0 +1,4 @@
|
||||
SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
141
roles/custom/matrix-tuwunel/templates/labels.j2
Normal file
141
roles/custom/matrix-tuwunel/templates/labels.j2
Normal file
@@ -0,0 +1,141 @@
|
||||
{#
|
||||
SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
#}
|
||||
|
||||
{% if matrix_tuwunel_container_labels_traefik_enabled %}
|
||||
traefik.enable=true
|
||||
|
||||
{% if matrix_tuwunel_container_labels_traefik_docker_network %}
|
||||
traefik.docker.network={{ matrix_tuwunel_container_labels_traefik_docker_network }}
|
||||
{% endif %}
|
||||
|
||||
traefik.http.services.matrix-tuwunel.loadbalancer.server.port={{ matrix_tuwunel_config_port_number }}
|
||||
|
||||
|
||||
{% if matrix_tuwunel_container_labels_public_client_root_enabled %}
|
||||
############################################################
|
||||
# #
|
||||
# Public Root path (/) #
|
||||
# #
|
||||
############################################################
|
||||
|
||||
{% set client_root_middlewares = [] %}
|
||||
|
||||
{% if matrix_tuwunel_container_labels_public_client_root_redirection_enabled %}
|
||||
{% set client_root_middlewares = client_root_middlewares + ['matrix-tuwunel-client-root-redirect'] %}
|
||||
traefik.http.middlewares.matrix-tuwunel-client-root-redirect.redirectregex.regex=(.*)
|
||||
traefik.http.middlewares.matrix-tuwunel-client-root-redirect.redirectregex.replacement={{ matrix_tuwunel_container_labels_public_client_root_redirection_url }}
|
||||
{% endif %}
|
||||
|
||||
traefik.http.routers.matrix-tuwunel-public-client-root.rule={{ matrix_tuwunel_container_labels_public_client_root_traefik_rule }}
|
||||
|
||||
traefik.http.routers.matrix-tuwunel-public-client-root.middlewares={{ client_root_middlewares | join(',') }}
|
||||
|
||||
{% if matrix_tuwunel_container_labels_public_client_root_traefik_priority | int > 0 %}
|
||||
traefik.http.routers.matrix-tuwunel-public-client-root.priority={{ matrix_tuwunel_container_labels_public_client_root_traefik_priority }}
|
||||
{% endif %}
|
||||
|
||||
traefik.http.routers.matrix-tuwunel-public-client-root.service=matrix-tuwunel
|
||||
traefik.http.routers.matrix-tuwunel-public-client-root.entrypoints={{ matrix_tuwunel_container_labels_public_client_root_traefik_entrypoints }}
|
||||
traefik.http.routers.matrix-tuwunel-public-client-root.tls={{ matrix_tuwunel_container_labels_public_client_root_traefik_tls | to_json }}
|
||||
|
||||
{% if matrix_tuwunel_container_labels_public_client_root_traefik_tls %}
|
||||
traefik.http.routers.matrix-tuwunel-public-client-root.tls.certResolver={{ matrix_tuwunel_container_labels_public_client_root_traefik_tls_certResolver }}
|
||||
{% endif %}
|
||||
|
||||
############################################################
|
||||
# #
|
||||
# /Public Root path (/) #
|
||||
# #
|
||||
############################################################
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if matrix_tuwunel_container_labels_public_client_api_enabled %}
|
||||
############################################################
|
||||
# #
|
||||
# Public Client-API (/_matrix) #
|
||||
# #
|
||||
############################################################
|
||||
|
||||
traefik.http.routers.matrix-tuwunel-public-client-api.rule={{ matrix_tuwunel_container_labels_public_client_api_traefik_rule }}
|
||||
|
||||
{% if matrix_tuwunel_container_labels_public_client_api_traefik_priority | int > 0 %}
|
||||
traefik.http.routers.matrix-tuwunel-public-client-api.priority={{ matrix_tuwunel_container_labels_public_client_api_traefik_priority }}
|
||||
{% endif %}
|
||||
|
||||
traefik.http.routers.matrix-tuwunel-public-client-api.service=matrix-tuwunel
|
||||
traefik.http.routers.matrix-tuwunel-public-client-api.entrypoints={{ matrix_tuwunel_container_labels_public_client_api_traefik_entrypoints }}
|
||||
|
||||
traefik.http.routers.matrix-tuwunel-public-client-api.tls={{ matrix_tuwunel_container_labels_public_client_api_traefik_tls | to_json }}
|
||||
{% if matrix_tuwunel_container_labels_public_client_api_traefik_tls %}
|
||||
traefik.http.routers.matrix-tuwunel-public-client-api.tls.certResolver={{ matrix_tuwunel_container_labels_public_client_api_traefik_tls_certResolver }}
|
||||
{% endif %}
|
||||
|
||||
############################################################
|
||||
# #
|
||||
# /Public Client-API (/_matrix) #
|
||||
# #
|
||||
############################################################
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if matrix_tuwunel_container_labels_internal_client_api_enabled %}
|
||||
############################################################
|
||||
# #
|
||||
# Internal Client-API (/_matrix) #
|
||||
# #
|
||||
############################################################
|
||||
|
||||
traefik.http.routers.matrix-tuwunel-internal-client-api.rule={{ matrix_tuwunel_container_labels_internal_client_api_traefik_rule }}
|
||||
|
||||
{% if matrix_tuwunel_container_labels_internal_client_api_traefik_priority | int > 0 %}
|
||||
traefik.http.routers.matrix-tuwunel-internal-client-api.priority={{ matrix_tuwunel_container_labels_internal_client_api_traefik_priority }}
|
||||
{% endif %}
|
||||
|
||||
traefik.http.routers.matrix-tuwunel-internal-client-api.service=matrix-tuwunel
|
||||
traefik.http.routers.matrix-tuwunel-internal-client-api.entrypoints={{ matrix_tuwunel_container_labels_internal_client_api_traefik_entrypoints }}
|
||||
|
||||
############################################################
|
||||
# #
|
||||
# /Internal Client-API (/_matrix) #
|
||||
# #
|
||||
############################################################
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if matrix_tuwunel_container_labels_public_federation_api_enabled %}
|
||||
############################################################
|
||||
# #
|
||||
# Public Federation-API (/_matrix) #
|
||||
# #
|
||||
############################################################
|
||||
|
||||
traefik.http.routers.matrix-tuwunel-public-federation-api.rule={{ matrix_tuwunel_container_labels_public_federation_api_traefik_rule }}
|
||||
|
||||
{% if matrix_tuwunel_container_labels_public_federation_api_traefik_priority | int > 0 %}
|
||||
traefik.http.routers.matrix-tuwunel-public-federation-api.priority={{ matrix_tuwunel_container_labels_public_federation_api_traefik_priority }}
|
||||
{% endif %}
|
||||
|
||||
traefik.http.routers.matrix-tuwunel-public-federation-api.service=matrix-tuwunel
|
||||
traefik.http.routers.matrix-tuwunel-public-federation-api.entrypoints={{ matrix_tuwunel_container_labels_public_federation_api_traefik_entrypoints }}
|
||||
|
||||
traefik.http.routers.matrix-tuwunel-public-federation-api.tls={{ matrix_tuwunel_container_labels_public_federation_api_traefik_tls | to_json }}
|
||||
{% if matrix_tuwunel_container_labels_public_federation_api_traefik_tls %}
|
||||
traefik.http.routers.matrix-tuwunel-public-federation-api.tls.certResolver={{ matrix_tuwunel_container_labels_public_federation_api_traefik_tls_certResolver }}
|
||||
{% endif %}
|
||||
|
||||
############################################################
|
||||
# #
|
||||
# /Public Federation-API (/_matrix) #
|
||||
# #
|
||||
############################################################
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% endif %}
|
||||
|
||||
{{ matrix_tuwunel_container_labels_additional_labels }}
|
||||
@@ -0,0 +1,55 @@
|
||||
#jinja2: lstrip_blocks: True
|
||||
[Unit]
|
||||
Description=Tuwunel Matrix homeserver
|
||||
{% for service in matrix_tuwunel_systemd_required_services_list %}
|
||||
Requires={{ service }}
|
||||
After={{ service }}
|
||||
{% endfor %}
|
||||
{% for service in matrix_tuwunel_systemd_wanted_services_list %}
|
||||
Wants={{ service }}
|
||||
{% endfor %}
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Environment="HOME={{ devture_systemd_docker_base_systemd_unit_home_path }}"
|
||||
ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-tuwunel 2>/dev/null || true'
|
||||
ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-tuwunel 2>/dev/null || true'
|
||||
|
||||
ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} create \
|
||||
--rm \
|
||||
--name=matrix-tuwunel \
|
||||
--log-driver=none \
|
||||
--user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
|
||||
--cap-drop=ALL \
|
||||
--read-only \
|
||||
--tmpfs=/tmp:rw,noexec,nosuid,size={{ matrix_tuwunel_tmp_directory_size_mb }}m \
|
||||
--network={{ matrix_tuwunel_container_network }} \
|
||||
--env-file={{ matrix_tuwunel_base_path }}/env \
|
||||
--env TUWUNEL_CONFIG=/etc/tuwunel/tuwunel.toml \
|
||||
--label-file={{ matrix_tuwunel_base_path }}/labels \
|
||||
--mount type=bind,src={{ matrix_tuwunel_data_path }},dst=/var/lib/tuwunel \
|
||||
--mount type=bind,src={{ matrix_tuwunel_config_path }},dst=/etc/tuwunel,ro \
|
||||
{% for arg in matrix_tuwunel_container_extra_arguments %}
|
||||
{{ arg }} \
|
||||
{% endfor %}
|
||||
{{ matrix_tuwunel_container_image }}
|
||||
|
||||
{% for network in matrix_tuwunel_container_additional_networks %}
|
||||
ExecStartPre={{ devture_systemd_docker_base_host_command_docker }} network connect {{ network }} matrix-tuwunel
|
||||
{% endfor %}
|
||||
|
||||
ExecStart={{ devture_systemd_docker_base_host_command_docker }} start --attach matrix-tuwunel
|
||||
|
||||
{% if matrix_tuwunel_systemd_service_post_start_delay_seconds != 0 %}
|
||||
ExecStartPost=-{{ matrix_host_command_sleep }} {{ matrix_tuwunel_systemd_service_post_start_delay_seconds }}
|
||||
{% endif %}
|
||||
|
||||
ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} stop -t {{ devture_systemd_docker_base_container_stop_grace_time_seconds }} matrix-tuwunel 2>/dev/null || true'
|
||||
ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-tuwunel 2>/dev/null || true'
|
||||
ExecReload={{ devture_systemd_docker_base_host_command_docker }} exec matrix-tuwunel /bin/sh -c 'kill -HUP 1'
|
||||
Restart=always
|
||||
RestartSec=30
|
||||
SyslogIdentifier=matrix-tuwunel
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,4 @@
|
||||
SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
238
roles/custom/matrix-tuwunel/templates/tuwunel.toml.j2
Normal file
238
roles/custom/matrix-tuwunel/templates/tuwunel.toml.j2
Normal file
@@ -0,0 +1,238 @@
|
||||
{#
|
||||
SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
#}
|
||||
### Tuwunel configuration rendered by matrix-docker-ansible-deploy.
|
||||
###
|
||||
### This file only emits options exposed as Ansible variables. All other knobs
|
||||
### keep tuwunel's upstream defaults. To override anything not surfaced here,
|
||||
### use `matrix_tuwunel_environment_variables_extension` (env vars override TOML)
|
||||
### or replace the template via `matrix_tuwunel_template_tuwunel_config`.
|
||||
###
|
||||
### Reference: https://matrix-construct.github.io/tuwunel/configuration.html
|
||||
|
||||
[global]
|
||||
server_name = {{ matrix_tuwunel_config_server_name | to_json }}
|
||||
address = "0.0.0.0"
|
||||
port = {{ matrix_tuwunel_config_port_number }}
|
||||
database_path = "/var/lib/tuwunel"
|
||||
|
||||
max_request_size = {{ matrix_tuwunel_config_max_request_size }}
|
||||
|
||||
new_user_displayname_suffix = {{ matrix_tuwunel_config_new_user_displayname_suffix | to_json }}
|
||||
|
||||
allow_registration = {{ matrix_tuwunel_config_allow_registration | to_json }}
|
||||
{% if matrix_tuwunel_config_registration_token | length > 0 %}
|
||||
registration_token = {{ matrix_tuwunel_config_registration_token | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse | bool %}
|
||||
yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse = true
|
||||
{% endif %}
|
||||
|
||||
{% if matrix_tuwunel_config_emergency_password | length > 0 %}
|
||||
emergency_password = {{ matrix_tuwunel_config_emergency_password | to_json }}
|
||||
{% endif %}
|
||||
|
||||
allow_encryption = {{ matrix_tuwunel_config_allow_encryption | to_json }}
|
||||
allow_room_creation = {{ matrix_tuwunel_config_allow_room_creation | to_json }}
|
||||
default_room_version = {{ matrix_tuwunel_config_default_room_version | to_json }}
|
||||
{% if matrix_tuwunel_config_auto_join_rooms | length > 0 %}
|
||||
auto_join_rooms = {{ matrix_tuwunel_config_auto_join_rooms | to_json }}
|
||||
{% endif %}
|
||||
|
||||
allow_federation = {{ matrix_tuwunel_config_allow_federation | to_json }}
|
||||
trusted_servers = {{ matrix_tuwunel_config_trusted_servers | to_json }}
|
||||
{% if matrix_tuwunel_config_allowed_remote_server_names | length > 0 %}
|
||||
allowed_remote_server_names_experimental = {{ matrix_tuwunel_config_allowed_remote_server_names | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_forbidden_remote_server_names | length > 0 %}
|
||||
forbidden_remote_server_names = {{ matrix_tuwunel_config_forbidden_remote_server_names | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_forbidden_remote_room_directory_server_names | length > 0 %}
|
||||
forbidden_remote_room_directory_server_names = {{ matrix_tuwunel_config_forbidden_remote_room_directory_server_names | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_prevent_media_downloads_from | length > 0 %}
|
||||
prevent_media_downloads_from = {{ matrix_tuwunel_config_prevent_media_downloads_from | to_json }}
|
||||
{% endif %}
|
||||
|
||||
allow_outgoing_presence = {{ matrix_tuwunel_config_allow_outgoing_presence | to_json }}
|
||||
|
||||
{% if matrix_tuwunel_config_url_preview_domain_contains_allowlist | length > 0 %}
|
||||
url_preview_domain_contains_allowlist = {{ matrix_tuwunel_config_url_preview_domain_contains_allowlist | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_url_preview_domain_explicit_allowlist | length > 0 %}
|
||||
url_preview_domain_explicit_allowlist = {{ matrix_tuwunel_config_url_preview_domain_explicit_allowlist | to_json }}
|
||||
{% endif %}
|
||||
url_preview_check_root_domain = {{ matrix_tuwunel_config_url_preview_check_root_domain | to_json }}
|
||||
|
||||
create_admin_room = {{ matrix_tuwunel_config_create_admin_room | to_json }}
|
||||
federate_admin_room = {{ matrix_tuwunel_config_federate_admin_room | to_json }}
|
||||
grant_admin_to_first_user = {{ matrix_tuwunel_config_grant_admin_to_first_user | to_json }}
|
||||
|
||||
log = {{ matrix_tuwunel_config_log | to_json }}
|
||||
|
||||
{% if matrix_tuwunel_config_turn_uris | length > 0 %}
|
||||
turn_uris = {{ matrix_tuwunel_config_turn_uris | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_turn_secret | length > 0 %}
|
||||
turn_secret = {{ matrix_tuwunel_config_turn_secret | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_turn_username | length > 0 %}
|
||||
turn_username = {{ matrix_tuwunel_config_turn_username | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_turn_password | length > 0 %}
|
||||
turn_password = {{ matrix_tuwunel_config_turn_password | to_json }}
|
||||
{% endif %}
|
||||
|
||||
{% if matrix_tuwunel_config_rocksdb_compression_algo | length > 0 %}
|
||||
rocksdb_compression_algo = {{ matrix_tuwunel_config_rocksdb_compression_algo | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_rocksdb_compression_level | string | length > 0 %}
|
||||
rocksdb_compression_level = {{ matrix_tuwunel_config_rocksdb_compression_level }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_rocksdb_bottommost_compression_level | string | length > 0 %}
|
||||
rocksdb_bottommost_compression_level = {{ matrix_tuwunel_config_rocksdb_bottommost_compression_level }}
|
||||
{% endif %}
|
||||
rocksdb_direct_io = {{ matrix_tuwunel_config_rocksdb_direct_io | to_json }}
|
||||
{% if matrix_tuwunel_config_rocksdb_parallelism_threads | int > 0 %}
|
||||
rocksdb_parallelism_threads = {{ matrix_tuwunel_config_rocksdb_parallelism_threads }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_rocksdb_max_log_file_size | string | length > 0 %}
|
||||
rocksdb_max_log_file_size = {{ matrix_tuwunel_config_rocksdb_max_log_file_size }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_rocksdb_log_time_to_roll | string | length > 0 %}
|
||||
rocksdb_log_time_to_roll = {{ matrix_tuwunel_config_rocksdb_log_time_to_roll }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_database_backup_path | length > 0 %}
|
||||
database_backup_path = {{ matrix_tuwunel_config_database_backup_path | to_json }}
|
||||
database_backups_to_keep = {{ matrix_tuwunel_config_database_backups_to_keep }}
|
||||
{% endif %}
|
||||
|
||||
{% if matrix_tuwunel_config_cache_capacity_modifier | string | length > 0 %}
|
||||
cache_capacity_modifier = {{ matrix_tuwunel_config_cache_capacity_modifier }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_db_cache_capacity_mb | string | length > 0 %}
|
||||
db_cache_capacity_mb = {{ matrix_tuwunel_config_db_cache_capacity_mb }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_db_write_buffer_capacity_mb | string | length > 0 %}
|
||||
db_write_buffer_capacity_mb = {{ matrix_tuwunel_config_db_write_buffer_capacity_mb }}
|
||||
{% endif %}
|
||||
|
||||
{% if matrix_tuwunel_config_sentry_enabled | bool %}
|
||||
sentry = true
|
||||
{% if matrix_tuwunel_config_sentry_endpoint | length > 0 %}
|
||||
sentry_endpoint = {{ matrix_tuwunel_config_sentry_endpoint | to_json }}
|
||||
{% endif %}
|
||||
sentry_send_server_name = {{ matrix_tuwunel_config_sentry_send_server_name | to_json }}
|
||||
sentry_traces_sample_rate = {{ matrix_tuwunel_config_sentry_traces_sample_rate }}
|
||||
{% endif %}
|
||||
|
||||
{% if (matrix_tuwunel_config_tls_certs | length > 0) and (matrix_tuwunel_config_tls_key | length > 0) %}
|
||||
|
||||
[global.tls]
|
||||
certs = {{ matrix_tuwunel_config_tls_certs | to_json }}
|
||||
key = {{ matrix_tuwunel_config_tls_key | to_json }}
|
||||
dual_protocol = {{ matrix_tuwunel_config_tls_dual_protocol | to_json }}
|
||||
{% endif %}
|
||||
|
||||
{% set well_known_keys = [
|
||||
matrix_tuwunel_config_well_known_client,
|
||||
matrix_tuwunel_config_well_known_server,
|
||||
matrix_tuwunel_config_well_known_support_page,
|
||||
matrix_tuwunel_config_well_known_support_email,
|
||||
matrix_tuwunel_config_well_known_support_mxid,
|
||||
matrix_tuwunel_config_well_known_livekit_url,
|
||||
] %}
|
||||
{% if well_known_keys | select | list | length > 0 %}
|
||||
|
||||
[global.well_known]
|
||||
{% if matrix_tuwunel_config_well_known_client | length > 0 %}
|
||||
client = {{ matrix_tuwunel_config_well_known_client | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_well_known_server | length > 0 %}
|
||||
server = {{ matrix_tuwunel_config_well_known_server | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_well_known_support_page | length > 0 %}
|
||||
support_page = {{ matrix_tuwunel_config_well_known_support_page | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_well_known_support_email | length > 0 %}
|
||||
support_email = {{ matrix_tuwunel_config_well_known_support_email | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_well_known_support_mxid | length > 0 %}
|
||||
support_mxid = {{ matrix_tuwunel_config_well_known_support_mxid | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_well_known_livekit_url | length > 0 %}
|
||||
livekit_url = {{ matrix_tuwunel_config_well_known_livekit_url | to_json }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if matrix_tuwunel_config_blurhashing_enabled | bool %}
|
||||
|
||||
[global.blurhashing]
|
||||
components_x = {{ matrix_tuwunel_config_blurhashing_components_x }}
|
||||
components_y = {{ matrix_tuwunel_config_blurhashing_components_y }}
|
||||
blurhash_max_raw_size = {{ matrix_tuwunel_config_blurhashing_max_raw_size }}
|
||||
{% endif %}
|
||||
|
||||
{% if matrix_tuwunel_config_ldap_enabled | bool %}
|
||||
|
||||
[global.ldap]
|
||||
enable = true
|
||||
uri = {{ matrix_tuwunel_config_ldap_uri | to_json }}
|
||||
base_dn = {{ matrix_tuwunel_config_ldap_base_dn | to_json }}
|
||||
{% if matrix_tuwunel_config_ldap_bind_dn | length > 0 %}
|
||||
bind_dn = {{ matrix_tuwunel_config_ldap_bind_dn | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_ldap_bind_password_file | length > 0 %}
|
||||
bind_password_file = {{ matrix_tuwunel_config_ldap_bind_password_file | to_json }}
|
||||
{% endif %}
|
||||
filter = {{ matrix_tuwunel_config_ldap_filter | to_json }}
|
||||
uid_attribute = {{ matrix_tuwunel_config_ldap_uid_attribute | to_json }}
|
||||
name_attribute = {{ matrix_tuwunel_config_ldap_name_attribute | to_json }}
|
||||
{% if matrix_tuwunel_config_ldap_admin_base_dn | length > 0 %}
|
||||
admin_base_dn = {{ matrix_tuwunel_config_ldap_admin_base_dn | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_ldap_admin_filter | length > 0 %}
|
||||
admin_filter = {{ matrix_tuwunel_config_ldap_admin_filter | to_json }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if matrix_tuwunel_config_jwt_enabled | bool %}
|
||||
|
||||
[global.jwt]
|
||||
enable = true
|
||||
{% if matrix_tuwunel_config_jwt_key | length > 0 %}
|
||||
key = {{ matrix_tuwunel_config_jwt_key | to_json }}
|
||||
{% endif %}
|
||||
format = {{ matrix_tuwunel_config_jwt_format | to_json }}
|
||||
algorithm = {{ matrix_tuwunel_config_jwt_algorithm | to_json }}
|
||||
register_user = {{ matrix_tuwunel_config_jwt_register_user | to_json }}
|
||||
{% if matrix_tuwunel_config_jwt_audience | length > 0 %}
|
||||
audience = {{ matrix_tuwunel_config_jwt_audience | to_json }}
|
||||
{% endif %}
|
||||
{% if matrix_tuwunel_config_jwt_issuer | length > 0 %}
|
||||
issuer = {{ matrix_tuwunel_config_jwt_issuer | to_json }}
|
||||
{% endif %}
|
||||
require_exp = {{ matrix_tuwunel_config_jwt_require_exp | to_json }}
|
||||
require_nbf = {{ matrix_tuwunel_config_jwt_require_nbf | to_json }}
|
||||
validate_exp = {{ matrix_tuwunel_config_jwt_validate_exp | to_json }}
|
||||
validate_nbf = {{ matrix_tuwunel_config_jwt_validate_nbf | to_json }}
|
||||
{% endif %}
|
||||
|
||||
{% for idp in matrix_tuwunel_config_identity_providers %}
|
||||
|
||||
[[global.identity_provider]]
|
||||
{% for key, value in idp.items() %}
|
||||
{{ key }} = {{ value | to_json }}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
{% for sp in matrix_tuwunel_config_storage_providers %}
|
||||
|
||||
[global.storage_provider.{{ sp.id }}.{{ sp.kind }}]
|
||||
{% for key, value in sp.items() if key not in ['id', 'kind'] %}
|
||||
{{ key }} = {{ value | to_json }}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
9
roles/custom/matrix-tuwunel/vars/main.yml
Normal file
9
roles/custom/matrix-tuwunel/vars/main.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
# SPDX-FileCopyrightText: 2026 MDAD project contributors
|
||||
# SPDX-FileCopyrightText: 2026 Slavi Pantaleev
|
||||
#
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
---
|
||||
|
||||
matrix_tuwunel_client_api_url_endpoint_public: "{{ 'https' if matrix_playbook_ssl_enabled else 'http' }}://{{ matrix_tuwunel_hostname }}/_matrix/client/versions"
|
||||
matrix_tuwunel_federation_api_url_endpoint_public: "{{ 'https' if matrix_playbook_ssl_enabled else 'http' }}://{{ matrix_tuwunel_hostname }}:{{ matrix_federation_public_port }}/_matrix/federation/v1/version"
|
||||
Reference in New Issue
Block a user