| @@ -0,0 +1,175 @@ | |||||
| --- | |||||
| # Dendrite is a second-generation Matrix homeserver currently in Beta | |||||
| # See: https://github.com/matrix-org/dendrite | |||||
| matrix_conduit_enabled: true | |||||
| matrix_conduit_docker_image: "{{ matrix_conduit_docker_image_name_prefix }}matrixconduit/matrix-conduit:{{ matrix_conduit_docker_image_tag }}" | |||||
| matrix_conduit_docker_image_name_prefix: "docker.io/" | |||||
| matrix_conduit_docker_image_tag: "v0.5.1" | |||||
| matrix_conduit_docker_image_force_pull: "{{ matrix_conduit_docker_image.endswith(':latest') }}" | |||||
| matrix_conduit_base_path: "{{ matrix_base_data_path }}/dendrite" | |||||
| matrix_conduit_config_dir_path: "{{ matrix_conduit_base_path }}/config" | |||||
| matrix_conduit_storage_path: "{{ matrix_conduit_base_path }}/storage" | |||||
| matrix_conduit_media_store_path: "{{ matrix_conduit_storage_path }}/media-store" | |||||
| matrix_conduit_ext_path: "{{ matrix_conduit_base_path }}/ext" | |||||
| # By default, we make Dendrite only serve HTTP (not HTTPS). | |||||
| # HTTPS is usually served at the reverse-proxy side (usually via `matrix-nginx-proxy`). | |||||
| # | |||||
| # To enable HTTPS serving by Dendrite (directly): | |||||
| # - `matrix_conduit_https_bind_port` must be set | |||||
| # - `-tls-cert` and `-tls-key` must be passed to Dendrite via `matrix_conduit_process_extra_arguments` | |||||
| # - the TLS certificate files must be mounted into the container using `matrix_conduit_container_additional_volumes` | |||||
| matrix_conduit_http_bind_port: 8008 | |||||
| matrix_conduit_https_bind_port: ~ | |||||
| # This is passed as an `-http-bind-address` flag to the Dendrite server in the container | |||||
| matrix_conduit_http_bind_address: "{{ (':' + matrix_conduit_http_bind_port|string) if matrix_conduit_http_bind_port else '' }}" | |||||
| # This is passed as an `-https-bind-address` flag to the Dendrite server in the container | |||||
| matrix_conduit_https_bind_address: "{{ (':' + matrix_conduit_https_bind_port|string) if matrix_conduit_https_bind_port else '' }}" | |||||
| # Controls whether the matrix-dendrite container exposes the HTTP port (tcp/{{ matrix_conduit_http_bind_port }} in the container). | |||||
| # | |||||
| # Takes an "<ip>:<port>" or "<port>" value (e.g. "127.0.0.1:8008"), or empty string to not expose. | |||||
| matrix_conduit_container_http_host_bind_address: "" | |||||
| # Controls whether the matrix-dendrite container exposes the HTTPS port (tcp/{{ matrix_conduit_https_bind_port }} in the container). | |||||
| # | |||||
| # Takes an "<ip>:<port>" or "<port>" value (e.g. "127.0.0.1:8448"), or empty string to not expose. | |||||
| matrix_conduit_container_https_host_bind_address: "" | |||||
| # A list of extra arguments to pass to the container (`docker run` command) | |||||
| matrix_conduit_container_extra_arguments: [] | |||||
| # A list of extra arguments to pass to the container process (`dendrite-monolith` command) | |||||
| # Example: | |||||
| # matrix_conduit_process_extra_arguments: | |||||
| # - "-tls-cert /some/path.crt" | |||||
| # - "-tls-key /some/path.pem" | |||||
| matrix_conduit_process_extra_arguments: [] | |||||
| # List of systemd services that matrix-dendrite.service depends on | |||||
| matrix_conduit_systemd_required_services_list: ["docker.service"] | |||||
| # List of systemd services that matrix-dendrite.service wants | |||||
| matrix_conduit_systemd_wanted_services_list: [] | |||||
| # Specifies which template files to use when configuring Dendrite. | |||||
| # If you'd like to have your own different configuration, feel free to copy and paste | |||||
| # the original files into your inventory (e.g. in `inventory/host_vars/<host>/`) | |||||
| # and then change the specific host's `vars.yaml` file like this: | |||||
| # matrix_conduit_template_conduit_config: "{{ playbook_dir }}/inventory/host_vars/<host>/dendrite.yaml.j2" | |||||
| matrix_conduit_template_conduit_config: "{{ role_path }}/templates/dendrite/dendrite.yaml.j2" | |||||
| matrix_conduit_registration_shared_secret: '' | |||||
| matrix_conduit_allow_guest_access: false | |||||
| matrix_conduit_max_file_size_bytes: 10485760 | |||||
| # Controls which HTTP header (e.g. 'X-Forwarded-For', 'X-Real-IP') to inspect to find the real remote IP address of the client. | |||||
| # This is likely required if Dendrite is running behind a reverse proxy server. | |||||
| matrix_conduit_sync_api_real_ip_header: '' | |||||
| # The tmpfs at /tmp needs to be large enough to handle multiple concurrent file uploads. | |||||
| matrix_conduit_tmp_directory_size_mb: 500 | |||||
| # Rate limits | |||||
| matrix_conduit_rate_limiting_enabled: true | |||||
| matrix_conduit_rate_limiting_threshold: 5 | |||||
| matrix_conduit_rate_limiting_cooloff_ms: 500 | |||||
| # Controls whether people with access to the homeserver can register by themselves. | |||||
| matrix_conduit_registration_disabled: false | |||||
| # reCAPTCHA API for validating registration attempts | |||||
| matrix_conduit_enable_registration_captcha: false | |||||
| matrix_conduit_recaptcha_public_key: "" | |||||
| matrix_conduit_recaptcha_private_key: "" | |||||
| # A list of additional "volumes" to mount in the container. | |||||
| # This list gets populated dynamically based on Dendrite extensions that have been enabled. | |||||
| # Contains definition objects like this: `{"src": "/outside", "dst": "/inside", "options": "rw|ro|slave|.."} | |||||
| # | |||||
| # Note: internally, this uses the `-v` flag for mounting the specified volumes. | |||||
| # It's better (safer) to use the `--mount` flag for mounting volumes. | |||||
| # To use `--mount`, specify it in `matrix_conduit_container_extra_arguments`. | |||||
| # Example: `matrix_conduit_container_extra_arguments: ['--mount type=bind,src=/outside,dst=/inside,ro'] | |||||
| matrix_conduit_container_additional_volumes: [] | |||||
| # A list of appservice config files (in-container filesystem paths). | |||||
| # This list gets populated dynamically based on Dendrite extensions that have been enabled. | |||||
| # You may wish to use this together with `matrix_conduit_container_additional_volumes` or `matrix_conduit_container_extra_arguments`. | |||||
| matrix_conduit_app_service_config_files: [] | |||||
| # Enable exposure of metrics | |||||
| matrix_conduit_metrics_enabled: false | |||||
| matrix_conduit_metrics_username: "metrics" | |||||
| matrix_conduit_metrics_password: "metrics" | |||||
| # Postgres database information | |||||
| matrix_conduit_database_str: "postgresql://{{ matrix_conduit_database_user }}:{{ matrix_conduit_database_password }}@{{ matrix_conduit_database_hostname }}" | |||||
| matrix_conduit_database_hostname: "matrix-postgres" | |||||
| matrix_conduit_database_user: "dendrite" | |||||
| matrix_conduit_database_password: "itsasecret" | |||||
| matrix_conduit_naffka_database: "dendrite_naffka" | |||||
| matrix_conduit_appservice_database: "dendrite_appservice" | |||||
| matrix_conduit_federationsender_database: "dendrite_federationsender" | |||||
| matrix_conduit_keyserver_database: "dendrite_keyserver" | |||||
| matrix_conduit_mediaapi_database: "dendrite_mediaapi" | |||||
| matrix_conduit_room_database: "dendrite_room" | |||||
| matrix_conduit_singingkeyserver_database: "dendrite_sigingkeyserver" | |||||
| matrix_conduit_syncapi_database: "dendrite_syncapi" | |||||
| matrix_conduit_account_database: "dendrite_account" | |||||
| matrix_conduit_device_database: "dendrite_device" | |||||
| matrix_conduit_mscs_database: "dendrite_mscs" | |||||
| matrix_conduit_turn_uris: [] | |||||
| matrix_conduit_turn_shared_secret: "" | |||||
| matrix_conduit_turn_allow_guests: false | |||||
| # Controls whether the self-check feature should validate TLS certificates. | |||||
| matrix_conduit_disable_tls_validation: false | |||||
| matrix_conduit_trusted_id_servers: | |||||
| - "matrix.org" | |||||
| - "vector.im" | |||||
| # Controls whether Dendrite will federate at all. | |||||
| # Disable this to completely isolate your server from the rest of the Matrix network. | |||||
| matrix_conduit_federation_enabled: true | |||||
| # Controls whether the self-check feature should validate SSL certificates. | |||||
| matrix_conduit_self_check_validate_certificates: true | |||||
| # Default Dendrite configuration template which covers the generic use case. | |||||
| # You can customize it by controlling the various variables inside it. | |||||
| # | |||||
| # For a more advanced customization, you can extend the default (see `matrix_conduit_configuration_extension_yaml`) | |||||
| # or completely replace this variable with your own template. | |||||
| matrix_conduit_configuration_yaml: "{{ lookup('template', 'templates/dendrite/dendrite.yaml.j2') }}" | |||||
| matrix_conduit_configuration_extension_yaml: | | |||||
| # Your custom YAML configuration for Dendrite goes here. | |||||
| # This configuration extends the default starting configuration (`matrix_conduit_configuration_yaml`). | |||||
| # | |||||
| # You can override individual variables from the default configuration, or introduce new ones. | |||||
| # | |||||
| # If you need something more special, you can take full control by | |||||
| # completely redefining `matrix_conduit_configuration_yaml`. | |||||
| # | |||||
| # Example configuration extension follows: | |||||
| # | |||||
| # server_notices: | |||||
| # system_mxid_localpart: notices | |||||
| # system_mxid_display_name: "Server Notices" | |||||
| # system_mxid_avatar_url: "mxc://server.com/oumMVlgDnLYFaPVkExemNVVZ" | |||||
| # room_name: "Server Notices" | |||||
| matrix_conduit_configuration_extension: "{{ matrix_conduit_configuration_extension_yaml|from_yaml if matrix_conduit_configuration_extension_yaml|from_yaml is mapping else {} }}" | |||||
| # Holds the final Dendrite configuration (a combination of the default and its extension). | |||||
| # You most likely don't need to touch this variable. Instead, see `matrix_conduit_configuration_yaml`. | |||||
| matrix_conduit_configuration: "{{ matrix_conduit_configuration_yaml|from_yaml|combine(matrix_conduit_configuration_extension, recursive=True) }}" | |||||
| @@ -0,0 +1,7 @@ | |||||
| --- | |||||
| - import_tasks: "{{ role_path }}/tasks/dendrite/setup_install.yml" | |||||
| when: matrix_conduit_enabled|bool | |||||
| - import_tasks: "{{ role_path }}/tasks/dendrite/setup_uninstall.yml" | |||||
| when: "not matrix_conduit_enabled|bool" | |||||
| @@ -0,0 +1,81 @@ | |||||
| --- | |||||
| # This will throw a Permission Denied error if already mounted using fuse | |||||
| - name: Check Dendrite media store path | |||||
| stat: | |||||
| path: "{{ matrix_conduit_media_store_path }}" | |||||
| register: local_path_media_store_stat | |||||
| ignore_errors: true | |||||
| # This is separate and conditional, to ensure we don't execute it | |||||
| # if the path already exists or we failed to check, because it's mounted using fuse. | |||||
| - name: Ensure Dendrite media store path exists | |||||
| file: | |||||
| path: "{{ matrix_conduit_media_store_path }}" | |||||
| state: directory | |||||
| mode: 0750 | |||||
| owner: "{{ matrix_user_username }}" | |||||
| group: "{{ matrix_user_groupname }}" | |||||
| when: "not local_path_media_store_stat.failed and not local_path_media_store_stat.stat.exists" | |||||
| - name: Ensure Dendrite Docker image is pulled | |||||
| docker_image: | |||||
| name: "{{ matrix_conduit_docker_image }}" | |||||
| source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" | |||||
| force_source: "{{ matrix_conduit_docker_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}" | |||||
| force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_conduit_docker_image_force_pull }}" | |||||
| register: result | |||||
| retries: "{{ matrix_container_retries_count }}" | |||||
| delay: "{{ matrix_container_retries_delay }}" | |||||
| until: result is not failed | |||||
| - name: Check if a Dendrite signing key exists | |||||
| stat: | |||||
| path: "{{ matrix_conduit_config_dir_path }}/{{ matrix_server_fqn_matrix }}.signing.pem" | |||||
| register: matrix_conduit_signing_key_stat | |||||
| # We do this so that the signing key would get generated. | |||||
| # We don't use the `docker_container` module, because using it with `cap_drop` requires | |||||
| # a very recent version, which is not available for a lot of people yet. | |||||
| - name: Generate Dendrite signing key | |||||
| command: | | |||||
| docker run | |||||
| --rm | |||||
| --name=matrix-dendrite-config | |||||
| --entrypoint=generate-keys | |||||
| --mount type=bind,src={{ matrix_conduit_config_dir_path }},dst=/data | |||||
| {{ matrix_conduit_docker_image }} --private-key=/data/{{ matrix_server_fqn_matrix }}.signing.pem | |||||
| generate | |||||
| when: "not matrix_conduit_signing_key_stat.stat.exists" | |||||
| - name: Ensure Dendrite server key exists | |||||
| file: | |||||
| path: "{{ matrix_conduit_config_dir_path }}/{{ matrix_server_fqn_matrix }}.signing.pem" | |||||
| mode: 0644 | |||||
| owner: "{{ matrix_user_username }}" | |||||
| group: "{{ matrix_user_groupname }}" | |||||
| - name: Ensure Dendrite configuration installed | |||||
| copy: | |||||
| content: "{{ matrix_conduit_configuration|to_nice_yaml(indent=2, width=999999) }}" | |||||
| dest: "{{ matrix_conduit_config_dir_path }}/dendrite.yaml" | |||||
| mode: 0644 | |||||
| owner: "{{ matrix_user_username }}" | |||||
| group: "{{ matrix_user_groupname }}" | |||||
| - name: Ensure matrix-dendrite.service installed | |||||
| template: | |||||
| src: "{{ role_path }}/templates/dendrite/systemd/matrix-dendrite.service.j2" | |||||
| dest: "{{ matrix_systemd_path }}/matrix-dendrite.service" | |||||
| mode: 0644 | |||||
| register: matrix_conduit_systemd_service_result | |||||
| - name: Ensure systemd reloaded after matrix-dendrite.service installation | |||||
| service: | |||||
| daemon_reload: true | |||||
| when: "matrix_conduit_systemd_service_result.changed|bool" | |||||
| - name: Ensure matrix-dendrite-create-account script created | |||||
| template: | |||||
| src: "{{ role_path }}/templates/dendrite/usr-local-bin/matrix-dendrite-create-account.j2" | |||||
| dest: "{{ matrix_local_bin_path }}/matrix-dendrite-create-account" | |||||
| mode: 0750 | |||||
| @@ -0,0 +1,30 @@ | |||||
| --- | |||||
| - name: Check existence of matrix-dendrite service | |||||
| stat: | |||||
| path: "{{ matrix_systemd_path }}/matrix-dendrite.service" | |||||
| register: matrix_conduit_service_stat | |||||
| - name: Ensure matrix-dendrite is stopped | |||||
| service: | |||||
| name: matrix-dendrite | |||||
| state: stopped | |||||
| daemon_reload: true | |||||
| register: stopping_result | |||||
| when: "matrix_conduit_service_stat.stat.exists" | |||||
| - name: Ensure matrix-dendrite.service doesn't exist | |||||
| file: | |||||
| path: "{{ matrix_systemd_path }}/matrix-dendrite.service" | |||||
| state: absent | |||||
| when: "matrix_conduit_service_stat.stat.exists" | |||||
| - name: Ensure systemd reloaded after matrix-dendrite.service removal | |||||
| service: | |||||
| daemon_reload: true | |||||
| when: "matrix_conduit_service_stat.stat.exists" | |||||
| - name: Ensure Dendrite Docker image doesn't exist | |||||
| docker_image: | |||||
| name: "{{ matrix_conduit_docker_image }}" | |||||
| state: absent | |||||
| @@ -0,0 +1,5 @@ | |||||
| --- | |||||
| - set_fact: | |||||
| matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-dendrite.service'] }}" | |||||
| when: matrix_conduit_enabled|bool | |||||
| @@ -0,0 +1,42 @@ | |||||
| --- | |||||
| - import_tasks: "{{ role_path }}/tasks/init.yml" | |||||
| tags: | |||||
| - always | |||||
| - import_tasks: "{{ role_path }}/tasks/validate_config.yml" | |||||
| when: run_setup|bool | |||||
| tags: | |||||
| - setup-all | |||||
| - setup-dendrite | |||||
| - import_tasks: "{{ role_path }}/tasks/setup_dendrite.yml" | |||||
| when: run_setup|bool | |||||
| tags: | |||||
| - setup-all | |||||
| - setup-dendrite | |||||
| - import_tasks: "{{ role_path }}/tasks/register_user.yml" | |||||
| when: run_conduit_register_user|bool and matrix_conduit_enabled|bool | |||||
| tags: | |||||
| - register-user | |||||
| - import_tasks: "{{ role_path }}/tasks/self_check_client_api.yml" | |||||
| delegate_to: 127.0.0.1 | |||||
| become: false | |||||
| when: run_self_check|bool and matrix_conduit_enabled|bool | |||||
| tags: | |||||
| - self-check | |||||
| - import_tasks: "{{ role_path }}/tasks/self_check_federation_api.yml" | |||||
| delegate_to: 127.0.0.1 | |||||
| become: false | |||||
| when: run_self_check|bool and matrix_conduit_enabled|bool | |||||
| tags: | |||||
| - self-check | |||||
| - name: Mark matrix-dendrite role as executed | |||||
| set_fact: | |||||
| matrix_conduit_role_executed: true | |||||
| tags: | |||||
| - always | |||||
| @@ -0,0 +1,25 @@ | |||||
| --- | |||||
| - name: Fail if playbook called incorrectly | |||||
| fail: | |||||
| msg: "The `username` variable needs to be provided to this playbook, via --extra-vars" | |||||
| when: "username is not defined or username == '<your-username>'" | |||||
| - name: Fail if playbook called incorrectly | |||||
| fail: | |||||
| msg: "The `password` variable needs to be provided to this playbook, via --extra-vars" | |||||
| when: "password is not defined or password == '<your-password>'" | |||||
| - name: Ensure matrix-dendrite is started | |||||
| service: | |||||
| name: matrix-dendrite | |||||
| state: started | |||||
| daemon_reload: true | |||||
| register: start_result | |||||
| - name: Wait a while, so that Dendrite can manage to start | |||||
| pause: | |||||
| seconds: 7 | |||||
| when: "start_result.changed" | |||||
| - name: Register user | |||||
| command: "{{ matrix_local_bin_path }}/matrix-dendrite-create-account {{ username|quote }} {{ password|quote }}" | |||||
| @@ -0,0 +1,18 @@ | |||||
| --- | |||||
| - name: Check Matrix Client API | |||||
| uri: | |||||
| url: "{{ matrix_conduit_client_api_url_endpoint_public }}" | |||||
| follow_redirects: none | |||||
| validate_certs: "{{ matrix_conduit_self_check_validate_certificates }}" | |||||
| register: result_matrix_conduit_client_api | |||||
| ignore_errors: true | |||||
| check_mode: false | |||||
| - name: Fail if Matrix Client API not working | |||||
| fail: | |||||
| msg: "Failed checking Matrix Client API is up at `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ matrix_conduit_client_api_url_endpoint_public }}`). Is Dendrite running? Is port 443 open in your firewall? Full error: {{ result_matrix_conduit_client_api }}" | |||||
| when: "(result_matrix_conduit_client_api.failed or 'json' not in result_matrix_conduit_client_api)" | |||||
| - name: Report working Matrix Client API | |||||
| debug: | |||||
| msg: "The Matrix Client API at `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ matrix_conduit_client_api_url_endpoint_public }}`) is working" | |||||
| @@ -0,0 +1,24 @@ | |||||
| --- | |||||
| - name: Check Matrix Federation API | |||||
| uri: | |||||
| url: "{{ matrix_conduit_federation_api_url_endpoint_public }}" | |||||
| follow_redirects: none | |||||
| validate_certs: "{{ matrix_conduit_self_check_validate_certificates }}" | |||||
| register: result_matrix_conduit_federation_api | |||||
| ignore_errors: true | |||||
| check_mode: false | |||||
| - name: Fail if Matrix Federation API not working | |||||
| fail: | |||||
| msg: "Failed checking Matrix Federation API is up at `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ matrix_conduit_federation_api_url_endpoint_public }}`). Is Dendrite running? Is port {{ matrix_federation_public_port }} open in your firewall? Full error: {{ result_matrix_conduit_federation_api }}" | |||||
| when: "matrix_conduit_federation_enabled|bool and (result_matrix_conduit_federation_api.failed or 'json' not in result_matrix_conduit_federation_api)" | |||||
| - name: Fail if Matrix Federation API unexpectedly enabled | |||||
| fail: | |||||
| msg: "Matrix Federation API is up at `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ matrix_conduit_federation_api_url_endpoint_public }}`) despite being disabled." | |||||
| when: "not matrix_conduit_federation_enabled|bool and not result_matrix_conduit_federation_api.failed" | |||||
| - name: Report working Matrix Federation API | |||||
| debug: | |||||
| msg: "The Matrix Federation API at `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ matrix_conduit_federation_api_url_endpoint_public }}`) is working" | |||||
| when: "matrix_conduit_federation_enabled|bool" | |||||
| @@ -0,0 +1,14 @@ | |||||
| --- | |||||
| - name: Ensure Dendrite paths exist | |||||
| file: | |||||
| path: "{{ item.path }}" | |||||
| state: directory | |||||
| mode: 0750 | |||||
| owner: "{{ matrix_user_username }}" | |||||
| group: "{{ matrix_user_groupname }}" | |||||
| with_items: | |||||
| - {path: "{{ matrix_conduit_config_dir_path }}", when: true} | |||||
| - {path: "{{ matrix_conduit_ext_path }}", when: true} | |||||
| when: "matrix_conduit_enabled|bool and item.when" | |||||
| - import_tasks: "{{ role_path }}/tasks/dendrite/setup.yml" | |||||
| @@ -0,0 +1,16 @@ | |||||
| --- | |||||
| - name: Fail if required Dendrite settings not defined | |||||
| fail: | |||||
| msg: >- | |||||
| You need to define a required configuration setting (`{{ item }}`) for using Dendrite. | |||||
| when: "vars[item] == ''" | |||||
| with_items: | |||||
| - "matrix_conduit_registration_shared_secret" | |||||
| - name: (Deprecation) Catch and report renamed settings | |||||
| fail: | |||||
| msg: >- | |||||
| Your configuration contains a variable, which now has a different name. | |||||
| Please change your configuration to rename the variable (`{{ item.old }}` -> `{{ item.new }}`). | |||||
| when: "item.old in vars" | |||||
| with_items: [] | |||||
| @@ -0,0 +1,390 @@ | |||||
| # This is the Dendrite configuration file. | |||||
| # | |||||
| # The configuration is split up into sections - each Dendrite component has a | |||||
| # configuration section, in addition to the "global" section which applies to | |||||
| # all components. | |||||
| # | |||||
| # At a minimum, to get started, you will need to update the settings in the | |||||
| # "global" section for your deployment, and you will need to check that the | |||||
| # database "connection_string" line in each component section is correct. | |||||
| # | |||||
| # Each component with a "database" section can accept the following formats | |||||
| # for "connection_string": | |||||
| # SQLite: file:filename.db | |||||
| # file:///path/to/filename.db | |||||
| # PostgreSQL: postgresql://user:pass@hostname/database?params=... | |||||
| # | |||||
| # SQLite is embedded into Dendrite and therefore no further prerequisites are | |||||
| # needed for the database when using SQLite mode. However, performance with | |||||
| # PostgreSQL is significantly better and recommended for multi-user deployments. | |||||
| # SQLite is typically around 20-30% slower than PostgreSQL when tested with a | |||||
| # small number of users and likely will perform worse still with a higher volume | |||||
| # of users. | |||||
| # | |||||
| # The "max_open_conns" and "max_idle_conns" settings configure the maximum | |||||
| # number of open/idle database connections. The value 0 will use the database | |||||
| # engine default, and a negative value will use unlimited connections. The | |||||
| # "conn_max_lifetime" option controls the maximum length of time a database | |||||
| # connection can be idle in seconds - a negative value is unlimited. | |||||
| # The version of the configuration file. | |||||
| version: 1 | |||||
| # Global Matrix configuration. This configuration applies to all components. | |||||
| global: | |||||
| # The domain name of this homeserver. | |||||
| server_name: {{ matrix_domain|to_json }} | |||||
| # The path to the signing private key file, used to sign requests and events. | |||||
| # Note that this is NOT the same private key as used for TLS! To generate a | |||||
| # signing key, use "./bin/generate-keys --private-key matrix_key.pem". | |||||
| private_key: "/data/{{ matrix_server_fqn_matrix }}.signing.pem" | |||||
| # The paths and expiry timestamps (as a UNIX timestamp in millisecond precision) | |||||
| # to old signing private keys that were formerly in use on this domain. These | |||||
| # keys will not be used for federation request or event signing, but will be | |||||
| # provided to any other homeserver that asks when trying to verify old events. | |||||
| # old_private_keys: | |||||
| # - private_key: old_matrix_key.pem | |||||
| # expired_at: 1601024554498 | |||||
| # How long a remote server can cache our server signing key before requesting it | |||||
| # again. Increasing this number will reduce the number of requests made by other | |||||
| # servers for our key but increases the period that a compromised key will be | |||||
| # considered valid by other homeservers. | |||||
| key_validity_period: 168h0m0s | |||||
| # The server name to delegate server-server communications to, with optional port | |||||
| # e.g. localhost:443 | |||||
| well_known_server_name: "" | |||||
| # Lists of domains that the server will trust as identity servers to verify third | |||||
| # party identifiers such as phone numbers and email addresses. | |||||
| trusted_third_party_id_servers: {{ matrix_conduit_trusted_id_servers|to_json }} | |||||
| # Disables federation. Dendrite will not be able to make any outbound HTTP requests | |||||
| # to other servers and the federation API will not be exposed. | |||||
| disable_federation: {{ (not matrix_conduit_federation_enabled)|to_json }} | |||||
| # Configuration for Kafka/Naffka. | |||||
| kafka: | |||||
| # List of Kafka broker addresses to connect to. This is not needed if using | |||||
| # Naffka in monolith mode. | |||||
| addresses: [] | |||||
| # The prefix to use for Kafka topic names for this homeserver. Change this only if | |||||
| # you are running more than one Dendrite homeserver on the same Kafka deployment. | |||||
| topic_prefix: Dendrite | |||||
| # Whether to use Naffka instead of Kafka. This is only available in monolith | |||||
| # mode, but means that you can run a single-process server without requiring | |||||
| # Kafka. | |||||
| use_naffka: true | |||||
| # The max size a Kafka message is allowed to use. | |||||
| # You only need to change this value, if you encounter issues with too large messages. | |||||
| # Must be less than/equal to "max.message.bytes" configured in Kafka. | |||||
| # Defaults to 8388608 bytes. | |||||
| # max_message_bytes: 8388608 | |||||
| # Naffka database options. Not required when using Kafka. | |||||
| naffka_database: | |||||
| connection_string: {{ matrix_conduit_database_str }}/{{ matrix_conduit_naffka_database }}?sslmode=disable | |||||
| max_open_conns: 10 | |||||
| max_idle_conns: 2 | |||||
| conn_max_lifetime: -1 | |||||
| # Configuration for Prometheus metric collection. | |||||
| metrics: | |||||
| # Whether or not Prometheus metrics are enabled. | |||||
| enabled: {{ matrix_conduit_metrics_enabled|to_json }} | |||||
| # HTTP basic authentication to protect access to monitoring. | |||||
| basic_auth: | |||||
| username: {{ matrix_conduit_metrics_username|to_json }} | |||||
| password: {{ matrix_conduit_metrics_password|to_json }} | |||||
| # DNS cache options. The DNS cache may reduce the load on DNS servers | |||||
| # if there is no local caching resolver available for use. | |||||
| dns_cache: | |||||
| # Whether or not the DNS cache is enabled. | |||||
| enabled: false | |||||
| # Maximum number of entries to hold in the DNS cache, and | |||||
| # for how long those items should be considered valid in seconds. | |||||
| cache_size: 256 | |||||
| cache_lifetime: "5m" # 5minutes; see https://pkg.go.dev/time@master#ParseDuration for more | |||||
| # Configuration for the Appservice API. | |||||
| app_service_api: | |||||
| internal_api: | |||||
| listen: http://0.0.0.0:7777 | |||||
| connect: http://appservice_api:7777 | |||||
| database: | |||||
| connection_string: {{ matrix_conduit_database_str }}/{{ matrix_conduit_appservice_database }}?sslmode=disable | |||||
| max_open_conns: 10 | |||||
| max_idle_conns: 2 | |||||
| conn_max_lifetime: -1 | |||||
| # Disable the validation of TLS certificates of appservices. This is | |||||
| # not recommended in production since it may allow appservice traffic | |||||
| # to be sent to an unverified endpoint. | |||||
| disable_tls_validation: false | |||||
| # Appservice configuration files to load into this homeserver. | |||||
| config_files: {{ matrix_conduit_app_service_config_files|to_json }} | |||||
| # Configuration for the Client API. | |||||
| client_api: | |||||
| internal_api: | |||||
| listen: http://0.0.0.0:7771 | |||||
| connect: http://client_api:7771 | |||||
| external_api: | |||||
| listen: http://0.0.0.0:8071 | |||||
| # Prevents new users from being able to register on this homeserver, except when | |||||
| # using the registration shared secret below. | |||||
| registration_disabled: {{ matrix_conduit_registration_disabled|to_json }} | |||||
| # If set, allows registration by anyone who knows the shared secret, regardless of | |||||
| # whether registration is otherwise disabled. | |||||
| registration_shared_secret: {{ matrix_conduit_registration_shared_secret|string|to_json }} | |||||
| # Whether to require reCAPTCHA for registration. | |||||
| enable_registration_captcha: {{ matrix_conduit_enable_registration_captcha|to_json }} | |||||
| # Settings for ReCAPTCHA. | |||||
| recaptcha_public_key: {{ matrix_conduit_recaptcha_public_key|to_json }} | |||||
| recaptcha_private_key: {{ matrix_conduit_recaptcha_private_key|to_json }} | |||||
| recaptcha_bypass_secret: "" | |||||
| recaptcha_siteverify_api: "" | |||||
| # TURN server information that this homeserver should send to clients. | |||||
| turn: | |||||
| turn_user_lifetime: "" | |||||
| turn_uris: {{ matrix_conduit_turn_uris|to_json }} | |||||
| turn_shared_secret: {{ matrix_conduit_turn_shared_secret|to_json }} | |||||
| turn_username: "" | |||||
| turn_password: "" | |||||
| # Settings for rate-limited endpoints. Rate limiting will kick in after the | |||||
| # threshold number of "slots" have been taken by requests from a specific | |||||
| # host. Each "slot" will be released after the cooloff time in milliseconds. | |||||
| rate_limiting: | |||||
| enabled: {{ matrix_conduit_rate_limiting_enabled|to_json }} | |||||
| threshold: {{ matrix_conduit_rate_limiting_threshold|to_json }} | |||||
| cooloff_ms: {{ matrix_conduit_rate_limiting_cooloff_ms|to_json }} | |||||
| # Configuration for the EDU server. | |||||
| edu_server: | |||||
| internal_api: | |||||
| listen: http://0.0.0.0:7778 | |||||
| connect: http://edu_server:7778 | |||||
| # Configuration for the Federation API. | |||||
| federation_api: | |||||
| internal_api: | |||||
| listen: http://0.0.0.0:7772 | |||||
| connect: http://federation_api:7772 | |||||
| external_api: | |||||
| listen: http://0.0.0.0:8072 | |||||
| # List of paths to X.509 certificates to be used by the external federation listeners. | |||||
| # These certificates will be used to calculate the TLS fingerprints and other servers | |||||
| # will expect the certificate to match these fingerprints. Certificates must be in PEM | |||||
| # format. | |||||
| federation_certificates: [] | |||||
| # Configuration for the Federation Sender. | |||||
| federation_sender: | |||||
| internal_api: | |||||
| listen: http://0.0.0.0:7775 | |||||
| connect: http://federation_sender:7775 | |||||
| database: | |||||
| connection_string: {{ matrix_conduit_database_str }}/{{ matrix_conduit_federationsender_database }}?sslmode=disable | |||||
| max_open_conns: 10 | |||||
| max_idle_conns: 2 | |||||
| conn_max_lifetime: -1 | |||||
| # How many times we will try to resend a failed transaction to a specific server. The | |||||
| # backoff is 2**x seconds, so 1 = 2 seconds, 2 = 4 seconds, 3 = 8 seconds etc. | |||||
| send_max_retries: 16 | |||||
| # Disable the validation of TLS certificates of remote federated homeservers. Do not | |||||
| # enable this option in production as it presents a security risk! | |||||
| disable_tls_validation: {{ matrix_conduit_disable_tls_validation|to_json }} | |||||
| # Use the following proxy server for outbound federation traffic. | |||||
| proxy_outbound: | |||||
| enabled: false | |||||
| protocol: http | |||||
| host: localhost | |||||
| port: 8080 | |||||
| # Configuration for the Key Server (for end-to-end encryption). | |||||
| key_server: | |||||
| internal_api: | |||||
| listen: http://0.0.0.0:7779 | |||||
| connect: http://key_server:7779 | |||||
| database: | |||||
| connection_string: {{ matrix_conduit_database_str }}/{{ matrix_conduit_keyserver_database }}?sslmode=disable | |||||
| max_open_conns: 10 | |||||
| max_idle_conns: 2 | |||||
| conn_max_lifetime: -1 | |||||
| # Configuration for the Media API. | |||||
| media_api: | |||||
| internal_api: | |||||
| listen: http://0.0.0.0:7774 | |||||
| connect: http://media_api:7774 | |||||
| external_api: | |||||
| listen: http://0.0.0.0:8074 | |||||
| database: | |||||
| connection_string: {{ matrix_conduit_database_str }}/{{ matrix_conduit_mediaapi_database }}?sslmode=disable | |||||
| max_open_conns: 10 | |||||
| max_idle_conns: 2 | |||||
| conn_max_lifetime: -1 | |||||
| # Storage path for uploaded media. May be relative or absolute. | |||||
| base_path: "/matrix-media-store-parent/{{ matrix_conduit_media_store_directory_name }}" | |||||
| # The maximum allowed file size (in bytes) for media uploads to this homeserver | |||||
| # (0 = unlimited). If using a reverse proxy, ensure it allows requests at | |||||
| # least this large (e.g. client_max_body_size in nginx.) | |||||
| max_file_size_bytes: {{ matrix_conduit_max_file_size_bytes|to_json }} | |||||
| # Whether to dynamically generate thumbnails if needed. | |||||
| dynamic_thumbnails: false | |||||
| # The maximum number of simultaneous thumbnail generators to run. | |||||
| max_thumbnail_generators: 10 | |||||
| # A list of thumbnail sizes to be generated for media content. | |||||
| thumbnail_sizes: | |||||
| - width: 32 | |||||
| height: 32 | |||||
| method: crop | |||||
| - width: 96 | |||||
| height: 96 | |||||
| method: crop | |||||
| - width: 640 | |||||
| height: 480 | |||||
| method: scale | |||||
| # Configuration for experimental MSC's | |||||
| mscs: | |||||
| # A list of enabled MSC's | |||||
| # Currently valid values are: | |||||
| # - msc2836 (Threading, see https://github.com/matrix-org/matrix-doc/pull/2836) | |||||
| # - msc2946 (Spaces Summary, see https://github.com/matrix-org/matrix-doc/pull/2946) | |||||
| mscs: [] | |||||
| database: | |||||
| connection_string: {{ matrix_conduit_database_str }}/{{ matrix_conduit_mscs_database }}?sslmode=disable | |||||
| max_open_conns: 5 | |||||
| max_idle_conns: 2 | |||||
| conn_max_lifetime: -1 | |||||
| # Configuration for the Room Server. | |||||
| room_server: | |||||
| internal_api: | |||||
| listen: http://0.0.0.0:7770 | |||||
| connect: http://room_server:7770 | |||||
| database: | |||||
| connection_string: {{ matrix_conduit_database_str }}/{{ matrix_conduit_room_database }}?sslmode=disable | |||||
| max_open_conns: 10 | |||||
| max_idle_conns: 2 | |||||
| conn_max_lifetime: -1 | |||||
| # Configuration for the Signing Key Server (for server signing keys). | |||||
| signing_key_server: | |||||
| internal_api: | |||||
| listen: http://0.0.0.0:7780 | |||||
| connect: http://signing_key_server:7780 | |||||
| database: | |||||
| connection_string: {{ matrix_conduit_database_str }}/{{ matrix_conduit_singingkeyserver_database }}?sslmode=disable | |||||
| max_open_conns: 10 | |||||
| max_idle_conns: 2 | |||||
| conn_max_lifetime: -1 | |||||
| # Perspective keyservers to use as a backup when direct key fetches fail. This may | |||||
| # be required to satisfy key requests for servers that are no longer online when | |||||
| # joining some rooms. | |||||
| key_perspectives: | |||||
| - server_name: matrix.org | |||||
| keys: | |||||
| - key_id: ed25519:auto | |||||
| public_key: Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw | |||||
| - key_id: ed25519:a_RXGa | |||||
| public_key: l8Hft5qXKn1vfHrg3p4+W8gELQVo8N13JkluMfmn2sQ | |||||
| # This option will control whether Dendrite will prefer to look up keys directly | |||||
| # or whether it should try perspective servers first, using direct fetches as a | |||||
| # last resort. | |||||
| prefer_direct_fetch: false | |||||
| # Configuration for the Sync API. | |||||
| sync_api: | |||||
| internal_api: | |||||
| listen: http://0.0.0.0:7773 | |||||
| connect: http://sync_api:7773 | |||||
| external_api: | |||||
| listen: http://0.0.0.0:8073 | |||||
| database: | |||||
| connection_string: {{ matrix_conduit_database_str }}/{{ matrix_conduit_syncapi_database }}?sslmode=disable | |||||
| max_open_conns: 10 | |||||
| max_idle_conns: 2 | |||||
| conn_max_lifetime: -1 | |||||
| # This option controls which HTTP header to inspect to find the real remote IP | |||||
| # address of the client. This is likely required if Dendrite is running behind | |||||
| # a reverse proxy server. | |||||
| # real_ip_header: X-Real-IP | |||||
| real_ip_header: {{ matrix_conduit_sync_api_real_ip_header|to_json }} | |||||
| # Configuration for the User API. | |||||
| user_api: | |||||
| # The cost when hashing passwords on registration/login. Default: 10. Min: 4, Max: 31 | |||||
| # See https://pkg.go.dev/golang.org/x/crypto/bcrypt for more information. | |||||
| # Setting this lower makes registration/login consume less CPU resources at the cost of security | |||||
| # should the database be compromised. Setting this higher makes registration/login consume more | |||||
| # CPU resources but makes it harder to brute force password hashes. | |||||
| # This value can be low if performing tests or on embedded Dendrite instances (e.g WASM builds) | |||||
| # bcrypt_cost: 10 | |||||
| internal_api: | |||||
| listen: http://0.0.0.0:7781 | |||||
| connect: http://user_api:7781 | |||||
| account_database: | |||||
| connection_string: {{ matrix_conduit_database_str }}/{{ matrix_conduit_account_database }}?sslmode=disable | |||||
| max_open_conns: 10 | |||||
| max_idle_conns: 2 | |||||
| conn_max_lifetime: -1 | |||||
| device_database: | |||||
| connection_string: {{ matrix_conduit_database_str }}/{{ matrix_conduit_device_database }}?sslmode=disable | |||||
| max_open_conns: 10 | |||||
| max_idle_conns: 2 | |||||
| conn_max_lifetime: -1 | |||||
| # The length of time that a token issued for a relying party from | |||||
| # /_matrix/client/r0/user/{userId}/openid/request_token endpoint | |||||
| # is considered to be valid in milliseconds. | |||||
| # The default lifetime is 3600000ms (60 minutes). | |||||
| # openid_token_lifetime_ms: 3600000 | |||||
| # Configuration for Opentracing. | |||||
| # See https://github.com/matrix-org/dendrite/tree/master/docs/tracing for information on | |||||
| # how this works and how to set it up. | |||||
| tracing: | |||||
| enabled: false | |||||
| jaeger: | |||||
| serviceName: "" | |||||
| disabled: false | |||||
| rpc_metrics: false | |||||
| tags: [] | |||||
| sampler: null | |||||
| reporter: null | |||||
| headers: null | |||||
| baggage_restrictions: null | |||||
| throttler: null | |||||
| # Logging configuration, in addition to the standard logging that is sent to | |||||
| # stdout by Dendrite. | |||||
| logging: [] | |||||
| @@ -0,0 +1,64 @@ | |||||
| #jinja2: lstrip_blocks: "True" | |||||
| [Unit] | |||||
| Description=Dendrite server | |||||
| {% for service in matrix_conduit_systemd_required_services_list %} | |||||
| Requires={{ service }} | |||||
| After={{ service }} | |||||
| {% endfor %} | |||||
| {% for service in matrix_conduit_systemd_wanted_services_list %} | |||||
| Wants={{ service }} | |||||
| {% endfor %} | |||||
| DefaultDependencies=no | |||||
| [Service] | |||||
| Type=simple | |||||
| Environment="HOME={{ matrix_systemd_unit_home_path }}" | |||||
| ExecStartPre=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} kill matrix-dendrite 2>/dev/null' | |||||
| ExecStartPre=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} rm matrix-dendrite 2>/dev/null' | |||||
| {% if 'matrix-postgres.service' in matrix_conduit_systemd_required_services_list %} | |||||
| # Dendrite is too quick to start in relation to its matrix-postgres dependency. | |||||
| # Delay Dendrite startup to avoid failing with: "failed to connect to accounts db" ("pq: the database system is starting up"). | |||||
| ExecStartPre={{ matrix_host_command_sleep }} 5 | |||||
| {% endif %} | |||||
| ExecStart={{ matrix_host_command_docker }} run --rm --name matrix-dendrite \ | |||||
| --log-driver=none \ | |||||
| --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ | |||||
| --cap-drop=ALL \ | |||||
| --read-only \ | |||||
| --tmpfs=/tmp:rw,noexec,nosuid,size={{ matrix_conduit_tmp_directory_size_mb }}m \ | |||||
| --network={{ matrix_docker_network }} \ | |||||
| {% if matrix_conduit_container_http_host_bind_address and matrix_conduit_http_bind_port %} | |||||
| -p {{ matrix_conduit_container_http_host_bind_address }}:{{ matrix_conduit_http_bind_port }} \ | |||||
| {% endif %} | |||||
| {% if matrix_conduit_container_https_host_bind_address and matrix_conduit_https_bind_port %} | |||||
| -p {{ matrix_conduit_container_https_host_bind_address }}:{{ matrix_conduit_https_bind_port }} \ | |||||
| {% endif %} | |||||
| --mount type=bind,src={{ matrix_conduit_config_dir_path }},dst=/data,ro \ | |||||
| --mount type=bind,src={{ matrix_conduit_storage_path }},dst=/matrix-media-store-parent,bind-propagation=slave \ | |||||
| {% for volume in matrix_conduit_container_additional_volumes %} | |||||
| -v {{ volume.src }}:{{ volume.dst }}:{{ volume.options }} \ | |||||
| {% endfor %} | |||||
| {% for arg in matrix_conduit_container_extra_arguments %} | |||||
| {{ arg }} \ | |||||
| {% endfor %} | |||||
| {{ matrix_conduit_docker_image }} \ | |||||
| -config /data/dendrite.yaml \ | |||||
| {% if matrix_conduit_http_bind_address %} | |||||
| -http-bind-address {{ matrix_conduit_http_bind_address }} | |||||
| {% endif %} | |||||
| {% if matrix_conduit_https_bind_address %} | |||||
| -https-bind-address {{ matrix_conduit_https_bind_address }} | |||||
| {% endif %} | |||||
| {{ matrix_conduit_process_extra_arguments|join(' ') }} | |||||
| ExecStop=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} kill matrix-dendrite 2>/dev/null' | |||||
| ExecStop=-{{ matrix_host_command_sh }} -c '{{ matrix_host_command_docker }} rm matrix-dendrite 2>/dev/null' | |||||
| ExecReload={{ matrix_host_command_docker }} exec matrix-dendrite /bin/sh -c 'kill -HUP 1' | |||||
| Restart=always | |||||
| RestartSec=30 | |||||
| SyslogIdentifier=matrix-dendrite | |||||
| [Install] | |||||
| WantedBy=multi-user.target | |||||
| @@ -0,0 +1,12 @@ | |||||
| #jinja2: lstrip_blocks: "True" | |||||
| #!/bin/bash | |||||
| if [ $# -ne 2 ]; then | |||||
| echo "Usage: "$0" <username> <password>" | |||||
| exit 1 | |||||
| fi | |||||
| user=$1 | |||||
| password=$2 | |||||
| docker exec matrix-dendrite create-account -config /data/dendrite.yaml -username "$user" -password "$password" | |||||
| @@ -0,0 +1,11 @@ | |||||
| --- | |||||
| matrix_conduit_client_api_url_endpoint_public: "https://{{ matrix_server_fqn_matrix }}/_matrix/client/versions" | |||||
| matrix_conduit_federation_api_url_endpoint_public: "https://{{ matrix_server_fqn_matrix }}:{{ matrix_federation_public_port }}/_matrix/federation/v1/version" | |||||
| # Tells whether this role had executed or not. Toggled to `true` during runtime. | |||||
| matrix_conduit_role_executed: false | |||||
| matrix_conduit_media_store_parent_path: "{{ matrix_conduit_media_store_path|dirname }}" | |||||
| matrix_conduit_media_store_directory_name: "{{ matrix_conduit_media_store_path|basename }}" | |||||
| matrix_conduit_signing_key_file_name: "{{ matrix_conduit_signing_key|basename }}" | |||||