From f2131974af5f3071fed5dedf06126a6cf0796dd5 Mon Sep 17 00:00:00 2001 From: Halima Date: Wed, 15 Nov 2023 09:35:08 +0100 Subject: [PATCH] Add your files and folders --- .config/ansible-lint.yml | 16 + .editorconfig | 27 + .github/FUNDING.yml | 7 + .github/ISSUE_TEMPLATE/bug_report.md | 57 + .github/ISSUE_TEMPLATE/feature_request.md | 28 + .github/ISSUE_TEMPLATE/i-need-help.md | 49 + .github/dependabot.yaml | 7 + .github/workflows/matrix.yml | 26 + .gitignore | 12 + .yamllint | 5 + CHANGELOG.md | 2544 +++++++++++++ LICENSE | 661 ++++ Makefile | 13 + README.md | 181 + ansible.cfg | 6 + collections/requirements.yml | 4 + docs/README.md | 39 + docs/alternative-architectures.md | 18 + docs/ansible.md | 121 + docs/configuring-captcha.md | 52 + docs/configuring-dns.md | 95 + docs/configuring-playbook-backup-borg.md | 81 + ...onfiguring-playbook-base-domain-serving.md | 52 + docs/configuring-playbook-bot-buscarron.md | 70 + docs/configuring-playbook-bot-go-neb.md | 213 ++ docs/configuring-playbook-bot-honoroit.md | 49 + docs/configuring-playbook-bot-maubot.md | 58 + docs/configuring-playbook-bot-mjolnir.md | 122 + docs/configuring-playbook-conduit.md | 58 + docs/configuring-playbook-dendrite.md | 32 + docs/configuring-playbook-dimension.md | 78 + docs/configuring-playbook-dynamic-dns.md | 27 + docs/configuring-playbook-email.md | 55 + docs/configuring-playbook-email2matrix.md | 76 + docs/configuring-playbook-federation.md | 69 + docs/configuring-playbook-ldap-auth.md | 39 + docs/configuring-playbook-nginx.md | 84 + docs/configuring-playbook-ntfy.md | 94 + docs/configuring-playbook-own-webserver.md | 252 ++ docs/configuring-playbook-postgres-backup.md | 36 + ...configuring-playbook-prometheus-grafana.md | 138 + ...onfiguring-playbook-prometheus-nginxlog.md | 59 + ...onfiguring-playbook-prometheus-postgres.md | 25 + docs/configuring-playbook-rest-auth.md | 24 + docs/configuring-playbook-riot-web.md | 39 + docs/configuring-playbook-s3-goofys.md | 137 + docs/configuring-playbook-s3.md | 107 + ...configuring-playbook-shared-secret-auth.md | 23 + docs/configuring-playbook-ssl-certificates.md | 112 + docs/configuring-playbook-turn.md | 42 + docs/configuring-playbook.md | 192 + docs/configuring-well-known.md | 201 + docs/container-images.md | 121 + docs/faq.md | 475 +++ docs/getting-the-playbook.md | 41 + docs/howto-server-delegation.md | 132 + docs/importing-postgres.md | 105 + docs/importing-synapse-media-store.md | 22 + docs/importing-synapse-sqlite.md | 26 + docs/installing.md | 109 + docs/maintenance-and-troubleshooting.md | 49 + docs/maintenance-checking-services.md | 13 + docs/maintenance-migrating.md | 14 + docs/maintenance-postgres.md | 161 + docs/maintenance-upgrading-services.md | 17 + docs/obtaining-access-tokens.md | 49 + docs/prerequisites.md | 43 + docs/registering-users.md | 81 + docs/self-building.md | 45 + docs/uninstalling.md | 36 + docs/updating-users-passwords.md | 45 + examples/all | 108 + examples/apache/README.md | 17 + examples/apache/matrix-client-element.conf | 41 + examples/apache/matrix-dimension.conf | 41 + examples/apache/matrix-synapse.conf | 134 + examples/caddy/matrix-client-element | 8 + examples/caddy/matrix-dimension | 9 + examples/caddy/matrix-synapse | 31 + examples/caddy/matrix-util | 7 + examples/caddy2/Caddyfile | 269 ++ examples/caddy2/README.md | 12 + examples/haproxy/Dockerfile | 12 + examples/haproxy/README.md | 26 + examples/haproxy/docker-compose.yml | 9 + examples/haproxy/haproxy.cfg | 97 + examples/haproxy/nginx.conf | 15 + examples/host.yml | 11 + examples/hosts | 35 + examples/vars_keycloak.yml | 37 + examples/vars_matrix.yml | 38 + group_vars/matrix_servers | 3180 ++++++++++++++++ inventory/.gitkeep | 0 inventory/scripts/ansible-all-hosts.sh | 32 + inventory/scripts/jitsi-generate-passwords.sh | 24 + playbooks/jitsi_jvb.yml | 12 + playbooks/matrix.yml | 144 + requirements.yml | 36 + roles/base/docker/tasks/main.yml | 34 + .../docker/templates/docker-daemon.json.j2 | 6 + roles/gitlab/gitlab_drbd_storage/README.md | 38 + .../gitlab_drbd_storage/defaults/main.yml | 2 + .../gitlab_drbd_storage/handlers/main.yml | 2 + .../gitlab/gitlab_drbd_storage/meta/main.yml | 52 + .../tasks/drbd_presetup.yml | 7 + .../gitlab_drbd_storage/tasks/drbd_setup.yml | 277 ++ .../gitlab/gitlab_drbd_storage/tasks/main.yml | 49 + .../templates/drbd.conf.j2 | 55 + .../gitlab_drbd_storage/templates/exports.j2 | 7 + .../gitlab_drbd_storage/tests/inventory | 2 + .../gitlab/gitlab_drbd_storage/tests/test.yml | 5 + .../gitlab/gitlab_drbd_storage/vars/main.yml | 2 + roles/gitlab/gitlab_main/README.md | 38 + roles/gitlab/gitlab_main/defaults/main.yml | 2 + roles/gitlab/gitlab_main/handlers/main.yml | 2 + roles/gitlab/gitlab_main/meta/main.yml | 52 + .../gitlab_main/tasks/gitlab_presetup.yml | 10 + .../gitlab/gitlab_main/tasks/gitlab_setup.yml | 211 ++ .../gitlab_main/tasks/gitlab_update.yml | 55 + roles/gitlab/gitlab_main/tasks/main.yml | 25 + .../gitlab_main/tasks/pacemaker_setup.yml | 120 + .../gitlab/gitlab_main/templates/gitlab.rb.j2 | 3350 +++++++++++++++++ .../templates/nginx_custom.conf.j2 | 7 + roles/gitlab/gitlab_main/tests/inventory | 2 + roles/gitlab/gitlab_main/tests/test.yml | 5 + roles/gitlab/gitlab_main/vars/main.yml | 2 + .../keycloak/keycloak_base/defaults/main.yml | 21 + roles/keycloak/keycloak_base/tasks/main.yml | 7 + .../keycloak_base/tasks/setup_all.yml | 114 + .../keycloak_base/templates/Dockerfile.j2 | 23 + roles/keycloak/keycloak_custom/tasks/main.yml | 35 + roles/nginx-proxy/defaults/main.yml | 663 ++++ roles/nginx-proxy/tasks/main.yml | 41 + .../tasks/nginx-proxy/setup_metrics_auth.yml | 60 + .../tasks/self_check_well_known.yml | 30 + .../tasks/self_check_well_known_file.yml | 73 + roles/nginx-proxy/tasks/setup_nginx_proxy.yml | 372 ++ roles/nginx-proxy/tasks/setup_well_known.yml | 25 + roles/nginx-proxy/tasks/ssl/main.yml | 37 + ...urge_ssl_lets_encrypt_orphaned_configs.yml | 27 + .../tasks/ssl/setup_ssl_lets_encrypt.yml | 54 + ...tup_ssl_lets_encrypt_obtain_for_domain.yml | 96 + .../tasks/ssl/setup_ssl_manually_managed.yml | 11 + ...ssl_manually_managed_verify_for_domain.yml | 23 + .../tasks/ssl/setup_ssl_self_signed.yml | 13 + ...etup_ssl_self_signed_obtain_for_domain.yml | 49 + roles/nginx-proxy/tasks/validate_config.yml | 74 + .../bin/lets-encrypt-certificates-renew.j2 | 32 + .../conf.d/a-nginx-https-wildcard.conf.j2 | 79 + .../nginx/conf.d/gitlab-http.conf.j2 | 125 + .../nginx/conf.d/keycloak-http.conf.j2 | 125 + .../nginx/conf.d/matrix-base-domain.conf.j2 | 96 + .../nginx/conf.d/matrix-bot-buscarron.conf.j2 | 104 + .../nginx/conf.d/matrix-bot-go-neb.conf.j2 | 97 + .../nginx/conf.d/matrix-client-cinny.conf.j2 | 104 + .../conf.d/matrix-client-element.conf.j2 | 116 + .../conf.d/matrix-client-hydrogen.conf.j2 | 104 + .../nginx/conf.d/matrix-conduit.conf.j2 | 77 + .../nginx/conf.d/matrix-dendrite.conf.j2 | 77 + .../nginx/conf.d/matrix-dimension.conf.j2 | 100 + .../nginx/conf.d/matrix-domain.conf.j2 | 323 ++ .../nginx/conf.d/matrix-etherpad.conf.j2 | 108 + .../nginx/conf.d/matrix-grafana.conf.j2 | 108 + .../nginx/conf.d/matrix-jitsi.conf.j2 | 158 + .../nginx/conf.d/matrix-ntfy.conf.j2 | 102 + .../nginx/conf.d/matrix-riot-web.conf.j2 | 89 + .../nginx/conf.d/matrix-sygnal.conf.j2 | 99 + .../nginx/conf.d/matrix-synapse.conf.j2 | 71 + .../templates/nginx/conf.d/nginx-http.conf.j2 | 14 + .../nginx-proxy/templates/nginx/nginx.conf.j2 | 77 + .../systemd/matrix-nginx-proxy.service.j2 | 62 + ...lets-encrypt-certificates-renew.service.j2 | 7 + ...l-lets-encrypt-certificates-renew.timer.j2 | 10 + .../matrix-ssl-nginx-proxy-reload.service.j2 | 6 + .../matrix-ssl-nginx-proxy-reload.timer.j2 | 10 + roles/nginx-proxy/vars/main.yml | 26 + setup.yml | 193 + 177 files changed, 21547 insertions(+) create mode 100644 .config/ansible-lint.yml create mode 100644 .editorconfig create mode 100644 .github/FUNDING.yml create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/i-need-help.md create mode 100644 .github/dependabot.yaml create mode 100644 .github/workflows/matrix.yml create mode 100644 .gitignore create mode 100644 .yamllint create mode 100644 CHANGELOG.md create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100644 ansible.cfg create mode 100644 collections/requirements.yml create mode 100644 docs/README.md create mode 100644 docs/alternative-architectures.md create mode 100644 docs/ansible.md create mode 100644 docs/configuring-captcha.md create mode 100644 docs/configuring-dns.md create mode 100644 docs/configuring-playbook-backup-borg.md create mode 100644 docs/configuring-playbook-base-domain-serving.md create mode 100644 docs/configuring-playbook-bot-buscarron.md create mode 100644 docs/configuring-playbook-bot-go-neb.md create mode 100644 docs/configuring-playbook-bot-honoroit.md create mode 100644 docs/configuring-playbook-bot-maubot.md create mode 100644 docs/configuring-playbook-bot-mjolnir.md create mode 100644 docs/configuring-playbook-conduit.md create mode 100644 docs/configuring-playbook-dendrite.md create mode 100644 docs/configuring-playbook-dimension.md create mode 100644 docs/configuring-playbook-dynamic-dns.md create mode 100644 docs/configuring-playbook-email.md create mode 100644 docs/configuring-playbook-email2matrix.md create mode 100644 docs/configuring-playbook-federation.md create mode 100644 docs/configuring-playbook-ldap-auth.md create mode 100644 docs/configuring-playbook-nginx.md create mode 100644 docs/configuring-playbook-ntfy.md create mode 100644 docs/configuring-playbook-own-webserver.md create mode 100644 docs/configuring-playbook-postgres-backup.md create mode 100644 docs/configuring-playbook-prometheus-grafana.md create mode 100644 docs/configuring-playbook-prometheus-nginxlog.md create mode 100644 docs/configuring-playbook-prometheus-postgres.md create mode 100644 docs/configuring-playbook-rest-auth.md create mode 100644 docs/configuring-playbook-riot-web.md create mode 100644 docs/configuring-playbook-s3-goofys.md create mode 100644 docs/configuring-playbook-s3.md create mode 100644 docs/configuring-playbook-shared-secret-auth.md create mode 100644 docs/configuring-playbook-ssl-certificates.md create mode 100644 docs/configuring-playbook-turn.md create mode 100644 docs/configuring-playbook.md create mode 100644 docs/configuring-well-known.md create mode 100644 docs/container-images.md create mode 100644 docs/faq.md create mode 100644 docs/getting-the-playbook.md create mode 100644 docs/howto-server-delegation.md create mode 100644 docs/importing-postgres.md create mode 100644 docs/importing-synapse-media-store.md create mode 100644 docs/importing-synapse-sqlite.md create mode 100644 docs/installing.md create mode 100644 docs/maintenance-and-troubleshooting.md create mode 100644 docs/maintenance-checking-services.md create mode 100644 docs/maintenance-migrating.md create mode 100644 docs/maintenance-postgres.md create mode 100644 docs/maintenance-upgrading-services.md create mode 100644 docs/obtaining-access-tokens.md create mode 100644 docs/prerequisites.md create mode 100644 docs/registering-users.md create mode 100644 docs/self-building.md create mode 100644 docs/uninstalling.md create mode 100644 docs/updating-users-passwords.md create mode 100644 examples/all create mode 100644 examples/apache/README.md create mode 100644 examples/apache/matrix-client-element.conf create mode 100644 examples/apache/matrix-dimension.conf create mode 100644 examples/apache/matrix-synapse.conf create mode 100644 examples/caddy/matrix-client-element create mode 100644 examples/caddy/matrix-dimension create mode 100644 examples/caddy/matrix-synapse create mode 100644 examples/caddy/matrix-util create mode 100644 examples/caddy2/Caddyfile create mode 100644 examples/caddy2/README.md create mode 100644 examples/haproxy/Dockerfile create mode 100644 examples/haproxy/README.md create mode 100644 examples/haproxy/docker-compose.yml create mode 100644 examples/haproxy/haproxy.cfg create mode 100644 examples/haproxy/nginx.conf create mode 100644 examples/host.yml create mode 100644 examples/hosts create mode 100644 examples/vars_keycloak.yml create mode 100644 examples/vars_matrix.yml create mode 100644 group_vars/matrix_servers create mode 100644 inventory/.gitkeep create mode 100644 inventory/scripts/ansible-all-hosts.sh create mode 100644 inventory/scripts/jitsi-generate-passwords.sh create mode 100644 playbooks/jitsi_jvb.yml create mode 100644 playbooks/matrix.yml create mode 100644 requirements.yml create mode 100644 roles/base/docker/tasks/main.yml create mode 100644 roles/base/docker/templates/docker-daemon.json.j2 create mode 100644 roles/gitlab/gitlab_drbd_storage/README.md create mode 100644 roles/gitlab/gitlab_drbd_storage/defaults/main.yml create mode 100644 roles/gitlab/gitlab_drbd_storage/handlers/main.yml create mode 100644 roles/gitlab/gitlab_drbd_storage/meta/main.yml create mode 100644 roles/gitlab/gitlab_drbd_storage/tasks/drbd_presetup.yml create mode 100644 roles/gitlab/gitlab_drbd_storage/tasks/drbd_setup.yml create mode 100644 roles/gitlab/gitlab_drbd_storage/tasks/main.yml create mode 100644 roles/gitlab/gitlab_drbd_storage/templates/drbd.conf.j2 create mode 100644 roles/gitlab/gitlab_drbd_storage/templates/exports.j2 create mode 100644 roles/gitlab/gitlab_drbd_storage/tests/inventory create mode 100644 roles/gitlab/gitlab_drbd_storage/tests/test.yml create mode 100644 roles/gitlab/gitlab_drbd_storage/vars/main.yml create mode 100644 roles/gitlab/gitlab_main/README.md create mode 100644 roles/gitlab/gitlab_main/defaults/main.yml create mode 100644 roles/gitlab/gitlab_main/handlers/main.yml create mode 100644 roles/gitlab/gitlab_main/meta/main.yml create mode 100644 roles/gitlab/gitlab_main/tasks/gitlab_presetup.yml create mode 100644 roles/gitlab/gitlab_main/tasks/gitlab_setup.yml create mode 100644 roles/gitlab/gitlab_main/tasks/gitlab_update.yml create mode 100644 roles/gitlab/gitlab_main/tasks/main.yml create mode 100644 roles/gitlab/gitlab_main/tasks/pacemaker_setup.yml create mode 100644 roles/gitlab/gitlab_main/templates/gitlab.rb.j2 create mode 100644 roles/gitlab/gitlab_main/templates/nginx_custom.conf.j2 create mode 100644 roles/gitlab/gitlab_main/tests/inventory create mode 100644 roles/gitlab/gitlab_main/tests/test.yml create mode 100644 roles/gitlab/gitlab_main/vars/main.yml create mode 100644 roles/keycloak/keycloak_base/defaults/main.yml create mode 100644 roles/keycloak/keycloak_base/tasks/main.yml create mode 100644 roles/keycloak/keycloak_base/tasks/setup_all.yml create mode 100644 roles/keycloak/keycloak_base/templates/Dockerfile.j2 create mode 100644 roles/keycloak/keycloak_custom/tasks/main.yml create mode 100644 roles/nginx-proxy/defaults/main.yml create mode 100644 roles/nginx-proxy/tasks/main.yml create mode 100644 roles/nginx-proxy/tasks/nginx-proxy/setup_metrics_auth.yml create mode 100644 roles/nginx-proxy/tasks/self_check_well_known.yml create mode 100644 roles/nginx-proxy/tasks/self_check_well_known_file.yml create mode 100644 roles/nginx-proxy/tasks/setup_nginx_proxy.yml create mode 100644 roles/nginx-proxy/tasks/setup_well_known.yml create mode 100644 roles/nginx-proxy/tasks/ssl/main.yml create mode 100644 roles/nginx-proxy/tasks/ssl/purge_ssl_lets_encrypt_orphaned_configs.yml create mode 100644 roles/nginx-proxy/tasks/ssl/setup_ssl_lets_encrypt.yml create mode 100644 roles/nginx-proxy/tasks/ssl/setup_ssl_lets_encrypt_obtain_for_domain.yml create mode 100644 roles/nginx-proxy/tasks/ssl/setup_ssl_manually_managed.yml create mode 100644 roles/nginx-proxy/tasks/ssl/setup_ssl_manually_managed_verify_for_domain.yml create mode 100644 roles/nginx-proxy/tasks/ssl/setup_ssl_self_signed.yml create mode 100644 roles/nginx-proxy/tasks/ssl/setup_ssl_self_signed_obtain_for_domain.yml create mode 100644 roles/nginx-proxy/tasks/validate_config.yml create mode 100644 roles/nginx-proxy/templates/bin/lets-encrypt-certificates-renew.j2 create mode 100644 roles/nginx-proxy/templates/nginx/conf.d/a-nginx-https-wildcard.conf.j2 create mode 100644 roles/nginx-proxy/templates/nginx/conf.d/gitlab-http.conf.j2 create mode 100644 roles/nginx-proxy/templates/nginx/conf.d/keycloak-http.conf.j2 create mode 100644 roles/nginx-proxy/templates/nginx/conf.d/matrix-base-domain.conf.j2 create mode 100644 roles/nginx-proxy/templates/nginx/conf.d/matrix-bot-buscarron.conf.j2 create mode 100644 roles/nginx-proxy/templates/nginx/conf.d/matrix-bot-go-neb.conf.j2 create mode 100644 roles/nginx-proxy/templates/nginx/conf.d/matrix-client-cinny.conf.j2 create mode 100644 roles/nginx-proxy/templates/nginx/conf.d/matrix-client-element.conf.j2 create mode 100644 roles/nginx-proxy/templates/nginx/conf.d/matrix-client-hydrogen.conf.j2 create mode 100644 roles/nginx-proxy/templates/nginx/conf.d/matrix-conduit.conf.j2 create mode 100644 roles/nginx-proxy/templates/nginx/conf.d/matrix-dendrite.conf.j2 create mode 100644 roles/nginx-proxy/templates/nginx/conf.d/matrix-dimension.conf.j2 create mode 100644 roles/nginx-proxy/templates/nginx/conf.d/matrix-domain.conf.j2 create mode 100644 roles/nginx-proxy/templates/nginx/conf.d/matrix-etherpad.conf.j2 create mode 100644 roles/nginx-proxy/templates/nginx/conf.d/matrix-grafana.conf.j2 create mode 100644 roles/nginx-proxy/templates/nginx/conf.d/matrix-jitsi.conf.j2 create mode 100644 roles/nginx-proxy/templates/nginx/conf.d/matrix-ntfy.conf.j2 create mode 100644 roles/nginx-proxy/templates/nginx/conf.d/matrix-riot-web.conf.j2 create mode 100644 roles/nginx-proxy/templates/nginx/conf.d/matrix-sygnal.conf.j2 create mode 100644 roles/nginx-proxy/templates/nginx/conf.d/matrix-synapse.conf.j2 create mode 100644 roles/nginx-proxy/templates/nginx/conf.d/nginx-http.conf.j2 create mode 100644 roles/nginx-proxy/templates/nginx/nginx.conf.j2 create mode 100644 roles/nginx-proxy/templates/systemd/matrix-nginx-proxy.service.j2 create mode 100644 roles/nginx-proxy/templates/systemd/matrix-ssl-lets-encrypt-certificates-renew.service.j2 create mode 100644 roles/nginx-proxy/templates/systemd/matrix-ssl-lets-encrypt-certificates-renew.timer.j2 create mode 100644 roles/nginx-proxy/templates/systemd/matrix-ssl-nginx-proxy-reload.service.j2 create mode 100644 roles/nginx-proxy/templates/systemd/matrix-ssl-nginx-proxy-reload.timer.j2 create mode 100644 roles/nginx-proxy/vars/main.yml create mode 100644 setup.yml diff --git a/.config/ansible-lint.yml b/.config/ansible-lint.yml new file mode 100644 index 0000000..00d62f2 --- /dev/null +++ b/.config/ansible-lint.yml @@ -0,0 +1,16 @@ +--- + +use_default_rules: true + +skip_list: + - unnamed-task + - no-handler + - no-jinja-nesting + - schema + - command-instead-of-shell + - role-name + # We frequently load configuration from a template (into a variable), then merge that with another variable (configuration extension) + # before finally dumping it to a file. + - template-instead-of-copy + +offline: true diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..6d5dc09 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,27 @@ +# This file is the top-most EditorConfig file +root = true + +# All Files +[*] +charset = utf-8 +end_of_line = lf +indent_style = tab +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true + +######################### +# File Extension Settings +######################### + +# YAML Files +[*.{yml,yaml,log.config.j2,yaml.j2}] +indent_style = space +indent_size = 2 + +# Markdown Files +# +# Two spaces at the end of a line in Markdown mean "new line", +# so trimming trailing whitespace for such files can cause breakage. +[*.md] +trim_trailing_whitespace = false diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..463b7cd --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,7 @@ +--- +# These are supported funding model platforms + +# https://liberapay.com/s.pantaleev/ +liberapay: s.pantaleev +# https://ko-fi.com/spantaleev +ko_fi: spantaleev diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..9dffaee --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,57 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + + + +**To Reproduce** +My `vars.yml` file looks like this: + +```yaml +Paste your vars.yml file here. +Make sure to remove any secret values before posting your vars.yml file publicly. +``` + + + + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Matrix Server:** + - OS: [e.g. Ubuntu 21.04] + - Architecture [e.g. amd64, arm32, arm64] + +**Ansible:** +If your problem appears to be with Ansible, tell us: +- where you run Ansible -- e.g. on the Matrix server itself; on another computer (which OS? distro? standard installation or containerized Ansible?) +- what version of Ansible you're running (see `ansible --version`) + + + +**Client:** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + + + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..3fb2ffe --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,28 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + + + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/i-need-help.md b/.github/ISSUE_TEMPLATE/i-need-help.md new file mode 100644 index 0000000..6e86246 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/i-need-help.md @@ -0,0 +1,49 @@ +--- +name: I need help +about: Get support from our community +title: '' +labels: '' +assignees: '' + +--- + + + +**Playbook Configuration**: + +My `vars.yml` file looks like this: + +```yaml +Paste your vars.yml file here. +Make sure to remove any secret values before posting your vars.yml file publicly. +``` + +**Matrix Server:** + - OS: [e.g. Ubuntu 21.04] + - Architecture [e.g. amd64, arm32, arm64] + +**Ansible:** +If your problem appears to be with Ansible, tell us: +- where you run Ansible -- e.g. on the Matrix server itself; on another computer (which OS? distro? standard installation or containerized Ansible?) +- what version of Ansible you're running (see `ansible --version`) + +**Problem description**: + +Describe what you're doing, what you expect to happen and what happens instead here. +Tell us what you've tried and what you're aiming to achieve. + +**Client (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + + + +**Additional context** +Add any other context about the problem here. diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 0000000..b9c3cd4 --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,7 @@ +--- +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: daily diff --git a/.github/workflows/matrix.yml b/.github/workflows/matrix.yml new file mode 100644 index 0000000..6c7ce3c --- /dev/null +++ b/.github/workflows/matrix.yml @@ -0,0 +1,26 @@ +--- +name: Matrix CI + +on: # yamllint disable-line rule:truthy + push: + pull_request: + +jobs: + yamllint: + name: yamllint + runs-on: ubuntu-latest + steps: + - name: Check out + uses: actions/checkout@v3 + - name: Run yamllint + uses: frenck/action-yamllint@v1.3.1 + ansible-lint: + name: ansible-lint + runs-on: ubuntu-latest + steps: + - name: Check out + uses: actions/checkout@v3 + - name: Run ansible-lint + uses: ansible-community/ansible-lint-action@v6.8.2 + with: + path: roles/custom diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a0b1073 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +/inventory/* +!/inventory/.gitkeep +!/inventory/host_vars/.gitkeep +!/inventory/scripts +/roles/**/files/scratchpad +.DS_Store +.python-version +/group_vars/all +# ignore roles pulled by ansible-galaxy +/roles/galaxy/* +!/roles/galaxy/.gitkeep +.vscode/settings.json diff --git a/.yamllint b/.yamllint new file mode 100644 index 0000000..75da2b7 --- /dev/null +++ b/.yamllint @@ -0,0 +1,5 @@ +--- +extends: default + +rules: + line-length: disable diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..09e3a91 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,2544 @@ +# 2022-11-30 + +## matrix-postgres-backup has been replaced by the com.devture.ansible.role.postgres_backup external role + +Just like we've [replaced Postgres with an external role](#matrix-postgres-has-been-replaced-by-the-comdevtureansiblerolepostgres-external-role) on 2022-11-28, we're now replacing `matrix-postgres-backup` with an external role - [com.devture.ansible.role.postgres_backup](https://github.com/devture/com.devture.ansible.role.postgres_backup). + +You'll need to rename your `matrix_postgres_backup`-prefixed variables such that they use a `devture_postgres_backup` prefix. + + +# 2022-11-28 + +## matrix-postgres has been replaced by the com.devture.ansible.role.postgres external role + +**TLDR**: the tasks that install the integrated Postgres server now live in an external role - [com.devture.ansible.role.postgres](https://github.com/devture/com.devture.ansible.role.postgres). You'll need to run `make roles` to install it, and to also rename your `matrix_postgres`-prefixed variables to use a `devture_postgres` prefix (e.g. `matrix_postgres_connection_password` -> `devture_postgres_connection_password`). All your data will still be there! Some scripts have moved (`/usr/local/bin/matrix-postgres-cli` -> `/matrix/postgres/bin/cli`). + +The `matrix-postgres` role that has been part of the playbook for a long time has been replaced with the [com.devture.ansible.role.postgres](https://github.com/devture/com.devture.ansible.role.postgres) role. This was done as part of our work to [use external roles for some things](#the-playbook-now-uses-external-roles-for-some-things) for better code re-use and maintainability. + +The new role is an upgraded version of the old `matrix-postgres` role with these notable differences: + +- it uses different names for its variables (`matrix_postgres` -> `devture_postgres`) +- when [Vacuuming PostgreSQL](docs/maintenance-postgres.md#vacuuming-postgresql), it will vacuum all your databases, not just the Synapse one + +You'll need to run `make roles` to install the new role. You would also need to rename your `matrix_postgres`-prefixed variables to use a `devture_postgres` prefix. + +Note: the systemd service still remains the same - `matrix-postgres.service`. Your data will still be in `/matrix/postgres`, etc. +Postgres-related scripts will be moved to `/matrix/postgres/bin` (`/usr/local/bin/matrix-postgres-cli` -> `/matrix/postgres/bin/cli`, etc). Also see [The playbook no longer installs scripts in /usr/local/bin](#the-playbook-no-longer-installs-scripts-in-usrlocalbin). + +## The playbook no longer installs scripts to /usr/local/bin + +The locations of various scripts installed by the playbook have changed. + +The playbook no longer contaminates your `/usr/local/bin` directory. +All scripts installed by the playbook now live in `bin/` directories under `/matrix`. Some examples are below: + +- `/usr/local/bin/matrix-remove-all` -> `/matrix/bin/remove-all` +- `/usr/local/bin/matrix-postgres-cli` -> `/matrix/postgres/bin/cli` +- `/usr/local/bin/matrix-ssl-lets-encrypt-certificates-renew` -> `/matrix/ssl/bin/lets-encrypt-certificates-renew` +- `/usr/local/bin/matrix-synapse-register-user` -> `/matrix/synapse/bin/register-user` + + +# 2022-11-25 + +## 2x-5x performance improvements in playbook runtime + +**TLDR**: the playbook is 2x faster for running `--tags=setup-all` (and various other tags). It also has new `--tags=install-*` tags (like `--tags=install-all`), which skip uninstallation tasks and bring an additional 2.5x speedup. In total, the playbook can maintain your server 5 times faster. + +Our [etke.cc managed Matrix hosting service](https://etke.cc) runs maintenance against hundreds of servers, so the playbook being fast means a lot. +The [etke.cc Ansible playbook](https://gitlab.com/etke.cc/ansible) (which is an extension of this one) is growing to support more and more services (besides just Matrix), so the Matrix playbook being leaner prevents runtimes from becoming too slow and improves the customer experience. + +Even when running `ansible-playbook` manually (as most of us here do), it's beneficial not to waste time and CPU resources. + +Recently, a few large optimizations have been done to this playbook and its external roles (see [The playbook now uses external roles for some things](#the-playbook-now-uses-external-roles-for-some-things) and don't forget to run `make roles`): + +1. Replacing Ansible `import_tasks` calls with `include_tasks`, which decreased runtime in half. Using `import_tasks` is slower and causes Ansible to go through and skip way too many tasks (tasks which could have been skipped altogether by not having Ansible include them in the first place). On an experimental VM, **deployment time was decreased from ~530 seconds to ~250 seconds**. + +2. Introducing new `install-*` tags (`install-all` and `install-COMPONENT`, e.g. `install-synapse`, `install-bot-postmoogle`), which only run Ansible tasks pertaining to installation, while skipping uninstallation tasks. In most cases, people are maintaining the same setup or they're *adding* new components. Removing components is rare. Running thousands of uninstallation tasks each time is wasteful. On an experimental VM, **deployment time was decreased from ~250 seconds (`--tags=setup-all`) to ~100 seconds (`--tags=install-all`)**. + +You can still use `--tags=setup-all`. In fact, that's the best way to ensure your server is reconciled with the `vars.yml` configuration. + +If you know you haven't uninstalled any services since the last time you ran the playbook, you could run `--tags=install-all` instead and benefit from quicker runtimes. +It should be noted that a service may become "eligible for uninstallation" even if your `vars.yml` file remains the same. In rare cases, we toggle services from being auto-installed to being optional, like we did on the 17th of March 2022 when we made [ma1sd not get installed by default](https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/CHANGELOG.md#compatibility-break-ma1sd-identity-server-no-longer-installed-by-default). In such rare cases, you'd also need to run `--tags=setup-all`. + + +# 2022-11-22 + +# Automatic `matrix_architecture` determination + +From now on, the playbook automatically determines your server's architecture and sets the `matrix_architecture` variable accordingly. +You no longer need to set this variable manually in your `vars.yml` file. + +# Docker and the Docker SDK for Python are now installed via external roles + +We're continuing our effort to make [the playbook use external roles for some things](#the-playbook-now-uses-external-roles-for-some-things), so as to avoid doing everything ourselves and to facilitate code re-use. + +Docker will now be installed on the server via the [geerlingguy.docker](https://github.com/geerlingguy/ansible-role-docker) Ansible role. +If you'd like to manage the Docker installation yourself, you can disable the playbook's installation of Docker by setting `matrix_playbook_docker_installation_enabled: false`. + +The Docker SDK for Python (named `docker-python`, `python-docker`, etc. on the different platforms) is now also installed by another role ([com.devture.ansible.role.docker_sdk_for_python](https://github.com/devture/com.devture.ansible.role.docker_sdk_for_python)). To disable this role and install the necessary tools yourself, use `devture_docker_sdk_for_python_installation_enabled: false`. + +If you're hitting issues with Docker installation or Docker SDK for Python installation, consider reporting bugs or contributing to these other projects. + +These additional roles are downloaded into the playbook directory (to `roles/galaxy`) via an `ansible-galaxy ..` command. `make roles` is an easy shortcut for invoking the `ansible-galaxy` command to download these roles. + + +# 2022-11-20 + +## (Backward Compatibility Break) Changing how reverse-proxying to Synapse works - now via a `matrix-synapse-reverse-proxy-companion` service + +**TLDR**: There's now a `matrix-synapse-reverse-proxy-companion` nginx service, which helps with reverse-proxying to Synapse and its various worker processes (if workers are enabled), so that `matrix-nginx-proxy` can be relieved of this role. `matrix-nginx-proxy` still remains as the public SSL-terminating reverse-proxy in the playbook. `matrix-synapse-reverse-proxy-companion` is just one more reverse-proxy thrown into the mix for convenience. People with a more custom reverse-proxying configuration may be affected - see [Webserver configuration](#webserver-configuration) below. + +### Background + +Previously, `matrix-nginx-proxy` forwarded requests to Synapse directly. When Synapse is running in worker mode, the reverse-proxying configuration is more complicated (different requests need to go to different Synapse worker processes). `matrix-nginx-proxy` had configuration for sending each URL endpoint to the correct Synapse worker responsible for handling it. However, sometimes people like to disable `matrix-nginx-proxy` (for whatever reason) as detailed in [Using your own webserver, instead of this playbook's nginx proxy](docs/configuring-playbook-own-webserver.md). + +Because `matrix-nginx-proxy` was so central to request forwarding, when it was disabled and Synapse was running with workers enabled, there was nothing which could forward requests to the correct place anymore.. which caused [problems such as this one affecting Dimension](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/2090). + +### Solution + +From now on, `matrix-nginx-proxy` is relieved of its function of reverse-proxying to Synapse and its various worker processes. +This role is now handled by the new `matrix-synapse-reverse-proxy-companion` nginx service and works even if `matrix-nginx-proxy` is disabled. +The purpose of the new `matrix-synapse-reverse-proxy-companion` service is to: + +- serve as a companion to Synapse and know how to reverse-proxy to Synapse correctly (no matter if workers are enabled or not) + +- provide a unified container address for reaching Synapse (no matter if workers are enabled or not) + - `matrix-synapse-reverse-proxy-companion:8008` for Synapse Client-Server API traffic + - `matrix-synapse-reverse-proxy-companion:8048` for Synapse Server-Server (Federation) API traffic + +- simplify `matrix-nginx-proxy` configuration - it now only needs to send requests to `matrix-synapse-reverse-proxy-companion` or `matrix-dendrite`, etc., without having to worry about workers + +- allow reverse-proxying to Synapse, even if `matrix-nginx-proxy` is disabled + +`matrix-nginx-proxy` still remains as the public SSL-terminating reverse-proxy in the playbook. All traffic goes through it before reaching any of the services. +It's just that now the Synapse traffic is routed through `matrix-synapse-reverse-proxy-companion` like this: + +(`matrix-nginx-proxy` -> `matrix-synapse-reverse-proxy-companion` -> (`matrix-synapse` or some Synapse worker)). + +Various services (like Dimension, etc.) still talk to Synapse via `matrix-nginx-proxy` (e.g. `http://matrix-nginx-proxy:12080`) preferentially. They only talk to Synapse via the reverse-proxy companion (e.g. `http://matrix-synapse-reverse-proxy-companion:8008`) if `matrix-nginx-proxy` is disabled. Services should not be talking to Synapse (e.g. `https://matrix-synapse:8008` directly anymore), because when workers are enabled, that's the Synapse `master` process and may not be serving all URL endpoints needed by the service. + +### Webserver configuration + +- if you're using `matrix-nginx-proxy` (`matrix_nginx_proxy_enabled: true`, which is the default for the playbook), you don't need to do anything + +- if you're using your own `nginx` webserver running on the server, you shouldn't be affected. The `/matrix/nginx/conf.d` configuration and exposed ports that you're relying on will automatically be updated in a way that should work + +- if you're using another local webserver (e.g. Apache, etc.) and haven't changed any ports (`matrix_*_host_bind_port` definitions), you shouldn't be affected. You're likely sending Matrix traffic to `127.0.0.1:8008` and `127.0.0.1:8048`. These ports (`8008` and `8048`) will still be exposed on `127.0.0.1` by default - just not by the `matrix-synapse` container from now on, but by the `matrix-synapse-reverse-proxy-companion` container instead + +- if you've been exposing `matrix-synapse` ports (`matrix_synapse_container_client_api_host_bind_port`, etc.) manually, you should consider exposing `matrix-synapse-reverse-proxy-companion` ports instead + +- if you're running Traefik and reverse-proxying directly to the `matrix-synapse` container, you should start reverse-proxying to the `matrix-synapse-reverse-proxy-companion` container instead. See [our updated Traefik example configuration](docs/configuring-playbook-own-webserver.md#sample-configuration-for-running-behind-traefik-20). Note: we now recommend calling the federation entry point `federation` (instead of `synapse`) and reverse-proxying the federation traffic via `matrix-nginx-proxy`, instead of sending it directly to Synapse (or `matrix-synapse-reverse-proxy-companion`). This makes the configuration simpler. + + +# 2022-11-05 + +## (Backward Compatibility Break) A new default standalone mode for Etherpad + +Until now, [Etherpad](https://etherpad.org/) (which [the playbook could install for you](docs/configuring-playbook-etherpad.md)) required the [Dimension integration manager](docs/configuring-playbook-dimension.md) to also be installed, because Etherpad was hosted on the Dimension domain (at `dimension.DOMAIN/etherpad`). + +From now on, Etherpad can be installed in `standalone` mode on `etherpad.DOMAIN` and used even without Dimension. This is much more versatile, so the playbook now defaults to this new mode (`matrix_etherpad_mode: standalone`). + +If you've already got both Etherpad and Dimension in use you could: + +- **either** keep hosting Etherpad under the Dimension domain by adding `matrix_etherpad_mode: dimension` to your `vars.yml` file. All your existing room widgets will continue working at the same URLs and no other changes will be necessary. + +- **or**, you could change to hosting Etherpad separately on `etherpad.DOMAIN`. You will need to [configure a DNS record](docs/configuring-dns.md) for this new domain. You will also need to reconfigure Dimension to use the new pad URLs (`https://etherpad.DOMAIN/...`) going forward (refer to our [configuring Etherpad documentation](docs/configuring-playbook-etherpad.md)). All your existing room widgets (which still use `https://dimension.DOMAIN/etherpad/...`) will break as Etherpad is not hosted there anymore. You will need to re-add them or to consider not using `standalone` mode + + +# 2022-11-04 + +## The playbook now uses external roles for some things + +**TLDR**: when updating the playbook and before running it, you'll need to run `make roles` to make [ansible-galaxy](https://docs.ansible.com/ansible/latest/cli/ansible-galaxy.html) download dependency roles (see the [`requirements.yml` file](requirements.yml)) to the `roles/galaxy` directory. Without this, the playbook won't work. + +We're in the process of trimming the playbook and making it reuse Ansible roles. + +Starting now, the playbook is composed of 2 types of Ansible roles: + +- those that live within the playbook itself (`roles/matrix/*`) + +- those downloaded from other sources (using [ansible-galaxy](https://docs.ansible.com/ansible/latest/cli/ansible-galaxy.html) to `roles/galaxy`, based on the [`requirements.yml` file](requirements.yml)). These roles are maintained by us or by other people from the Ansible community. + +We're doing this for greater code-reuse (across Ansible playbooks, including our own related playbooks [gitea-docker-ansible-deploy](https://github.com/spantaleev/gitea-docker-ansible-deploy) and [nextcloud-docker-ansible-deploy](https://github.com/spantaleev/nextcloud-docker-ansible-deploy)) and decreased maintenance burden. Until now, certain features were copy-pasted across playbooks or were maintained separately in each one, with improvements often falling behind. We've also tended to do too much by ourselves - installing Docker on the server from our `matrix-base` role, etc. - something that we'd rather not do anymore by switching to the [geerlingguy.docker](https://galaxy.ansible.com/geerlingguy/docker) role. + +Some variable names will change during the transition to having more and more external (galaxy) roles. There's a new `matrix/matrix_playbook_migration` role added to the playbook which will tell you about these changes each time you run the playbook. + +**From now on**, every time you update the playbook (well, every time the `requirements.yml` file changes), it's best to run `make roles` to update the roles downloaded from other sources. `make roles` is a shortcut (a `roles` target defined in [`Makefile`](Makefile) and executed by the [`make`](https://www.gnu.org/software/make/) utility) which ultimately runs [ansible-galaxy](https://docs.ansible.com/ansible/latest/cli/ansible-galaxy.html) to download Ansible roles. If you don't have `make`, you can also manually run the commands seen in the `Makefile`. + + +# 2022-10-14 + +## synapse-s3-storage-provider support + +**`synapse-s3-storage-provider` support is very new and still relatively untested. Using it may cause data loss.** + +You can now store your Synapse media repository files on Amazon S3 (or another S3-compatible object store) using [synapse-s3-storage-provider](https://github.com/matrix-org/synapse-s3-storage-provider) - a media provider for Synapse (Python module), which should work faster and more reliably than our previous [Goofys](docs/configuring-playbook-s3-goofys.md) implementation (Goofys will continue to work). + +This is not just for initial installations. Users with existing files (stored in the local filesystem) can also migrate their files to `synapse-s3-storage-provider`. + +To get started, see our [Storing Synapse media files on Amazon S3 with synapse-s3-storage-provider](docs/configuring-playbook-synapse-s3-storage-provider.md) documentation. + + +## Synapse container image customization support + +We now support customizing the Synapse container image by adding additional build steps to its [`Dockerfile`](https://docs.docker.com/engine/reference/builder/). + +Our [synapse-s3-storage-provider support](#synapse-s3-storage-provider-support) is actually built on this. When `s3-storage-provider` is enabled, we automatically add additional build steps to install its Python module into the Synapse image. + +Besides this kind of auto-added build steps (for components supported by the playbook), we also let you inject your own custom build steps using configuration like this: + +```yaml +matrix_synapse_container_image_customizations_enabled: true + +matrix_synapse_container_image_customizations_dockerfile_body_custom: | + RUN echo 'This is a custom step for building the customized Docker image for Synapse.' + RUN echo 'You can override matrix_synapse_container_image_customizations_dockerfile_body_custom to add your own steps.' + RUN echo 'You do NOT need to include a FROM clause yourself.' +``` + +People who have needed to customize Synapse previously had to fork the git repository, make their changes to the `Dockerfile` there, point the playbook to the new repository (`matrix_synapse_container_image_self_build_repo`) and enable self-building from scratch (`matrix_synapse_container_image_self_build: true`). This is harder and slower. + +With the new Synapse-customization feature in the playbook, we use the original upstream (pre-built, if available) Synapse image and only build on top of it, right on the Matrix server. This is much faster than building all of Synapse from scratch. + + +# 2022-10-02 + +## matrix-ldap-registration-proxy support + +Thanks to [@TheOneWithTheBraid](https://github.com/TheOneWithTheBraid), we now support installing [matrix-ldap-registration-proxy](https://gitlab.com/activism.international/matrix_ldap_registration_proxy) - a proxy which handles Matrix registration requests and forwards them to LDAP. + +See our [Setting up the ldap-registration-proxy](docs/configuring-playbook-matrix-ldap-registration-proxy.md) documentation to get started. + + +# 2022-09-15 + +## (Potential Backward Compatibility Break) Major improvements to Synapse workers + +People who are interested in running a Synapse worker setup should know that **our Synapse worker implementation is much more powerful now**: + +- we've added support for [Stream writers](#stream-writers-support) +- we've added support for [multiple federation sender workers](#multiple-federation-sender-workers-support) +- we've added support for [multiple pusher workers](#multiple-pusher-workers-support) +- we've added support for [running background tasks on a worker](#background-tasks-can-run-on-a-worker) +- we've restored support for [`appservice` workers](#appservice-worker-support-is-back) +- we've restored support for [`user_dir` workers](#user-directory-worker-support-is-back) +- we've made it possible to [reliably use more than 1 `media_repository` worker](#using-more-than-1-media-repository-worker-is-now-more-reliable) +- see the [Potential Backward Incompatibilities after these Synapse worker changes](#potential-backward-incompatibilities-after-these-synapse-worker-changes) + +### Stream writers support + +From now on, the playbook lets you easily set up various [stream writer workers](https://matrix-org.github.io/synapse/latest/workers.html#stream-writers) which can handle different streams (`events` stream; `typing` URL endpoints, `to_device` URL endpoints, `account_data` URL endpoints, `receipts` URL endpoints, `presence` URL endpoints). All of this work was previously handled by the main Synapse process, but can now be offloaded to stream writer worker processes. + +If you're using `matrix_synapse_workers_preset: one-of-each`, you'll automatically get 6 additional workers (one for each of the above stream types). Our `little-federation-helper` preset (meant to be quite minimal and focusing in improved federation performance) does not include stream writer workers. + +If you'd like to customize the number of workers we also make that possible using these variables: + +```yaml +# Synapse only supports more than 1 worker for the `events` stream. +# All other streams can utilize either 0 or 1 workers, not more than that. +matrix_synapse_workers_stream_writer_events_stream_workers_count: 5 +matrix_synapse_workers_stream_writer_typing_stream_workers_count: 1 +matrix_synapse_workers_stream_writer_to_device_stream_workers_count: 1 +matrix_synapse_workers_stream_writer_account_data_stream_workers_count: 1 +matrix_synapse_workers_stream_writer_receipts_stream_workers_count: 1 +matrix_synapse_workers_stream_writer_presence_stream_workers_count: 1 +``` + +### Multiple federation sender workers support + +Until now, we only supported a single `federation_sender` worker (`matrix_synapse_workers_federation_sender_workers_count` could either be `0` or `1`). +From now on, you can have as many as you want to help with your federation traffic. + +### Multiple pusher workers support + +Until now, we only supported a single `pusher` worker (`matrix_synapse_workers_pusher_workers_count` could either be `0` or `1`). +From now on, you can have as many as you want to help with pushing notifications out. + +### Background tasks can run on a worker + +From now on, you can put [background task processing on a worker](https://matrix-org.github.io/synapse/latest/workers.html#background-tasks). + +With `matrix_synapse_workers_preset: one-of-each`, you'll get one `background` worker automatically. +You can also control the `background` workers count with `matrix_synapse_workers_background_workers_count`. Only `0` or `1` workers of this type are supported by Synapse. + +### Appservice worker support is back + +We previously had an `appservice` worker type, which [Synapse deprecated in v1.59.0](https://github.com/matrix-org/synapse/blob/v1.59.0/docs/upgrade.md#deprecation-of-the-synapseappappservice-and-synapseappuser_dir-worker-application-types). So did we, at the time. + +The new way to implement such workers is by using a `generic_worker` and dedicating it to the task of talking to Application Services. +From now on, we have support for this. + +With `matrix_synapse_workers_preset: one-of-each`, you'll get one `appservice` worker automatically. +You can also control the `appservice` workers count with `matrix_synapse_workers_appservice_workers_count`. Only `0` or `1` workers of this type are supported by Synapse. + +### User Directory worker support is back + +We previously had a `user_dir` worker type, which [Synapse deprecated in v1.59.0](https://github.com/matrix-org/synapse/blob/v1.59.0/docs/upgrade.md#deprecation-of-the-synapseappappservice-and-synapseappuser_dir-worker-application-types). So did we, at the time. + +The new way to implement such workers is by using a `generic_worker` and dedicating it to the task of serving the user directory. +From now on, we have support for this. + +With `matrix_synapse_workers_preset: one-of-each`, you'll get one `user_dir` worker automatically. +You can also control the `user_dir` workers count with `matrix_synapse_workers_user_dir_workers_count`. Only `0` or `1` workers of this type are supported by Synapse. + +### Using more than 1 media repository worker is now more reliable + +With `matrix_synapse_workers_preset: one-of-each`, we only launch one `media_repository` worker. + +If you've been configuring `matrix_synapse_workers_media_repository_workers_count` manually, you may have increased that to more workers. +When multiple media repository workers are in use, background tasks related to the media repository must always be configured to run on a single `media_repository` worker via `media_instance_running_background_jobs`. Until now, we weren't doing this correctly, but we now are. + +### Potential Backward Incompatibilities after these Synapse worker changes + +Below we'll discuss **potential backward incompatibilities**. + +- **Worker names** (container names, systemd services, worker configuration files) **have changed**. Workers are now labeled sequentially (e.g. `matrix-synapse-worker_generic_worker-18111` -> `matrix-synapse-worker-generic-0`). The playbook will handle these changes automatically. + +- Due to increased worker types support above, people who use `matrix_synapse_workers_preset: one-of-each` should be aware that with these changes, **the playbook will deploy 9 additional workers** (6 stream writers, 1 `appservice` worker, 1 `user_dir` worker, 1 background task worker). This **may increase RAM/CPU usage**, etc. If you find your server struggling, consider disabling some workers with the appropriate `matrix_synapse_workers_*_workers_count` variables. + +- **Metric endpoints have also changed** (`/metrics/synapse/worker/generic_worker-18111` -> `/metrics/synapse/worker/generic-worker-0`). If you're [collecting metrics to an external Prometheus server](docs/configuring-playbook-prometheus-grafana.md#collecting-metrics-to-an-external-prometheus-server), consider revisiting our [Collecting Synapse worker metrics to an external Prometheus server](docs/configuring-playbook-prometheus-grafana.md#collecting-synapse-worker-metrics-to-an-external-prometheus-server) docs and updating your Prometheus configuration. **If you're collecting metrics to the integrated Prometheus server** (not enabled by default), **your Prometheus configuration will be updated automatically**. Old data (from before this change) may stick around though. + +- **the format of `matrix_synapse_workers_enabled_list` has changed**. You were never advised to use this variable for directly creating workers (we advise people to control workers using `matrix_synapse_workers_preset` or by tweaking `matrix_synapse_workers_*_workers_count` variables only), but some people may have started using the `matrix_synapse_workers_enabled_list` variable to gain more control over workers. If you're one of them, you'll need to adjust its value. See `roles/matrix/matrix-synapse/defaults/main.yml` for more information on the new format. The playbook will also do basic validation and complain if you got something wrong. + + +# 2022-09-09 + +## Cactus Comments support + +Thanks to [Julian-Samuel Gebühr (@moan0s)](https://github.com/moan0s), the playbook can now set up [Cactus Comments](https://cactus.chat) - federated comment system for the web based on Matrix. + +See our [Setting up a Cactus Comments server](docs/configuring-playbook-cactus-comments.md) documentation to get started. + + +# 2022-08-23 + +## Postmoogle email bridge support + +Thanks to [Aine](https://gitlab.com/etke.cc) of [etke.cc](https://etke.cc/), the playbook can now set up the new [Postmoogle](https://gitlab.com/etke.cc/postmoogle) email bridge/bot. Postmoogle is like the [email2matrix bridge](https://github.com/devture/email2matrix) (also [already supported by the playbook](docs/configuring-playbook-email2matrix.md)), but more capable and with the intention to soon support *sending* emails, not just receiving. + +See our [Setting up Postmoogle email bridging](docs/configuring-playbook-bot-postmoogle.md) documentation to get started. + + +# 2022-08-10 + +## mautrix-whatsapp default configuration changes + +In [Pull Request #2012](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/2012), we've made some changes to the default configuration used by the `mautrix-whatsapp` bridge. + +If you're using this bridge, you should look into this PR and see if the new configuration suits you. If not, you can always change individual preferences in your `vars.yml` file. + +Most notably, spaces support has been enabled by default. The bridge will now group rooms into a Matrix space. **If you've already bridged to Whatsapp** prior to this update, you will need to send `!wa sync space` to the bridge bot to make it create the space and put your existing rooms into it. + + +# 2022-08-09 + +## Conduit support + +Thanks to [Charles Wright](https://github.com/cvwright), we now have optional experimental [Conduit](https://conduit.rs) homeserver support for new installations. This comes as a follow-up to the playbook getting [Dendrite support](#dendrite-support) earlier this year. + +Existing Synapse or Dendrite installations do **not** need to be updated. **Synapse is still the default homeserver implementation** installed by the playbook. + +To try out Conduit, we recommend that you **use a new server** and the following `vars.yml` configuration: + +```yaml +matrix_homeserver_implementation: conduit +``` + +**The homeserver implementation of an existing server cannot be changed** (e.g. from Synapse or Dendrite to Conduit) without data loss. + + +# 2022-07-29 + +## mautrix-discord support + +Thanks to [MdotAmaan](https://github.com/MdotAmaan)'s efforts, the playbook now supports bridging to [Discord](https://discordapp.com/) via the [mautrix-discord](https://mau.dev/mautrix/discord) bridge. See our [Setting up Mautrix Discord bridging](docs/configuring-playbook-bridge-mautrix-discord.md) documentation page for getting started. + +**Note**: this is a new Discord bridge. The playbook still retains Discord bridging via [matrix-appservice-discord](docs/configuring-playbook-bridge-appservice-discord.md) and [mx-puppet-discord](docs/configuring-playbook-bridge-mx-puppet-discord.md). You're free too use the bridge that serves you better, or even all three of them (for different users and use-cases). + + +# 2022-07-27 + +## matrix-appservice-kakaotalk support + +The playbook now supports bridging to [Kakaotalk](https://www.kakaocorp.com/page/service/service/KakaoTalk?lang=ENG) via [matrix-appservice-kakaotalk](https://src.miscworks.net/fair/matrix-appservice-kakaotalk) - a bridge based on [node-kakao](https://github.com/storycraft/node-kakao) (now unmaintained) and some [mautrix-facebook](https://github.com/mautrix/facebook) code. Thanks to [hnarjis](https://github.com/hnarjis) for helping us add support for this! + +See our [Setting up Appservice Kakaotalk bridging](docs/configuring-playbook-bridge-appservice-kakaotalk.md) documentation to get started. + + +# 2022-07-20 + +## maubot support + +Thanks to [Stuart Mumford (@Cadair)](https://github.com/cadair) for starting ([PR #373](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/373) and [PR #622](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/622)) and to [Julian-Samuel Gebühr (@moan0s)](https://github.com/moan0s) for finishing up (in [PR #1894](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/1894)), the playbook can now help you set up [maubot](https://github.com/maubot/maubot) - a plugin-based Matrix bot system. + +See our [Setting up maubot](docs/configuring-playbook-bot-maubot.md) documentation to get started. + + +# 2022-07-14 + +## mx-puppet-skype removal + +The playbook no longer includes the [mx-puppet-skype](https://github.com/Sorunome/mx-puppet-skype) bridge, because it has been broken and unmaintaned for a long time. Users that have `matrix_mx_puppet_skype_enabled` in their configuration files will encounter an error when running the playbook until they remove references to this bridge from their configuration. + +To completely clean up your server from `mx-puppet-skype`'s presence on it: + +- ensure your Ansible configuration (`vars.yml` file) no longer contains `matrix_mx_puppet_skype_*` references +- stop and disable the systemd service (run `systemctl disable --now matrix-mx-puppet-skype` on the server) +- delete the systemd service (run `rm /etc/systemd/system/matrix-mx-puppet-skype.service` on the server) +- delete `/matrix/mx-puppet-skype` (run `rm -rf /matrix/mx-puppet-skype` on the server) +- drop the `matrix_mx_puppet_skype` database (run `/usr/local/bin/matrix-postgres-cli` on the server, and execute the `DROP DATABASE matrix_mx_puppet_skype;` query there) + +If you still need bridging to [Skype](https://www.skype.com/), consider switching to [go-skype-bridge](https://github.com/kelaresg/go-skype-bridge) instead. See [Setting up Go Skype Bridge bridging](docs/configuring-playbook-bridge-go-skype-bridge.md). + +If you think this is a mistake and `mx-puppet-skype` works for you (or you get it to work somehow), let us know and we may reconsider this removal. + + +## signald (0.19.0+) upgrade requires data migration + +In [Pull Request #1921](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/1921) we upgraded [signald](https://signald.org/) (used by the mautrix-signal bridge) from `v0.18.5` to `v0.20.0`. + +Back in the [`v0.19.0` released of signald](https://gitlab.com/signald/signald/-/blob/main/releases/0.19.0.md) (which we skipped and migrated straight to `v0.20.0`), a new `--migrate-data` command had been added that migrates avatars, group images, attachments, etc., into the database (those were previously stored in the filesystem). + +If you've been using the mautrix-signal bridge for a while, you may have files stored in the local filesystem, which will need to be upgraded. + +We attempt to do this data migration automatically every time Signald starts (`matrix-mautrix-signal-daemon.service`) using a `ExecStartPre` systemd unit definition. + +Keep an eye on your Signal bridge and let us know (in our [support room](README.md#support) or in [Pull Request #1921](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/1921)) if you experience any trouble! + + +# 2022-07-05 + +## Ntfy push notifications support + +Thanks to [Julian Foad](https://matrix.to/#/@julian:foad.me.uk), the playbook can now install a [ntfy](https://ntfy.sh/) push notifications server for you. + +See our [Setting up the ntfy push notifications server](docs/configuring-playbook-ntfy.md) documentation to get started. + + +# 2022-06-23 + +## (Potential Backward Compatibility Break) Changes around metrics collection + +**TLDR**: we've made extensive **changes to metrics exposure/collection, which concern people using an external Prometheus server**. If you don't know what that is, you don't need to read below. + +**Why do major changes to metrics**? Because various services were exposing metrics in different, hacky, ways. Synapse was exposing metrics at `/_synapse/metrics` and `/_synapse-worker-.../metrics` on the `matrix.DOMAIN`. The Hookshot role was **repurposing** the Granana web UI domain (`stats.DOMAIN`) for exposing its metrics on `stats.DOMAIN/hookshot/metrics`, while protecting these routes using Basic Authentication **normally used for Synapse** (`/_synapse/metrics`). Node-exporter and Postgres-exporter roles were advising for more `stats.DOMAIN` usage in manual ways. Each role was doing things differently and mixing variables from other roles. Each metrics endpoint was ending up in a different place, protected by who knows what Basic Authentication credentials (if protected at all). + +**The solution**: a completely revamped way to expose metrics to an external Prometheus server. We are **introducing new `https://matrix.DOMAIN/metrics/*` endpoints**, where various services *can* expose their metrics, for collection by external Prometheus servers. To enable the `/metrics/*` endpoints, use `matrix_nginx_proxy_proxy_matrix_metrics_enabled: true`. There's also a way to protect access using [Basic Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication). See the `matrix-nginx-proxy` role or our [Collecting metrics to an external Prometheus server](docs/configuring-playbook-prometheus-grafana.md#collecting-metrics-to-an-external-prometheus-server) documentation for additional variables around `matrix_nginx_proxy_proxy_matrix_metrics_enabled`. + +**If you are using the [Hookshot bridge](docs/configuring-playbook-bridge-hookshot.md)**, you may find that: +1. **Metrics may not be enabled by default anymore**: + - If Prometheus is enabled (`matrix_prometheus_enabled: true`), then Hookshot metrics will be enabled automatically (`matrix_hookshot_metrics_enabled: true`). These metrics will be collected from the local (in-container) Prometheus over the container network. + - **If Prometheus is not enabled** (you are either not using Prometheus or are using an external one), **Hookshot metrics will not be enabled by default anymore**. Feel free to enable them by setting `matrix_hookshot_metrics_enabled: true`. Also, see below. +2. When metrics are meant to be **consumed by an external Prometheus server**, `matrix_hookshot_metrics_proxying_enabled` needs to be set to `true`, so that metrics would be exposed (proxied) "publicly" on `https://matrix.DOMAIN/metrics/hookshot`. To make use of this, you'll also need to enable the new `https://matrix.DOMAIN/metrics/*` endpoints mentioned above, using `matrix_nginx_proxy_proxy_matrix_metrics_enabled`. Learn more in our [Collecting metrics to an external Prometheus server](docs/configuring-playbook-prometheus-grafana.md#collecting-metrics-to-an-external-prometheus-server) documentation. +3. **We've changed the URL we're exposing Hookshot metrics at** for external Prometheus servers. Until now, you were advised to consume Hookshot metrics from `https://stats.DOMAIN/hookshot/metrics` (working in conjunction with `matrix_nginx_proxy_proxy_synapse_metrics`). From now on, **this no longer works**. As described above, you need to start consuming metrics from `https://matrix.DOMAIN/metrics/hookshot`. + +**If you're using node-exporter** (`matrix_prometheus_node_exporter_enabled: true`) and would like to collect its metrics from an external Prometheus server, see `matrix_prometheus_node_exporter_metrics_proxying_enabled` described in our [Collecting metrics to an external Prometheus server](docs/configuring-playbook-prometheus-grafana.md#collecting-metrics-to-an-external-prometheus-server) documentation. You will be able to collect its metrics from `https://matrix.DOMAIN/metrics/node-exporter`. + +**If you're using [postgres-exporter](docs/configuring-playbook-prometheus-postgres.md)** (`matrix_prometheus_postgres_exporter_enabled: true`) and would like to collect its metrics from an external Prometheus server, see `matrix_prometheus_postgres_exporter_metrics_proxying_enabled` described in our [Collecting metrics to an external Prometheus server](docs/configuring-playbook-prometheus-grafana.md#collecting-metrics-to-an-external-prometheus-server) documentation. You will be able to collect its metrics from `https://matrix.DOMAIN/metrics/postgres-exporter`. + +**If you're using Synapse** and would like to collect its metrics from an external Prometheus server, you may find that: + +1. Exposing metrics is now done using `matrix_synapse_metrics_proxying_enabled`, not `matrix_nginx_proxy_proxy_synapse_metrics: true`. You may still need to enable metrics using `matrix_synapse_metrics_enabled: true` before exposing them. +2. Protecting metrics endpoints using [Basic Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication) is now done in another way. See our [Collecting metrics to an external Prometheus server](docs/configuring-playbook-prometheus-grafana.md#collecting-metrics-to-an-external-prometheus-server) documentation +3. If Synapse metrics are exposed, they will be made available at `https://matrix.DOMAIN/metrics/synapse/main-process` or `https://matrix.DOMAIN/metrics/synapse/worker/TYPE-ID` (when workers are enabled), not at `https://matrix.DOMAIN/_synapse/metrics` and `https://matrix.DOMAIN/_synapse-worker-.../metrics` +4. The playbook still generates an `external_prometheus.yml.example` sample file for scraping Synapse from Prometheus as described in [Collecting Synapse worker metrics to an external Prometheus server](docs/configuring-playbook-prometheus-grafana.md#collecting-synapse-worker-metrics-to-an-external-prometheus-server), but it's now saved under `/matrix/synapse` (not `/matrix`). + +**If you where already using a external Prometheus server** before this change, and you gave a hashed version of the password as a variable, the playbook will now take care of hashing the password for you. Thus, you need to provide the non-hashed version now. + +# 2022-06-13 + +## go-skype-bridge bridging support + +Thanks to [CyberShadow](https://github.com/CyberShadow), the playbook can now install the [go-skype-bridge](https://github.com/kelaresg/go-skype-bridge) bridge for bridging Matrix to [Skype](https://www.skype.com/). + +See our [Setting up Go Skype Bridge](docs/configuring-playbook-bridge-go-skype-bridge.md) documentation to get started. + +The playbook has supported [mx-puppet-skype](https://github.com/Sorunome/mx-puppet-skype) bridging (see [Setting up MX Puppet Skype bridging](docs/configuring-playbook-bridge-mx-puppet-skype.md)) since [2020-04-09](#2020-04-09), but `mx-puppet-skype` is reportedly broken. + + +# 2022-06-09 + +## Running Ansible in a container can now happen on the Matrix server itself + +If you're tired of being on an old and problematic Ansible version, you can now run [run Ansible in a container on the Matrix server itself](docs/ansible.md#running-ansible-in-a-container-on-the-matrix-server-itself). + + +# 2022-05-31 + +## Synapse v1.60 upgrade may cause trouble and require manual intervention + +Synapse v1.60 will try to add a new unique index to `state_group_edges` upon startup and could fail if your database is corrupted. + +We haven't observed this problem yet, but [the Synapse v1.60.0 upgrade notes](https://github.com/matrix-org/synapse/blob/v1.60.0/docs/upgrade.md#adding-a-new-unique-index-to-state_group_edges-could-fail-if-your-database-is-corrupted) mention it, so we're giving you a heads up here in case you're unlucky. + +**If Synapse fails to start** after your next playbook run, you'll need to: + +- SSH into the Matrix server +- launch `/usr/local/bin/matrix-postgres-cli` +- switch to the `synapse` database: `\c synapse` +- run the following SQL query: + +```sql +BEGIN; +DELETE FROM state_group_edges WHERE (ctid, state_group, prev_state_group) IN ( + SELECT row_id, state_group, prev_state_group + FROM ( + SELECT + ctid AS row_id, + MIN(ctid) OVER (PARTITION BY state_group, prev_state_group) AS min_row_id, + state_group, + prev_state_group + FROM state_group_edges + ) AS t1 + WHERE row_id <> min_row_id +); +COMMIT; +``` + +You could then restart services: `ansible-playbook -i inventory/hosts setup.yml --tags=start` + + +# 2022-04-25 + +## buscarron bot support + +Thanks to [Aine](https://gitlab.com/etke.cc) of [etke.cc](https://etke.cc/), the playbook can now set up [the Buscarron bot](https://gitlab.com/etke.cc/buscarron). It's a bot you can use to send any form (HTTP POST, HTML) to a (encrypted) Matrix room + +See our [Setting up Buscarron](docs/configuring-playbook-bot-buscarron.md) documentation to get started. + + +# 2022-04-21 + +## matrix-registration-bot support + +Thanks to [Julian-Samuel Gebühr (@moan0s)](https://github.com/moan0s), the playbook can now help you set up [matrix-registration-bot](https://github.com/moan0s/matrix-registration-bot) - a bot that is used to create and manage registration tokens for a Matrix server. + +See our [Setting up matrix-registration-bot](docs/configuring-playbook-bot-matrix-registration-bot.md) documentation to get started. + + +# 2022-04-19 + +## Borg backup support + +Thanks to [Aine](https://gitlab.com/etke.cc) of [etke.cc](https://etke.cc/), the playbook can now set up [Borg](https://www.borgbackup.org/) backups with [borgmatic](https://torsion.org/borgmatic/) of your Matrix server. + +See our [Setting up borg backup](docs/configuring-playbook-backup-borg.md) documentation to get started. + + +## (Compatibility Break) Upgrading to Synapse v1.57 on setups using workers may require manual action + +If you're running a worker setup for Synapse (`matrix_synapse_workers_enabled: true`), the [Synapse v1.57 upgrade notes](https://github.com/matrix-org/synapse/blob/v1.57.0rc1/docs/upgrade.md#changes-to-database-schema-for-application-services) say that you may need to take special care when upgrading: + +> Synapse v1.57.0 includes a change to the way transaction IDs are managed for application services. If your deployment uses a dedicated worker for application service traffic, **it must be stopped** when the database is upgraded (which normally happens when the main process is upgraded), to ensure the change is made safely without any risk of reusing transaction IDs. + +If you're not running an `appservice` worker (`matrix_synapse_workers_preset: little-federation-helper` or `matrix_synapse_workers_appservice_workers_count: 0`), you are probably safe to upgrade as per normal, without taking any special care. + +If you are running a setup with an `appservice` worker, or otherwise want to be on the safe side, we recommend the following upgrade path: + +0. Pull the latest playbook changes +1. Stop all services (`ansible-playbook -i inventory/hosts setup.yml --tags=stop`) +2. Re-run the playbook (`ansible-playbook -i inventory/hosts setup.yml --tags=setup-all`) +3. Start Postgres (`systemctl start matrix-postgres` on the server) +4. Start the main Synapse process (`systemctl start matrix-synapse` on the server) +5. Wait a while so that Synapse can start and complete the database migrations. You can use `journalctl -fu matrix-synapse` on the server to get a clue. Waiting a few minutes should also be enough. +6. It should now be safe to start all other services. `ansible-playbook -i inventory/hosts setup.yml --tags=start` will do it for you + + +# 2022-04-14 + +## (Compatibility Break) Changes to `docker-src` permissions necessitating manual action + +Users who build container images from source will need to manually correct file permissions of some directories on the server. + +When self-building, the playbook used to `git clone` repositories (into `/matrix/SERVICE/docker-src`) using the `root` user, but now uses `matrix` instead to work around [the following issue with git 2.35.2](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1749). + +If you're on a non-`amd64` architecture (that is, you're overriding `matrix_architecture` in your `vars.yml` file) or you have enabled self-building for some service (e.g. `matrix_*_self_build: true`), you're certainly building some container images from source and have `docker-src` directories with mixed permissions lying around in various `/matrix/SERVICE` directories. + +The playbook *could* correct these permissions automatically, but that requires additional Ansible tasks in some ~45 different places - something that takes considerable effort. So we ask users observing errors related to `docker-src` directories to correct the problem manually by **running this command on the Matrix server** (which deletes all `/matrix/*/docker-src` directories): `find /matrix -maxdepth 2 -name 'docker-src' | xargs rm -rf` + + +# 2022-03-17 + +## (Compatibility Break) ma1sd identity server no longer installed by default + +The playbook no longer installs the [ma1sd](https://github.com/ma1uta/ma1sd) identity server by default. The next time you run the playbook, ma1sd will be uninstalled from your server, unless you explicitly enable the ma1sd service (see how below). + +The main reason we used to install ma1sd by default in the past was to prevent Element from talking to the `matrix.org` / `vector.im` identity servers, by forcing it to talk to our own self-hosted (but otherwise useless) identity server instead, thus preventing contact list leaks. + +Since Element no longer defaults to using a public identity server if another one is not provided, we can stop installing ma1sd. + +If you need to install the ma1sd identity server for some reason, you can explicitly enable it by adding this to your `vars.yml` file: + +```yaml +matrix_ma1sd_enabled: true +``` + + +# 2022-02-12 + +## matrix_encryption_disabler support + +We now support installing the [matrix_encryption_disabler](https://github.com/digitalentity/matrix_encryption_disabler) Synapse module, which lets you prevent End-to-End-Encryption from being enabled by users on your homeserver. The popular opinion is that this is dangerous and shouldn't be done, but there are valid use cases for disabling encryption discussed [here](https://github.com/matrix-org/synapse/issues/4401). + +To enable this module (and prevent encryption from being used on your homserver), add `matrix_synapse_ext_encryption_disabler_enabled: true` to your configuration. This module provides further customization. Check its other configuration settings (and defaults) in `roles/matrix/matrix-synapse/defaults/main.yml`. + + +# 2022-02-01 + +## matrix-hookshot bridging support + +Thanks to [HarHarLinks](https://github.com/HarHarLinks), the playbook can now install the [matrix-hookshot](https://github.com/Half-Shot/matrix-hookshot) bridge for bridging Matrix to multiple project management services, such as GitHub, GitLab and JIRA. +See our [Setting up matrix-hookshot](docs/configuring-playbook-bridge-hookshot.md) documentation to get started. + + +# 2022-01-31 + +## ARM support for matrix-corporal + +[matrix-corporal](https://github.com/devture/matrix-corporal) (as of version `2.2.3`) is now published to Docker Hub (see [devture/matrix-corporal](https://hub.docker.com/r/devture/matrix-corporal)) as a multi-arch container image with support for all these platforms: `linux/amd64`, `linux/arm64/v8` and `linux/arm/v7`. The playbook no longer resorts to self-building matrix-corporal on these ARM architectures. + + +# 2022-01-07 + +## Dendrite support + +**TLDR**: We now have optional experimental [Dendrite](https://github.com/matrix-org/dendrite) homeserver support for new installations. **Existing (Synapse) installations need to be updated**, because some internals changed. See [Adapting the configuration for existing Synapse installations](#adapting-the-configuration-for-existing-synapse-installations). + +[Jip J. Dekker](https://github.com/Dekker1) did the [initial work](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/818) of adding [Dendrite](https://github.com/matrix-org/dendrite) support to the playbook back in January 2021. Lots of work (and time) later, Dendrite support is finally ready for testing. + +We believe that 2022 will be the year of the non-Synapse Matrix server! + +The playbook was previously quite [Synapse](https://github.com/matrix-org/synapse)-centric, but can now accommodate multiple homeserver implementations. Only one homeserver implementation can be active (installed) at a given time. + +**Synapse is still the default homeserver implementation** installed by the playbook. A new variable (`matrix_homeserver_implementation`) controls which server implementation is enabled (`synapse` or `dendrite` at the given moment). + +### Adapting the configuration for existing Synapse installations + +Because the playbook is not so Synapse-centric anymore, a small configuration change is necessary for existing installations to bring them up to date. + +The `vars.yml` file for **existing installations will need to be updated** by adding this **additional configuration**: + +```yaml +# All secrets keys are now derived from `matrix_homeserver_generic_secret_key`, not from `matrix_synapse_macaroon_secret_key`. +# To keep them all the same, define `matrix_homeserver_generic_secret_key` in terms of `matrix_synapse_macaroon_secret_key`. +# Using a new secret value for this configuration key is also possible and should not cause any problems. +# +# Fun fact: new installations (based on the new `examples/vars.yml` file) do this in reverse. +# That is, the Synapse macaroon secret is derived from `matrix_homeserver_generic_secret_key`. +matrix_homeserver_generic_secret_key: "{{ matrix_synapse_macaroon_secret_key }}" +``` + +### Trying out Dendrite + +Finally, **to try out Dendrite**, we recommend that you **use a new server** and the following addition to your `vars.yml` configuration: + +```yaml +matrix_homeserver_implementation: dendrite +``` + +**The homeserver implementation of an existing server cannot be changed** (e.g. from Synapse to Dendrite) without data loss. + +We're excited to gain support for other homeserver implementations, like [Conduit](https://conduit.rs/), etc! + + +## Honoroit bot support + +Thanks to [Aine](https://gitlab.com/etke.cc) of [etke.cc](https://etke.cc/), the playbook can now help you set up [Honoroit](https://gitlab.com/etke.cc/honoroit) - a helpdesk bot. + +See our [Setting up Honoroit](docs/configuring-playbook-bot-honoroit.md) documentation to get started. + + +# 2022-01-06 + +## Cinny support + +Thanks to [Aine](https://gitlab.com/etke.cc) of [etke.cc](https://etke.cc/), the playbook now supports [Cinny](https://cinny.in/) - a new simple, elegant and secure Matrix client. + +By default, we still install Element. Still, people who'd like to try Cinny out can now install it via the playbook. + +Additional details are available in [Setting up Cinny](docs/configuring-playbook-client-cinny.md). + + +# 2021-12-22 + +## Twitter bridging support via mautrix-twitter + +Thanks to [Matthew Cengia](https://github.com/mattcen) and [Shreyas Ajjarapu](https://github.com/shreyasajj), besides [mx-puppet-twitter](docs/configuring-playbook-bridge-mx-puppet-twitter.md), bridging to [Twitter](https://twitter.com/) can now also happen with [mautrix-twitter](docs/configuring-playbook-bridge-mautrix-twitter.md). + + +# 2021-12-14 + +## (Security) Users of the Signal bridge may wish to upgrade it to work around log4j vulnerability + +Recently, a security vulnerability affecting the Java logging package `log4j` [has been discovered](https://www.huntress.com/blog/rapid-response-critical-rce-vulnerability-is-affecting-java). Software that uses this Java package is potentially vulnerable. + +One such piece of software that is part of the playbook is the [mautrix-signal bridge](./docs/configuring-playbook-bridge-mautrix-signal.md), which [has been patched already](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/1452). If you're running this bridge, you may wish to [upgrade](./docs/maintenance-upgrading-services.md). + + +# 2021-11-11 + +## Dropped support for Postgres v9.6 + +Postgres v9.6 reached its end of life today, so the playbook will refuse to run for you if you're still on that version. + +Synapse still supports v9.6 (for now), but we're retiring support for it early, to avoid having to maintain support for so many Postgres versions. Users that are still on Postgres v9.6 can easily [upgrade Postgres](docs/maintenance-postgres.md#upgrading-postgresql) via the playbook. + + +# 2021-10-23 + +## Hangouts bridge no longer updated, superseded by a Googlechat bridge + +The mautrix-hangouts bridge is no longer receiving updates upstream and is likely to stop working in the future. +We still retain support for this bridge in the playbook, but you're encouraged to switch away from it. + +There's a new [mautrix-googlechat](https://github.com/mautrix/googlechat) bridge that you can [install using the playbook](docs/configuring-playbook-bridge-mautrix-googlechat.md). +Your **Hangouts bridge data will not be migrated**, however. You need to start fresh with the new bridge. + + +# 2021-08-23 + +## LinkedIn bridging support via beeper-linkedin + +Thanks to [Alexandar Mechev](https://github.com/apmechev), the playbook can now install the [beeper-linkedin](https://gitlab.com/beeper/linkedin) bridge for bridging to [LinkedIn](https://www.linkedin.com/) Messaging. + +This brings the total number of bridges supported by the playbook up to 20. See all supported bridges [here](docs/configuring-playbook.md#bridging-other-networks). + +To get started with bridging to LinkedIn, see [Setting up Beeper LinkedIn bridging](docs/configuring-playbook-bridge-beeper-linkedin.md). + + +# 2021-08-20 + +# Sygnal upgraded - ARM support and no longer requires a database + +The [Sygnal](docs/configuring-playbook-sygnal.md) push gateway has been upgraded from `v0.9.0` to `v0.10.1`. + +This is an optional component for the playbook, so most of our users wouldn't care about this announcement. + +Since this feels like a relatively big (and untested, as of yet) Sygnal change, we're putting up this changelog entry. + +The new version is also available for the ARM architecture. It also no longer requires a database anymore. +If you need to downgrade to the previous version, changing `matrix_sygnal_version` or `matrix_sygnal_docker_image` will not be enough, as we've removed the `database` configuration completely. You'd need to switch to an earlier playbook commit. + + +# 2021-05-21 + +## Hydrogen support + +Thanks to [Aaron Raimist](https://github.com/aaronraimist), the playbook now supports [Hydrogen](https://github.com/vector-im/hydrogen-web) - a new lightweight matrix client with legacy and mobile browser support. + +By default, we still install Element, as Hydrogen is still not fully-featured. Still, people who'd like to try Hydrogen out can now install it via the playbook. + +Additional details are available in [Setting up Hydrogen](docs/configuring-playbook-client-hydrogen.md). + + +# 2021-05-19 + +## Heisenbridge support + +Thanks to [Toni Spets (hifi)](https://github.com/hifi), the playbook now supports bridging to [IRC](https://en.wikipedia.org/wiki/Internet_Relay_Chat) using yet another bridge (besides matrix-appservice-irc), called [Heisenbridge](https://github.com/hifi/heisenbridge). + +Additional details are available in [Setting up Heisenbridge bouncer-style IRC bridging](docs/configuring-playbook-bridge-heisenbridge.md). + + +# 2021-04-16 + +## Disabling TLSv1 and TLSv1.1 for Coturn + +To improve security, we've [removed TLSv1 and TLSv1.1 support](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/999) from our default [Coturn](https://github.com/coturn/coturn) configuration. + +If you need to support old clients, you can re-enable both (or whichever one you need) with the following configuration: + +```yaml +matrix_coturn_tls_v1_enabled: true +matrix_coturn_tls_v1_1_enabled: true +``` + + +# 2021-04-05 + +## Automated local Postgres backup support + +Thanks to [foxcris](https://github.com/foxcris), the playbook can now make automated local Postgres backups on a fixed schedule using [docker-postgres-backup-local](https://github.com/prodrigestivill/docker-postgres-backup-local). + +Additional details are available in [Setting up postgres backup](docs/configuring-playbook-postgres-backup.md). + + + +# 2021-04-03 + +## Mjolnir moderation tool (bot) support + +Thanks to [Aaron Raimist](https://github.com/aaronraimist), the playbook can now install and configure the [Mjolnir](https://github.com/matrix-org/mjolnir) moderation tool (bot). + +Additional details are available in [Setting up Mjolnir](docs/configuring-playbook-bot-mjolnir.md). + + +# 2021-03-20 + +## Sygnal push gateway support + +The playbook can now install the [Sygnal](https://github.com/matrix-org/sygnal) push gateway for you. + +This is only useful to people who develop/build their own Matrix client applications. + +Additional details are available in our [Setting up Sygnal](docs/configuring-playbook-sygnal.md) docs. + + +# 2021-03-16 + +## Go-NEB support + +Thanks to [Zir0h](https://github.com/Zir0h), the playbook can now install and configure the [Go-NEB](https://github.com/matrix-org/go-neb) bot. + +Additional details are available in [Setting up Go-NEB](docs/configuring-playbook-bot-go-neb.md). + + +# 2021-02-19 + +## GroupMe bridging support via mx-puppet-groupme + +Thanks to [Cody Neiman](https://github.com/xangelix), the playbook can now install the [mx-puppet-groupme](https://gitlab.com/robintown/mx-puppet-groupme) bridge for bridging to [GroupMe](https://groupme.com). + +This brings the total number of bridges supported by the playbook up to 18. See all supported bridges [here](docs/configuring-playbook.md#bridging-other-networks). + +To get started, follow our [Setting up MX Puppet GroupMe](docs/configuring-playbook-bridge-mx-puppet-groupme.md) docs. + +## Mautrix Instagram bridging support + +The playbook now supports bridging with [Instagram](https://www.instagram.com/) by installing the [mautrix-instagram](https://github.com/tulir/mautrix-instagram) bridge. This playbook functionality is available thanks to [@MarcProe](https://github.com/MarcProe). + +Additional details are available in [Setting up Mautrix Instagram bridging](docs/configuring-playbook-bridge-mautrix-instagram.md). + +## Synapse workers support + +After [lots and lots of work](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/456) (done over many months by [Marcel Partap](https://github.com/eMPee584), [Max Klenk](https://github.com/maxklenk), a few others from the [Technical University of Dresden, Germany](https://tu-dresden.de/) and various other contributors), support for Synapse workers has finally landed. + +Having support for workers makes the playbook suitable for larger homeserver deployments. + +Our setup is not yet perfect (we don't support all types of workers; scaling some of them (like `pusher`, `federation_sender`) beyond a single instance is not yet supported). Still, it's a great start and can already power homeservers with thousands of users, like the [Matrix deployment at TU Dresden](https://doc.matrix.tu-dresden.de/en/) discussed in [Matrix Live S06E09 - TU Dresden on their Matrix deployment](https://www.youtube.com/watch?v=UHJX2pmT2gk). + +By default, workers are disabled and Synapse runs as a single process (homeservers don't necessarily need the complexity and increased memory requirements of running a worker-based setup). + +To enable Synapse workers, follow our [Load balancing with workers](docs/configuring-playbook-synapse.md#load-balancing-with-workers) documentation. + + +# 2021-02-12 + +## (Potential Breaking Change) Monitoring/metrics support using Prometheus and Grafana + +Thanks to [@Peetz0r](https://github.com/Peetz0r), the playbook can now install a bunch of tools for monitoring your Matrix server: the [Prometheus](https://prometheus.io) time-series database server, the Prometheus [node-exporter](https://prometheus.io/docs/guides/node-exporter/) host metrics exporter, and the [Grafana](https://grafana.com/) web UI. + +To get get these installed, follow our [Enabling metrics and graphs (Prometheus, Grafana) for your Matrix server](docs/configuring-playbook-prometheus-grafana.md) docs page. + +This update comes with a **potential breaking change** for people who were already exposing Synapse metrics (for consumption via another Prometheus installation). From now on, `matrix_synapse_metrics_enabled: true` no longer exposes metrics publicly via matrix-nginx-proxy (at `https://matrix.DOMAIN/_synapse/metrics`). To do so, you'd need to explicitly set `matrix_nginx_proxy_proxy_synapse_metrics: true`. + + +# 2021-01-31 + +## Etherpad support + +Thanks to [@pushytoxin](https://github.com/pushytoxin), the playbook can now install the [Etherpad](https://etherpad.org) realtime collaborative text editor. It can be used in a [Jitsi](https://jitsi.org/) audio/video call or integrated as a widget into Matrix chat rooms via the [Dimension](https://dimension.t2bot.io) integration manager. + +To get it installed, follow [our Etherpad docs page](docs/configuring-playbook-etherpad.md). + + +# 2021-01-22 + +## (Breaking Change) Postgres changes that require manual intervention + +We've made a lot of changes to our Postgres setup and some manual action is required (described below). Sorry about the hassle. + +**TLDR**: people running an [external Postgres server](docs/configuring-playbook-external-postgres.md) don't need to change anything for now. Everyone else (the common/default case) is affected and manual intervention is required. + +### Why? + +- we had a default Postgres password (`matrix_postgres_connection_password: synapse-password`), which we think is **not ideal for security anymore**. We now ask you to generate/provide a strong password yourself. Postgres is normally not exposed outside the container network, making it relatively secure, but still: + - by tweaking the configuration, you may end up intentionally or unintentionally exposing your Postgres server to the local network (or even publicly), while still using the default default credentials (`synapse` + `synapse-password`) + - we can't be sure we trust all these services (bridges, etc). Some of them may try to talk to or attack `matrix-postgres` using the default credentials (`synapse` + `synapse-password`) + - you may have other containers running on the same Docker network, which may try to talk to or attack `matrix-postgres` using the default credentials (`synapse` + `synapse-password`) +- our Postgres usage **was overly-focused on Synapse** (default username of `synapse` and default/main database of `homeserver`). Additional homeserver options are likely coming in the future ([Dendrite](https://matrix.org/docs/projects/server/dendrite), [Conduit](https://matrix.org/docs/projects/server/conduit), [The Construct](https://matrix.org/docs/projects/server/construct)), so being too focused on `matrix-synapse` is not great. From now on, Synapse is just another component of this playbook, which happens to have an *additional database* (called `synapse`) on the Postgres server. +- we try to reorganize things a bit, to make the playbook even friendlier to people running an [external Postgres server](docs/configuring-playbook-external-postgres.md). Work on this will proceed in the future. + +So, this is some **effort to improve security** and to **prepare for a brighter future of having more homeserver options** than just Synapse. + +### What has really changed? + +- the default superuser Postgres username is now `matrix` (used to be `synapse`) +- the default Postgres database is now `matrix` (used to be `homeserver`) +- Synapse's database is now `synapse` (used to be `homeserver`). This is now just another "additional database" that the playbook manages for you +- Synapse's user called `synapse` is just a regular user that can only use the `synapse` database (not a superuser anymore) + +### What do I do if I'm using the integrated Postgres server (default)? + +By default, the playbook runs an integrated Postgres server for you in a container (`matrix-postgres`). Unless you've explicitly configured an [external Postgres server](docs/configuring-playbook-external-postgres.md), these steps are meant for you. + +To migrate to the new setup, expect a few minutes of downtime, while you follow these steps: + +1. We believe the steps below are safe and you won't encounter any data loss, but consider [making a Postgres backup](docs/maintenance-postgres.md#backing-up-postgresql) anyway. If you've never backed up Postgres, now would be a good time to try it. + +2. Generate a strong password to be used for your superuser Postgres user (called `matrix`). You can use `pwgen -s 64 1` to generate it, or some other tool. The **maximum length** for a Postgres password is 100 bytes (characters). Don't go crazy! + +3. Update your playbook's `inventory/host_vars/matrix.DOMAIN/vars.yml` file, adding a line like this: +```yaml +matrix_postgres_connection_password: 'YOUR_POSTGRES_PASSWORD_HERE' +``` + +.. where `YOUR_POSTGRES_PASSWORD_HERE` is to be replaced with the password you generated during step #2. + +4. Stop all services: `ansible-playbook -i inventory/hosts setup.yml --tags=stop` +5. Log in to the server via SSH. The next commands will be performed there. +6. Start the Postgres database server: `systemctl start matrix-postgres` +7. Open a Postgres shell: `/usr/local/bin/matrix-postgres-cli` +8. Execute the following query, while making sure to **change the password inside** (**don't forget the ending `;`**): + +```sql +CREATE ROLE matrix LOGIN SUPERUSER PASSWORD 'YOUR_POSTGRES_PASSWORD_HERE'; +``` + +.. where `YOUR_POSTGRES_PASSWORD_HERE` is to be replaced with the password you generated during step #2. + +9. Execute the following queries as you see them (no modifications necessary, so you can just **paste them all at once**): + +```sql +CREATE DATABASE matrix OWNER matrix; + +ALTER DATABASE postgres OWNER TO matrix; +ALTER DATABASE template0 OWNER TO matrix; +ALTER DATABASE template1 OWNER TO matrix; + +\c matrix; + +ALTER DATABASE homeserver RENAME TO synapse; + +ALTER ROLE synapse NOSUPERUSER NOCREATEDB NOCREATEROLE; + +\quit +``` + +You may need to press *Enter* after pasting the lines above. + +10. Re-run the playbook normally: `ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start` + +### What do I do if I'm using an external Postgres server? + +If you've explicitly configured an [external Postgres server](docs/configuring-playbook-external-postgres.md), there are **no changes** that you need to do at this time. + +The fact that we've renamed Synapse's database from `homeserver` to `synapse` (in our defaults) should not affect you, as you're already explicitly defining `matrix_synapse_database_database` (if you've followed our guide, that is). If you're not explicitly defining this variable, you may wish to do so (`matrix_synapse_database_database: homeserver`), to avoid the new `synapse` default and keep things as they were. + + +# 2021-01-20 + +## (Breaking Change) The mautrix-facebook bridge now requires a Postgres database + +**Update from 2021-11-15**: SQLite support has been re-added to the mautrix-facebook bridge in [v0.3.2](https://github.com/mautrix/facebook/releases/tag/v0.3.2). You can ignore this changelog entry. + +A new version of the [mautrix-facebook](https://github.com/tulir/mautrix-facebook) bridge has been released. It's a full rewrite of its backend and the bridge now requires Postgres. New versions of the bridge can no longer run on SQLite. + +**TLDR**: if you're NOT using an [external Postgres server](docs/configuring-playbook-external-postgres.md) and have NOT forcefully kept the bridge on SQLite during [The big move to all-on-Postgres (potentially dangerous)](#the-big-move-to-all-on-postgres-potentially-dangerous), you will be automatically upgraded without manual intervention. All you need to do is send a `login` message to the Facebook bridge bot again. + +Whether this change requires your intervention depends mostly on: +- whether you're using an [external Postgres server](docs/configuring-playbook-external-postgres.md). If yes, then [you need to do something](#upgrade-path-for-people-running-an-external-postgres-server). +- or whether you've force-changed the bridge's database engine to SQLite (`matrix_mautrix_facebook_database_engine: 'sqlite'` in your `vars.yml`) some time in the past (likely during [The big move to all-on-Postgres (potentially dangerous)](#the-big-move-to-all-on-postgres-potentially-dangerous)). + +As already mentioned above, you most likely don't need to do anything. If you rerun the playbook and don't get an error, you've been automatically upgraded. Just send a `login` message to the Facebook bridge bot again. Otherwise, read below for a solution. + +### Upgrade path for people NOT running an external Postgres server (default for the playbook) + +If you're **not running an external Postgres server**, then this bridge either already works on Postgres for you, or you've intentionally kept it back on SQLite with custom configuration (`matrix_mautrix_facebook_database_engine: 'sqlite'` in your `vars.yml`) . + +Simply remove that custom configuration from your `vars.yml` file (if it's there) and re-run the playbook. It should upgrade you automatically. +You'll need to send a `login` message to the Facebook bridge bot again. + +Alternatively, [you can stay on SQLite for a little longer](#staying-on-sqlite-for-a-little-longer-temporary-solution). + +### Upgrade path for people running an external Postgres server + +For people using the internal Postgres server (the default for the playbook): +- we automatically create an additional `matrix_mautrix_facebook` Postgres database and credentials to access it +- we automatically adjust the bridge's `matrix_mautrix_facebook_database_*` variables to point the bridge to that Postgres database +- we use [pgloader](https://pgloader.io/) to automatically import the existing SQLite data for the bridge into the `matrix_mautrix_facebook` Postgres database + +If you are using an [external Postgres server](docs/configuring-playbook-external-postgres.md), unfortunately we currently can't do any of that for you. + +You have 3 ways to proceed: + +- contribute to the playbook to make this possible (difficult) +- or, do the migration "steps" manually: + - stop the bridge (`systemctl stop matrix-mautrix-facebook`) + - create a new `matrix_mautrix_facebook` Postgres database for it + - run [pgloader](https://pgloader.io/) manually (we import this bridge's data using default settings and it works well) + - define `matrix_mautrix_facebook_database_*` variables in your `vars.yml` file (credentials, etc.) - you can find their defaults in `roles/matrix/matrix-mautrix-facebook/defaults/main.yml` + - switch the bridge to Postgres (`matrix_mautrix_facebook_database_engine: 'postgres'` in your `vars.yml` file) + - re-run the playbook (`--tags=setup-all,start`) and ensure the bridge works (`systemctl status matrix-mautrix-facebook` and `journalctl -fu matrix-mautrix-facebook`) + - send a `login` message to the Facebook bridge bot again +- or, [stay on SQLite for a little longer (temporary solution)](#staying-on-sqlite-for-a-little-longer-temporary-solution) + +### Staying on SQLite for a little longer (temporary solution) + +To keep using this bridge with SQLite for a little longer (**not recommended**), use the following configuration in your `vars.yml` file: + +```yaml +# Force-change the database engine to SQLite. +matrix_mautrix_facebook_database_engine: 'sqlite' + +# Force-downgrade to the last bridge version which supported SQLite. +matrix_mautrix_facebook_docker_image: "{{ matrix_mautrix_facebook_docker_image_name_prefix }}tulir/mautrix-facebook:da1b4ec596e334325a1589e70829dea46e73064b" +``` + +If you do this, keep in mind that **you can't run this forever**. This SQLite-supporting bridge version is not getting any updates and will break sooner or later. The playbook will also drop support for SQLite at some point in the future. + + +# 2021-01-17 + +## matrix-corporal goes 2.0 + +[matrix-corporal v2 has been released](https://github.com/devture/matrix-corporal/releases/tag/2.0.0) and the playbook also supports it now. + +No manual intervention is required in the common case. + +The new [matrix-corporal](https://github.com/devture/matrix-corporal) version is also the first one to support Interactive Authentication. If you wish to enable that (hint: you should), you'll need to set up the [REST auth password provider](docs/configuring-playbook-rest-auth.md). There's more information in [our matrix-corporal docs](docs/configuring-playbook-matrix-corporal.md). + + +# 2021-01-14 + +## Moving from cronjobs to systemd timers + +We no longer use cronjobs for Let's Encrypt SSL renewal and `matrix-nginx-proxy`/`matrix-coturn` reloading. Instead, we've switched to systemd timers. + +The largest benefit of this is that we no longer require you to install a cron daemon, thus simplifying our install procedure. + +The playbook will migrate you from cronjobs to systemd timers automatically. This is just a heads up. + + +# 2021-01-08 + +## (Breaking Change) New SSL configuration + +SSL configuration (protocols, ciphers) can now be more easily controlled thanks to us making use of configuration presets. + +We define a few presets (old, intermediate, modern), following the [Mozilla SSL Configuration Generator](https://ssl-config.mozilla.org/#server=nginx). + +A new variable `matrix_nginx_proxy_ssl_preset` controls which preset is used (defaults to `"intermediate"`). + +Compared to before, this changes nginx's `ssl_prefer_server_ciphers` to `off` (used to default to `on`). It also add some more ciphers to the list, giving better performance on mobile devices, and removes some weak ciphers. More information in the [documentation](docs/configuring-playbook-nginx.md). + +To revert to the old behaviour, set the following variables: + +```yaml +matrix_nginx_proxy_ssl_ciphers: "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH" +matrix_nginx_proxy_ssl_prefer_server_ciphers: "on" +``` + +Just like before, you can still use your own custom protocols by specifying them in `matrix_nginx_proxy_ssl_protocols`. Doing so overrides the values coming from the preset. + + +# 2021-01-03 + +## Signal bridging support via mautrix-signal + +Thanks to [laszabine](https://github.com/laszabine)'s efforts, the playbook now supports bridging to [Signal](https://www.signal.org/) via the [mautrix-signal](https://github.com/tulir/mautrix-signal) bridge. See our [Setting up Mautrix Signal bridging](docs/configuring-playbook-bridge-mautrix-signal.md) documentation page for getting started. + +If you had installed the mautrix-signal bridge while its Pull Request was still work-in-progress, you can migrate your data to the new and final setup by referring to [this comment](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/686#issuecomment-753510789). + + +# 2020-12-23 + +## The big move to all-on-Postgres (potentially dangerous) + +**TLDR**: all your bridges (and other services) will likely be auto-migrated from SQLite/nedb to Postgres, hopefully without trouble. You can opt-out (see how below), if too worried about breakage. + +Until now, we've only used Postgres as a database for Synapse. All other services (bridges, bots, etc.) were kept simple and used a file-based database (SQLite or nedb). + +Since [this huge pull request](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/740), **all of our services now use Postgres by default**. Thanks to [Johanna Dorothea Reichmann](https://github.com/jdreichmann) for starting the work on it and for providing great input! + +Moving all services to Postgres brings a few **benefits** to us: + +- **improved performance** +- **improved compatibility**. Most bridges are deprecating SQLite/nedb support or offer less features when not on Postgres. +- **easier backups**. It's still some effort to take a proper backup (Postgres dump + various files, keys), but a Postgres dump now takes you much further. +- we're now **more prepared to introduce other services** that need a Postgres database - [Dendrite](https://github.com/matrix-org/dendrite), the [mautrix-signal](https://github.com/tulir/mautrix-signal) bridge (existing [pull request](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/686)), etc. + +### Key takeway + +- existing installations that use an [external Postgres](https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/docs/configuring-playbook-external-postgres.md) server should be unaffected (they remain on SQLite/nedb for all services, except Synapse) + +- for existing installations which use our integrated Postgres database server (`matrix-postgres`, which is the default), **we automatically migrate data** from SQLite/nedb to Postgres and **archive the database files** (`something.db` -> `something.db.backup`), so you can restore them if you need to go back (see how below). + +### Opting-out of the Postgres migration + +This is a **very large and somewhat untested change** (potentially dangerous), so **if you're not feeling confident/experimental, opt-out** of it for now. Still, it's the new default and what we (and various bridges) will focus on going forward, so don't stick to old ways for too long. + +You can remain on SQLite/nedb (at least for now) by adding a variable like this to your `vars.yml` file for each service you use: `matrix_COMPONENT_database_engine: sqlite` (e.g. `matrix_mautrix_facebook_database_engine: sqlite`). + +Some services (like `appservice-irc` and `appservice-slack`) don't use SQLite, so use `nedb`, instead of `sqlite` for them. + +### Going back to SQLite/nedb if things went wrong + +If you went with the Postgres migration and it went badly for you (some bridge not working as expected or not working at all), do this: + +- stop all services (`ansible-playbook -i inventory/hosts setup.yml --tags=stop`) +- SSH into the server and rename the old database files (`something.db.backup` -> `something.db`). Example: `mv /matrix/mautrix-facebook/data/mautrix-facebook.db.backup /matrix/mautrix-facebook/data/mautrix-facebook.db` +- switch the affected service back to SQLite (e.g. `matrix_mautrix_facebook_database_engine: sqlite`). Some services (like `appservice-irc` and `appservice-slack`) don't use SQLite, so use `nedb`, instead of `sqlite` for them. +- re-run the playbook (`ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start`) +- [get in touch](README.md#support) with us + +# 2020-12-11 + +## synapse-janitor support removed + +We've removed support for the unmaintained [synapse-janitor](https://github.com/xwiki-labs/synapse_scripts) script. There's been past reports of it corrupting the Synapse database. Since there hasn't been any new development on it and it doesn't seem too useful nowadays, there's no point in including it in the playbook. + +If you need to clean up or compact your database, consider using the Synapse Admin APIs directly. See our [Synapse maintenance](docs/maintenance-synapse.md) and [Postgres maintenance](docs/maintenance-postgres.md) documentation pages for more details. + + +## Docker 20.10 is here + +(No need to do anything special in relation to this. Just something to keep in mind) + +Docker 20.10 got released recently and your server will likely get it the next time you update. + +This is the first major Docker update in a long time and it packs a lot of changes. +Some of them introduced some breakage for us initially (see [here](https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/d08b27784f222effcbce2abf924bf07bbe0893be) and [here](https://github.com/spantaleev/matrix-docker-ansible-deploy/commit/7593d969e316cc0144bce378a5be58c76c2c37ee)), but it should be all good now. + + +# 2020-12-08 + +## openid APIs exposed by default on the federation port when federation disabled + +We've changed some defaults. People running with our default configuration (federation enabled), are not affected at all. + +If you are running an unfederated server (`matrix_synapse_federation_enabled: false`), this may be of interest to you. + +When federation is disabled, but ma1sd or Dimension are enabled, we'll now expose the `openid` APIs on the federation port. +These APIs are necessary for some ma1sd features to work. If you'd like to prevent this, you can: `matrix_synapse_federation_port_openid_resource_required: false`. + + +# 2020-11-27 + +## Recent Jitsi updates may require configuration changes + +We've recently [updated from Jitsi build 4857 to build 5142](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/719), which brings a lot of configuration changes. + +**If you use our default Jitsi settings, you won't have to do anything.** + +People who have [fine-tuned Jitsi](docs/configuring-playbook-jitsi.md#optional-fine-tune-jitsi) may find that some options got renamed now, others are gone and yet others still need to be defined in another way. + +The next time you run the playbook [installation](docs/installing.md) command, our validation logic will tell you if you're using some variables like that and will recommend a migration path for each one. + +Additionally, we've recently disabled transcriptions (`matrix_jitsi_enable_transcriptions: false`) and recording (`matrix_jitsi_enable_recording: false`) by default. These features did not work anyway, because we don't install the required dependencies for them (Jigasi and Jibri, respectively). If you've been somehow pointing your Jitsi installation to some manually installed Jigasi/Jibri service, you may need to toggle these flags back to enabled to have transcriptions and recordings working. + + +# 2020-11-23 + +## Breaking change matrix-sms-bridge + +Because of many problems using gammu as SMS provider, matrix-sms-bridge now uses (https://github.com/RebekkaMa/android-sms-gateway-server) by default. See (the docs)[./docs/configuring-playbook-bridge-matrix-bridge-sms.md] which new vars you need to add. + +If you are using this playbook to deploy matrix-sms-bridge and still really want to use gammu as SMS provider, we could possibly add support for both android-sms-gateway-server and gammu. + +# 2020-11-13 + +## Breaking change matrix-sms-bridge + +The new version of [matrix-sms-bridge](https://github.com/benkuly/matrix-sms-bridge) changed its database from neo4j to h2. You need to sync the bridge at the first start. Note that this only will sync rooms where the @smsbot:yourServer is member. For rooms without @smsbot:yourServer you need to kick and invite the telephone number **or** invite @smsbot:yourServer. + +1. Add the following to your `vars.yml` file: `matrix_sms_bridge_container_extra_arguments=['--env SPRING_PROFILES_ACTIVE=initialsync']` +2. Login to your host shell and remove old systemd file from your host: `rm /etc/systemd/system/matrix-sms-bridge-database.service` +2. Run `ansible-playbook -i inventory/hosts setup.yml --tags=setup-matrix-sms-bridge,start` +3. Login to your host shell and check the logs with `journalctl -u matrix-sms-bridge` until the sync finished. +4. Remove the var from the first step. +5. Run `ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start`. + +# 2020-11-10 + +## Dynamic DNS support + +Thanks to [Scott Crossen](https://github.com/scottcrossen), the playbook can now manage Dynamic DNS for you using [ddclient](https://ddclient.net/). + +To learn more, follow our [Dynamic DNS docs page](docs/configuring-playbook-dynamic-dns.md). + + +# 2020-10-28 + +## (Compatibility Break) https://matrix.DOMAIN/ now redirects to https://element.DOMAIN/ + +Until now, we used to serve a static page coming from Synapse at `https://matrix.DOMAIN/`. This page was not very useful to anyone. + +Since `matrix.DOMAIN` may be accessed by regular users in certain conditions, it's probably better to redirect them to a better place (e.g. to the [Element](docs/configuring-playbook-client-element.md) client). + +If Element is installed (`matrix_client_element_enabled: true`, which it is by default), we now redirect people to it, instead of showing them a Synapse static page. + +If you'd like to control where the redirect goes, use the `matrix_nginx_proxy_proxy_matrix_client_redirect_root_uri_to_domain` variable. +To restore the old behavior of not redirecting anywhere and serving the Synapse static page, set it to an empty value (`matrix_nginx_proxy_proxy_matrix_client_redirect_root_uri_to_domain: ""`). + + +# 2020-10-26 + +## (Compatibility Break) /_synapse/admin is no longer publicly exposed by default + +We used to expose the Synapse Admin APIs publicly (at `https://matrix.DOMAIN/_synapse/admin`). +These APIs require authentication with a valid access token, so it's not that big a deal to expose them. + +However, following [official Synapse's reverse-proxying recommendations](https://github.com/matrix-org/synapse/blob/master/docs/reverse_proxy.md#synapse-administration-endpoints), we're no longer exposing `/_synapse/admin` by default. + +If you'd like to restore restore the old behavior and expose `/_synapse/admin` publicly, you can use the following configuration (in your `vars.yml`): + +```yaml +matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_synapse_admin_api_enabled: true +``` + + +# 2020-10-02 + +## Minimum Ansible version raised to v2.7.0 + +We were claiming to support [Ansible](https://www.ansible.com/) v2.5.2 and higher, but issues like [#662](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/662) demonstrate that we need at least v2.7.0. + +If you've been using the playbook without getting any errors until now, you're probably on a version higher than that already (or you're not using the `matrix-ma1sd` and `matrix-client-element` roles). + +Our [Ansible docs page](docs/ansible.md) contains information on how to run a more up-to-date version of Ansible. + + +# 2020-10-01 + +## Postgres 13 support + +The playbook now installs [Postgres 13](https://www.postgresql.org/about/news/postgresql-13-released-2077/) by default. + +If you have have an existing setup, it's likely running on an older Postgres version (9.x, 10.x, 11.x or 12.x). You can easily upgrade by following the [upgrading PostgreSQL guide](docs/maintenance-postgres.md#upgrading-postgresql). + +# 2020-09-01 + +## matrix-registration support + +The playbook can now help you set up [matrix-registration](https://github.com/ZerataX/matrix-registration) - an application that lets you keep your Matrix server's registration private, but still allow certain users (those having a unique registration link) to register by themselves. + +See our [Setting up matrix-registration](docs/configuring-playbook-matrix-registration.md) documentation page to get started. + + +# 2020-08-21 + +## rust-synapse-compress-state support + +The playbook can now help you use [rust-synapse-compress-state](https://github.com/matrix-org/rust-synapse-compress-state) to compress the state groups in your Synapse database. + +See our [Compressing state with rust-synapse-compress-state](docs/maintenance-synapse.md#compressing-state-with-rust-synapse-compress-state) documentation page to get started. + + +# 2020-07-22 + +## Synapse Admin support + +The playbook can now help you set up [synapse-admin](https://github.com/Awesome-Technologies/synapse-admin). + +See our [Setting up Synapse Admin](docs/configuring-playbook-synapse-admin.md) documentation to get started. + + +# 2020-07-20 + +## matrix-reminder-bot support + +The playbook can now help you set up [matrix-reminder-bot](https://github.com/anoadragon453/matrix-reminder-bot). + +See our [Setting up matrix-reminder-bot](docs/configuring-playbook-bot-matrix-reminder-bot.md) documentation to get started. + + +# 2020-07-17 + +## (Compatibility Break) Riot is now Element + +As per the official announcement, [Riot has been rebraned to Element](https://element.io/blog/welcome-to-element/). + +The playbook follows suit. Existing installations have a few options for how to handle this. + +See our [Migrating to Element](docs/configuring-playbook-riot-web.md#migrating-to-element) documentation page for more details. + + +# 2020-07-03 + +## Steam bridging support via mx-puppet-steam + +Thanks to [Hugues Morisset](https://github.com/izissise)'s efforts, the playbook now supports bridging to [Steam](https://steamapp.com/) via the [mx-puppet-steam](https://github.com/icewind1991/mx-puppet-steam) bridge. See our [Setting up MX Puppet Steam bridging](docs/configuring-playbook-bridge-mx-puppet-steam.md) documentation page for getting started. + + +# 2020-07-01 + +## Discord bridging support via mx-puppet-discord + +Thanks to [Hugues Morisset](https://github.com/izissise)'s efforts, the playbook now supports bridging to [Discord](https://discordapp.com/) via the [mx-puppet-discord](https://github.com/Sorunome/mx-puppet-discord) bridge. See our [Setting up MX Puppet Discord bridging](docs/configuring-playbook-bridge-mx-puppet-discord.md) documentation page for getting started. + +**Note**: this is a new Discord bridge. The playbook still retains Discord bridging via [matrix-appservice-discord](docs/configuring-playbook-bridge-appservice-discord.md). You're free too use the bridge that serves you better, or even both (for different users and use-cases). + + +# 2020-06-30 + +## Instagram and Twitter bridging support + +Thanks to [Johanna Dorothea Reichmann](https://github.com/jdreichmann)'s efforts, the playbook now supports bridging to [Instagram](https://www.instagram.com/) via the [mx-puppet-instagram](https://github.com/Sorunome/mx-puppet-instagram) bridge. See our [Setting up MX Puppet Instagram bridging](docs/configuring-playbook-bridge-mx-puppet-instagram.md) documentation page for getting started. + +Thanks to [Tulir Asokan](https://github.com/tulir)'s efforts, the playbook now supports bridging to [Twitter](https://twitter.com/) via the [mx-puppet-twitter](https://github.com/Sorunome/mx-puppet-twitter) bridge. See our [Setting up MX Puppet Twitter bridging](docs/configuring-playbook-bridge-mx-puppet-twitter.md) documentation page for getting started. + + +# 2020-06-28 + +## (Post Mortem / fixed Security Issue) Re-enabling User Directory search powered by the ma1sd Identity Server + +User Directory search requests used to go to the ma1sd identity server by default, which queried its own stores and the Synapse database. + +ma1sd's [security issue](https://github.com/ma1uta/ma1sd/issues/44) has been fixed in version `2.4.0`, with [this commit](ma1uta/ma1sd@2bb5a734d11662b06471113cf3d6b4cee5e33a85). `ma1sd 2.4.0` is now the default version for this playbook. For more information on what happened, please check the mentioned issue. + +We are re-enabling user directory search with this update. Those who would like to keep it disabled can use this configuration: `matrix_nginx_proxy_proxy_matrix_user_directory_search_enabled: false` + +As always, re-running the playbook is enough to get the updated bits. + +# 2020-06-11 + +## SMS bridging requires db reset + +The current version of [matrix-sms-bridge](https://github.com/benkuly/matrix-sms-bridge) needs you to delete the database to work as expected. Just remove `/matrix/matrix-sms-bridge/database/*`. It also adds a new requried var `matrix_sms_bridge_default_region`. + +To reuse your existing rooms, invite `@smsbot:yourServer` to the room or write a message. You are also able to use automated room creation with telephonenumers by writing `sms send -t 01749292923 "Hello World"` in a room with `@smsbot:yourServer`. See [the docs](https://github.com/benkuly/matrix-sms-bridge) for more information. + +# 2020-06-05 + +## SMS bridging support + +Thanks to [benkuly](https://github.com/benkuly)'s efforts, the playbook now supports bridging to SMS (with one telephone number only) via [matrix-sms-bridge](https://github.com/benkuly/matrix-sms-bridge). + +See our [Setting up Matrix SMS bridging](docs/configuring-playbook-bridge-matrix-bridge-sms.md) documentation page for getting started. + + +# 2020-05-19 + +## (Compatibility Break / Security Issue) Disabling User Directory search powered by the ma1sd Identity Server + +User Directory search requests used to go to the ma1sd identity server by default, which queried its own stores and the Synapse database. + +ma1sd current has [a security issue](https://github.com/ma1uta/ma1sd/issues/44), which made it leak information about all users - including users created by bridges, etc. + +Until the issue gets fixed, we're making User Directory search not go to ma1sd by default. You **need to re-run the playbook and restart services to apply this workaround**. + +*If you insist on restoring the old behavior* (**which has a security issue!**), you *might* use this configuration: `matrix_nginx_proxy_proxy_matrix_user_directory_search_enabled: "{{ matrix_ma1sd_enabled }}"` + + +# 2020-04-28 + +## Newer IRC bridge (with potential breaking change) + +This upgrades matrix-appservice-irc from 0.14.1 to 0.16.0. Upstream +made a change to how you define manual mappings. If you added a +`mapping` to your configuration, you will need to update it accoring +to the [upstream +instructions](https://github.com/matrix-org/matrix-appservice-irc/blob/master/CHANGELOG.md#0150-2020-02-05). +If you did not include `mappings` in your configuration for IRC, no +change is necessary. `mappings` is not part of the default +configuration. + + +# 2020-04-23 + +## Slack bridging support + +Thanks to [Rodrigo Belem](https://github.com/rbelem)'s efforts, the playbook now supports bridging to [Slack](https://slack.com) via the [mx-puppet-slack](https://github.com/Sorunome/mx-puppet-slack) bridge. + +See our [Setting up MX Puppet Slack bridging](docs/configuring-playbook-bridge-mx-puppet-slack.md) documentation page for getting started. + + +# 2020-04-09 + +## Skype bridging support + +Thanks to [Rodrigo Belem](https://github.com/rbelem)'s efforts, the playbook now supports bridging to [Skype](https://www.skype.com) via the [mx-puppet-skype](https://github.com/Sorunome/mx-puppet-skype) bridge. + +See our [Setting up MX Puppet Skype bridging](docs/configuring-playbook-bridge-mx-puppet-skype.md) documentation page for getting started. + + +# 2020-04-05 + +## Private Jitsi support + +The [Jitsi support](#jitsi-support) we had landed a few weeks ago was working well, but it was always open to the whole world. + +Running such an open instance is not desirable to most people, so [teutat3s](https://github.com/teutat3s) has contributed support for making Jitsi use authentication. + +To make your Jitsi server more private, see the [configure internal Jitsi authentication and guests mode](docs/configuring-playbook-jitsi.md#optional-configure-internal-jitsi-authentication-and-guests-mode) section in our Jitsi documentation. + + +# 2020-04-03 + +## (Potential Backward Compatibility Break) ma1sd replaces mxisd + +Thanks to [Marcel Partap](https://github.com/eMPee584)'s efforts, the [mxisd](https://github.com/kamax-io/mxisd) identity server, which has been deprecated for a long time, has finally been replaced by [ma1sd](https://github.com/ma1uta/ma1sd), a compatible fork. + +**If you're using the default playbook configuration**, you don't need to do anything -- your mxisd installation will be replaced with ma1sd and all existing data will be migrated automatically the next time you run the playbook. + +**If you're doing something more special** (defining custom `matrix_mxisd_*` variables), the playbook will ask you to rename them to `matrix_ma1sd_*`. +You're also encouraged to test that ma1sd works well for such a more custom setup. + + +# 2020-03-29 + +## Archlinux support + +Thanks to [Christian Lupus](https://github.com/christianlupus)'s efforts, the playbook now supports installing to an [Archlinux](https://www.archlinux.org/) server. + + +# 2020-03-24 + +## Jitsi support + +The playbook can now (optionally) install the [Jitsi](https://jitsi.org/) video-conferencing platform and integrate it with [Riot](docs/configuring-playbook-riot-web.md). + +See our [Jitsi documentation page](docs/configuring-playbook-jitsi.md) to get started. + + +# 2020-03-15 + +## Raspberry Pi support + +Thanks to [Gergely Horváth](https://github.com/hooger)'s effort, the playbook supports installing to a Raspberry Pi server, for at least some of the services. + +Since most ready-made container images do not support that architecture, we achieve this by building images locally on the device itself. +See our [Self-building documentation page](docs/self-building.md) for how to get started. + + +# 2020-02-26 + +## Riot-web themes are here + +The playbook now makes it easy to install custom riot-web themes. + +To learn more, take a look at our [riot-web documentation on Themes](docs/configuring-playbook-riot-web.md#themes). + + +# 2020-02-24 + +## Customize the server name in Riot's login page + +You can now customize the server name string that Riot-web displays in its login page. + +These playbook variables, with these default values, have been added: + +``` +matrix_riot_web_default_server_name: "{{ matrix_domain }}" +``` + +The login page previously said "Sign in to your Matrix account on matrix.example.org" (the homeserver's domain name). It will now say "Sign in ... on example.org" (the server name) by default, or "Sign in ... on Our Server" if you set the variable to "Our Server". + +To support this, the config.json template is changed to use the configuration key `default_server_config` for setting the default HS/IS, and the new configuration key `server_name` is added in there. + + +# 2020-01-30 + +## Disabling TLSv1.1 + +To improve security, we've removed TLSv1.1 support from our default matrix-nginx-proxy configuration. + +If you need to support old clients, you can re-enable it with the following configuration: `matrix_nginx_proxy_ssl_protocols: "TLSv1.1 TLSv1.2 TLSv1.3"` + + +# 2020-01-21 + +## Postgres collation changes (action required!) + +By default, we've been using a UTF-8 collation for Postgres. This is known to cause Synapse some troubles (see the [relevant issue](https://github.com/matrix-org/synapse/issues/6722)) on systems that use [glibc](https://www.gnu.org/software/libc/). We run Postgres in an [Alpine Linux](https://alpinelinux.org/) container (which uses [musl](https://www.musl-libc.org/), and not glibc), so our users are likely not affected by the index corruption problem observed by others. + +Still, we might become affected in the future. In any case, it's imminent that Synapse will complain about databases which do not use a C collation. + +To avoid future problems, we recommend that you run the following command: + +``` +ansible-playbook -i inventory/hosts setup.yml --tags=upgrade-postgres --extra-vars='{"postgres_force_upgrade": true}' +``` + +It forces a [Postgres database upgrade](docs/maintenance-postgres.md#upgrading-postgresql), which would recreate your Postgres database using the proper (`C`) collation. If you are low on disk space, or run into trouble, refer to the Postgres database upgrade documentation page. + + +# 2020-01-14 + +## Added support for Appservice Webhooks + +Thanks to a contribution from [Björn Marten](https://github.com/tripleawwy) from [netresearch](https://www.netresearch.de/), the playbook can now install and configure [matrix-appservice-webhooks](https://github.com/turt2live/matrix-appservice-webhooks) for you. This bridge provides support for Slack-compatible webhooks. + +Learn more in [Setting up Appservice Webhooks](docs/configuring-playbook-bridge-appservice-webhooks.md). + + +# 2020-01-12 + +## Added support for automatic Double Puppeting for all Mautrix bridges + +Double Puppeting can now be easily enabled for all Mautrix bridges supported by the playbook (Facebook, Hangouts, Whatsapp, Telegram). + +This is possible due to those bridges' integration with [matrix-synapse-shared-secret-auth](https://github.com/devture/matrix-synapse-shared-secret-auth) - yet another component that this playbook can install for you. + +To get started, following the playbook's documentation for the bridge you'd like to configure. + + +# 2019-12-06 + +## Added support for an alternative method for using another webserver + +We have added support for making `matrix-nginx-proxy` not being so invasive, so that it would be easier to [use your own webserver](docs/configuring-playbook-own-webserver.md). + +The documentation has been updated with a **Method 2**, which might make "own webserver" setup easier in some cases (such as [reverse-proxying using Traefik](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/296)). + +**Existing users** are not affected by this and **don't need to change anything**. +The defaults are still the same (`matrix-nginx-proxy` obtaining SSL certificates and doing everything for you automatically). + + +# 2019-11-10 + +## Tightened security around room directory publishing + +As per this [advisory blog post](https://matrix.org/blog/2019/11/09/avoiding-unwelcome-visitors-on-private-matrix-servers), we've decided to change the default publishing rules for the Matrix room directory. + +Our general goal is to favor privacy and security when running personal (family & friends) and corporate homeservers. +Both of these likely benefit from having a more secure default of **not showing the room directory without authentication** and **not publishing the room directory over federation**. + +As with anything else, these new defaults can be overriden by changing the `matrix_synapse_allow_public_rooms_without_auth` and `matrix_synapse_allow_public_rooms_over_federation` variables, respectively. + + +# 2019-10-05 + +## Improved Postgres upgrading/importing + +Postgres [upgrading](docs/maintenance-postgres.md#upgrading-postgresql) and [importing](docs/importing-postgres.md) have been improved to add support for multiple databases and roles. + +Previously, the playbook would only take care of the `homeserver` database and `synapse` user. +We now back up and restore all databases and users on the Postgres server. + +For now, the playbook only uses that one database (`homeserver`) and that one single user (`synapse`), so it's all the same. +However, in the future, additional components besides Synapse may also make use the Postgres database server. +One such example is the [matrix-appservice-slack](https://github.com/matrix-org/matrix-appservice-slack) bridge, which strongly encourages use of Postgres in its v1.0 release. We are yet to upgrade to it. + +Additionally, Postgres [upgrading](docs/maintenance-postgres.md#upgrading-postgresql) now uses gzipped dump files by default, to minimize disk space usage. + + +# 2019-10-04 + +## Postgres 12 support + +The playbook now installs [Postgres 12](https://www.postgresql.org/about/news/1976/) by default. + +If you have have an existing setup, it's likely running on an older Postgres version (9.x, 10.x or 11.x). You can easily upgrade by following the [upgrading PostgreSQL guide](docs/maintenance-postgres.md#upgrading-postgresql). + + +# 2019-10-03 + +## Synapse 1.4.0 + +Synapse 1.4.0 [is out](https://matrix.org/blog/2019/10/03/synapse-1-4-0-released) with lots of changes related to privacy. + +Its new defaults (which we adopt as well) mean that certain old data will automatically get purged after a certain number of days. 1.4.0 automatically garbage collects redacted messages (defaults to 7 days) and removes unused IP and user agent information stored in the user_ips table (defaults to 30 days). If you'd like to preserve this data, we encourage you to look at the `redaction_retention_period` and `user_ips_max_age` options (controllable by the `matrix_synapse_redaction_retention_period` and `matrix_synapse_user_ips_max_age` playbook variables, respectively) before doing the upgrade. If you'd like to keep data indefinitely, set these variables to `null` (e.g. `matrix_synapse_redaction_retention_period: ~`). + +From now on the `trusted_key_servers` setting for Synapse is configurable. It still defaults to `matrix.org` just like it always has, but in a more explicit way now. If you'd like to use another trusted key server, adjust the `matrix_synapse_trusted_key_servers` playbook variable. + +Synapse 1.4.0 also changes lots of things related to identity server integration. +Because Synapse will now by default be responsible for validating email addresses for user accounts, running without an identity server looks more feasible. +We still [have concerns](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/275/files#r331104117) over disabling the identity server by default, so for now it remains enabled. + + +# 2019-09-09 + +## Synapse Simple Antispam support + +There have been lots of invite-spam attacks lately and [Travis](https://github.com/t2bot) has created a Synapse module ([synapse-simple-antispam](https://github.com/t2bot/synapse-simple-antispam)) to let people protect themselves. + +From now on, you can easily install and configure this spam checker module through the playbook. + +Learn more in [Setting up Synapse Simple Antispam](docs/configuring-playbook-synapse-simple-antispam.md). + + +# 2019-08-25 + +## Extensible Riot-web configuration + +Similarly to [Extensible Synapse configuration](#extensible-synapse-configuration) (below), Riot-web configuration is also extensible now. + +From now on, you can extend/override Riot-web's configuration by making use of the `matrix_riot_web_configuration_extension_json` variable. +This should be enough for most customization needs. + +If you need even more power, you can now also take full control and override `matrix_riot_web_configuration_default` (or `matrix_riot_web_configuration`) directly. + +Learn more in [Configuring Riot-web](docs/configuring-playbook-riot-web.md). + + +# 2019-08-22 + +## Extensible Synapse configuration + +Previously, we had to create custom Ansible variables for each and every Synapse setting. +This lead to too much effort (and configuration ugliness) to all of Synapse's settings, so naturally, not all features of Synapse could be controlled through the playbook. + +From now on, you can extend/override the Synapse server's configuration by making use of the `matrix_synapse_configuration_extension_yaml` variable. +This should be enough for most customization needs. + +If you need even more power, you can now also take full control and override `matrix_synapse_configuration` (or `matrix_synapse_configuration_yaml`) directly. + +Learn more here in [Configuring Synapse](docs/configuring-playbook-synapse.md). + + +# 2019-08-21 + +## Slack bridging support + +Thanks to the [great work](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/205) of [kingoftheconnors](https://github.com/kingoftheconnors) and [Stuart Mumford (Cadair)](https://github.com/Cadair), the playbook now supports bridging to [Slack](https://slack.com) via the [appservice-slack](https://github.com/matrix-org/matrix-appservice-slack) bridge. + +Additional details are available in [Setting up Appservice Slack bridging](docs/configuring-playbook-bridge-appservice-slack.md). + +## Google Hangouts bridging support + +Thanks to the [great work](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/251) of [Eduardo Beltrame (Munfred)](https://github.com/Munfred) and [Robbie D (microchipster)](https://github.com/microchipster), the playbook now supports bridging to [Google Hangouts](https://hangouts.google.com/) via the [mautrix-hangouts](https://mau.dev/tulir/mautrix-hangouts) bridge. + +Additional details are available in [Setting up Mautrix Hangouts bridging](docs/configuring-playbook-bridge-mautrix-hangouts.md). + + +# 2019-08-05 + +## Email2Matrix support + +Support for [Email2Matrix](https://github.com/devture/email2matrix) has been added. + +It's an optional feature that you can enable via the playbook. + +To learn more, see the [playbook's documentation on Email2Matrix](./docs/configuring-playbook-email2matrix.md). + + +# 2019-08-03 + +## Synapse logging level has been reduced to WARNING + +After [some discussion in our support room](https://matrix.to/#/!PukFFdIcHgtaaHZflT:devture.com/$156476852524179TBeKy:matrix.org?via=devture.com&via=matrix.org&via=librem.one), we've decided to change the default logging level for Synapse from `INFO` to `WARNING`. + +This greatly reduces the number of log messages that are being logged, leading to: + +- much less disk space dedicated to Synapse and thus, logs kept for longer +- easier to find some important `WARNING`, `ERROR` and `CRITICAL` messages, as they're not longer buried in thousands of non-important `INFO` messages + +If you'd like to track down an issue, you [can always increase the logging level as described here](./docs/maintenance-and-troubleshooting.md#increasing-synapse-logging). + + + +# 2019-07-08 + +## Synapse Maintenance docs and synapse-janitor support are available + +The playbook can now help you with Synapse's maintenance. + +There's a new documentation page about [Synapse maintenance](./docs/maintenance-synapse.md) and another section on [Postgres vacuuming](./docs/maintenance-postgres.md#vacuuming-postgresql). + +Among other things, if your Postgres database has grown significantly over time, you may wish to [ask the playbook to purge unused data with synapse-janitor](./docs/maintenance-synapse.md#purging-unused-data-with-synapse-janitor) for you. + + +## (BC Break) Rename run control variables + +Some internal playbook control variables have been renamed. + +This change **only affects people who run this playbook's roles from another playbook**. +If you're using this playbook as-is, you're not affected and don't need to do anything. + +The following variables have been renamed: + +- from `run_import_postgres` to `run_postgres_import` +- from `run_import_sqlite_db` to `run_postgres_import_sqlite_db` +- from `run_upgrade_postgres` to `run_postgres_upgrade` +- from `run_import_media_store` to `run_synapse_import_media_store` +- from `run_register_user` to `run_synapse_register_user` +- from `run_update_user_password` to `run_synapse_update_user_password` + + +# 2019-07-04 + +## Synapse no longer logs to text files + +Following what the official Synapse Docker image is doing ([#5565](https://github.com/matrix-org/synapse/pull/5565)) and what we've been doing for mostly everything installed by this playbook, **Synapse no longer logs to text files** (`/matrix/synapse/run/homeserver.log*`). + +From now on, Synapse would only log to console, which goes to systemd's journald. +To see Synapse's logs, execute: `journalctl -fu matrix-synapse` + +Because of this, the following variables have become obsolete and were removed: + +- `matrix_synapse_max_log_file_size_mb` +- `matrix_synapse_max_log_files_count` + +To prevent confusion, it'd be better if you delete all old files manually after you've upgraded (`rm -f /matrix/synapse/run/homeserver.log*`). + +Because Synapse is incredibly chatty when it comes to logging (here's [one such issue](https://github.com/matrix-org/synapse/issues/4751) describing the problem), if you're running an ancient distribution (like CentOS 7.0), be advised that systemd's journald default logging restrictions may not be high enough to capture all log messages generated by Synapse. This is especially true if you've got a busy (Synapse) server. We advise that you manually add `RateLimitInterval=0` and `RateLimitBurst=0` under `[Storage]` in the `/etc/systemd/journald.conf` file, followed by restarting the logging service (`systemctl restart systemd-journald`). + + +# 2019-06-27 + +## (BC Break) Discord bridge configuration is now entirely managed by the playbook + +Until now, the `config.yaml` file for the [Discord bridge](docs/configuring-playbook-bridge-appservice-discord.md) was managed by the playbook, but the `registration.yaml` file was not. + +From now on, the playbook will keep both configuration files sync for you. + +This means that if you were making manual changes to the `/matrix/appservice-discord/discord-registration.yaml` configuration file, those would be lost the next time you run the playbook. + +The bridge now stores configuration in a subdirectory (`/matrix/appservice-discord/config`). + +Likewise, data is now also stored in a subdirectory (`/matrix/appservice-discord/data`). When you run the playbook with an existing database file (`/matrix/appservice-discord/discord.db`), the playbook will stop the bridge and relocate the database file to the `./data` directory. There's no data-loss involved. You'll need to restart the bridge manually though (`--tags=start`). + +The main directory (`/matrix/appservice-discord`) may contain some leftover files (`user-store.db`, `room-store.db`, `config.yaml`, `discord-registration.yaml`, `invite_link`). These are no longer necessary and can be deleted manually. + +We're now following the default sample configuration for the Discord bridge. +If you need to override some values, define them in `matrix_appservice_discord_configuration_extension_yaml`. + + +# 2019-06-24 + +## (BC Break) WhatsApp bridge configuration is now entirely managed by the playbook + +Until now, configuration files for the [WhatsApp bridge](docs/configuring-playbook-bridge-mautrix-whatsapp.md) were created by the playbook initially, but never modified later on. + +From now on, the playbook will keep the configuration in sync for you. + +This means that if you were making manual changes to the `/matrix/mautrix-whatsapp/config.yaml` or `/matrix/mautrix-whatsapp/registration.yaml` configuration files, those would be lost the next time you run the playbook. + +The bridge now stores configuration in a subdirectory (`/matrix/mautrix-whatsapp/config`), so your old configuration remains in the base directory (`/matrix/mautrix-whatsapp`). +You need to migrate any manual changes over to the new `matrix_mautrix_whatsapp_configuration_extension_yaml` variable, so that the playbook would apply them for you. + +Likewise, data is now also stored in a subdirectory (`/matrix/mautrix-whatsapp/data`). When you run the playbook with an existing database file (`/matrix/mautrix-whatsapp/mautrix-whatsapp.db`), the playbook will stop the bridge and relocate the database file to the `./data` directory. There's no data-loss involved. You'll need to restart the bridge manually though (`--tags=start`). + +We're now following the default configuration for the WhatsApp bridge. + + +# 2019-06-20 + +## (BC Break) IRC bridge configuration is now entirely managed by the playbook + +Until now, configuration files for the [IRC bridge](docs/configuring-playbook-bridge-appservice-irc.md) were created by the playbook initially, but never modified later on. + +From now on, the playbook will keep the configuration in sync for you. + +This means that if you were making manual changes to the `/matrix/appservice-irc/config.yaml` or `/matrix/appservice-irc/registration.yaml` configuration files, those would be lost the next time you run the playbook. + +The bridge now stores configuration in a subdirectory (`/matrix/appservice-irc/config`), so your old configuration remains in the base directory (`/matrix/appservice-irc`). + +Previously, we asked people to configure bridged IRC servers by extending the bridge configuration (`matrix_appservice_irc_configuration_extension_yaml`). While this is still possible and will continue working forever, **we now recommend defining IRC servers in the easier to use `matrix_appservice_irc_ircService_servers` variable**. See [our IRC bridge documentation page](docs/configuring-playbook-bridge-appservice-irc.md) for an example. + +If you decide to continue using `matrix_appservice_irc_configuration_extension_yaml`, you might be interested to know that `ircService.databaseUri` and a few other keys now have default values in the base configuration (`matrix_appservice_irc_configuration_yaml`). You may wish to stop redefining those keys, unless you really intend to override them. You most likely only need to override `ircService.servers`. + +Bridge data (`passkey.pem` and database files) is now also stored in a subdirectory (`/matrix/appservice-irc/data`). +When you run the playbook with an existing `/matrix/appservice-irc/passkey.pem` file, the playbook will stop the bridge and relocate the passkey and database files (`rooms.db` and `users.db`) to the `./data` directory. There's no data-loss involved. You'll need to restart the bridge manually though (`--tags=start`). + + +# 2019-06-15 + +## (BC Break) Telegram bridge configuration is now entirely managed by the playbook + +Until now, configuration files for the [Telegram bridge](docs/configuring-playbook-bridge-mautrix-telegram.md) were created by the playbook initially, but never modified later on. + +From now on, the playbook will keep the configuration in sync for you. + +This means that if you were making manual changes to the `/matrix/mautrix-telegram/config.yaml` or `/matrix/mautrix-telegram/registration.yaml` configuration files, those would be lost the next time you run the playbook. + +The bridge now stores configuration in a subdirectory (`/matrix/mautrix-telegram/config`), so your old configuration remains in the base directory (`/matrix/mautrix-telegram`). +You need to migrate any manual changes over to the new `matrix_mautrix_telegram_configuration_extension_yaml` variable, so that the playbook would apply them for you. + +Likewise, data is now also stored in a subdirectory (`/matrix/mautrix-telegram/data`). When you run the playbook with an existing database file (`/matrix/mautrix-telegram/mautrix-telegram.db`), the playbook will stop the bridge and relocate the database file to the `./data` directory. There's no data-loss involved. You'll need to restart the bridge manually though (`--tags=start`). + +Also, we're now following the default configuration for the Telegram bridge, so some default configuration values are different: + +- `edits_as_replies` (used to be `false`, now `true`) - previously replies were not sent over to Matrix at all; ow they are sent over as a reply to the original message +- `inline_images` (used to be `true`, now `false`) - this has to do with captioned images. Inline-image (included caption) are said to exhibit troubles on Riot iOS. When `false`, the caption arrives on the Matrix side as a separate message. +- `authless_portals` (used to be `false`, now `true`) - creating portals from the Telegram side is now possible +- `whitelist_group_admins` (used to be `false`, now `true`) - allows Telegram group admins to use the bot commands + +If the new values are not to your liking, use `matrix_mautrix_telegram_configuration_extension_yaml` to specify an override (refer to `matrix_mautrix_telegram_configuration_yaml` to figure out which variable goes where). + + +# 2019-06-12 + +## Synapse v1.0 + +With [Synapse v1.0 now available](https://matrix.org/blog/2019/06/11/introducing-matrix-1-0-and-the-matrix-org-foundation) and most people being on at least Synapse v0.99, it's time to remove the `_matrix._tcp` DNS SRV record that we've been keeping for compatibility with old Synapse versions (<= 0.34). + +According to the [Server Discovery specification](https://matrix.org/docs/spec/server_server/r0.1.2.html#server-discovery), it's no harm to keep the DNS SRV record. But since it's not necessary for federating with the larger Matrix network anymore, you should be safe to get rid of it. + +**Note**: don't confuse the `_matrix._tcp` and `_matrix-identity._tcp` DNS SRV records. The latter, **must not** be removed. + +For completeness, we must say that using a `_matrix._tcp` [SRV record for Server Delegation](docs/howto-server-delegation.md#server-delegation-via-a-dns-srv-record-advanced) is still valid and useful for certain deployments. It's just that our guide recommends the [`/.well-known/matrix/server` Server Delegation method](docs/howto-server-delegation.md#server-delegation-via-a-well-known-file), due to its easier implementation when using this playbook. + +Besides this optional/non-urgent DNS change, assuming you're already on Synapse v0.99, upgrading to Synapse v1.0 should be as simple as [re-running the playbook](docs/maintenance-upgrading-services.md). + + +# 2019-06-07 + +## (BC Break) Facebook bridge configuration is now entirely managed by the playbook + +Until now, configuration files for the [Facebook bridge](docs/configuring-playbook-bridge-mautrix-facebook.md) were created by the playbook initially, but never modified later on. + +From now on, the playbook will keep the configuration in sync for you. + +This means that if you were making manual changes to the `/matrix/mautrix-facebook/config.yaml` or `/matrix/mautrix-facebook/registration.yaml` configuration files, those would be lost the next time you run the playbook. + +The bridge now stores configuration in a subdirectory (`/matrix/mautrix-facebook/config`), so your old configuration remains in the base directory (`/matrix/mautrix-facebook`). +You need to migrate any manual changes over to the new `matrix_mautrix_facebook_configuration_extension_yaml` variable, so that the playbook would apply them for you. + +Likewise, data is now also stored in a subdirectory (`/matrix/mautrix-facebook/data`). When you run the playbook with an existing database file (`/matrix/mautrix-facebook/mautrix-facebook.db`), the playbook will stop the bridge and relocate the database file to the `./data` directory. There's no data-loss involved. You'll need to restart the bridge manually though (`--tags=start`). + + +# 2019-05-25 + +## Support for exposing container ports publicly (not just to the host) + +Until now, various roles supported a `matrix_*_expose_port` variable, which would expose their container's port to the host. This was mostly useful for reverse-proxying manually (in case `matrix-nginx-proxy` was disabled). It could also be used for installing some playbook services (e.g. bridges, etc.) and wiring them to a separate (manual) Matrix setup. + +`matrix_*_expose_port` variables were not granular enough - sometimes they would expose one port, other times multiple. They also didn't provide control over **where** to expose (to which port number and to which network interface), because they would usually hardcode something like `127.0.0.1:8080`. + +All such variables have been superseded by a better (more flexible) way to do it. + +**Most** people (including those not using `matrix-nginx-proxy`), **don't need** to bother with this. + +Porting examples follow for people having more customized setups: + +- **from** `matrix_synapse_container_expose_client_api_port: true` **to** `matrix_synapse_container_client_api_host_bind_port: '127.0.0.1:8008'` + +- **from** `matrix_synapse_container_expose_federation_api_port: true` **to** `matrix_synapse_container_federation_api_plain_host_bind_port: '127.0.0.1:8048'` and possibly `matrix_synapse_container_federation_api_tls_host_bind_port: '8448'` + +- **from** `matrix_synapse_container_expose_metrics_port: true` **to** `matrix_synapse_container_metrics_api_host_bind_port: '127.0.0.1:9100'` + +- **from** `matrix_riot_web_container_expose_port: true` **to** `matrix_riot_web_container_http_host_bind_port: '127.0.0.1:8765'` + +- **from** `matrix_mxisd_container_expose_port: true` **to** `matrix_mxisd_container_http_host_bind_port: '127.0.0.1:8090'` + +- **from** `matrix_dimension_container_expose_port: true` **to** `matrix_dimension_container_http_host_bind_port: '127.0.0.1:8184'` + +- **from** `matrix_corporal_container_expose_ports: true` **to** `matrix_corporal_container_http_gateway_host_bind_port: '127.0.0.1:41080'` and possibly `matrix_corporal_container_http_api_host_bind_port: '127.0.0.1:41081'` + +- **from** `matrix_appservice_irc_container_expose_client_server_api_port: true` **to** `matrix_appservice_irc_container_http_host_bind_port: '127.0.0.1:9999'` + +- **from** `matrix_appservice_discord_container_expose_client_server_api_port: true` **to** `matrix_appservice_discord_container_http_host_bind_port: '127.0.0.1:9005'` + +As always, if you forget to remove usage of some outdated variable, the playbook will warn you. + + +# 2019-05-23 + +## (BC Break) Ansible 2.8 compatibility + +Thanks to [@danbob](https://github.com/danbob), the playbook now [supports the new Ansible 2.8](https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/187). + +A manual change is required to the `inventory/hosts` file, changing the group name from `matrix-servers` to `matrix_servers` (dash to underscore). + +To avoid doing it manually, run this: +- Linux: `sed -i 's/matrix-servers/matrix_servers/g' inventory/hosts` +- Mac: `sed -i '' 's/matrix-servers/matrix_servers/g' inventory/hosts` + + +# 2019-05-21 + +## Synapse no longer required + +The playbook no longer insists on installing [Synapse](https://github.com/matrix-org/synapse) via the `matrix-synapse` role. + +If you would prefer to install Synapse another way and just use the playbook to install other services, it should be possible (`matrix_synapse_enabled: false`). + +Note that it won't necessarily be the best experience, since the playbook wires things to Synapse by default. +If you're using your own Synapse instance (especially one not running in a container), you may have to override many variables to point them to the correct place. + +Having Synapse not be a required component potentially opens the door for installing alternative Matrix homeservers. + + +## Bridges are now separate from the Synapse role + +Bridges are no longer part of the `matrix-synapse` role. +Each bridge now lives in its own separate role (`roles/matrix/matrix-bridge-*`). + +These bridge roles are independent of the `matrix-synapse` role, so it should be possible to use them with a Synapse instance installed another way (not through the playbook). + + +## Renaming inconsistently-named Synapse variables + +For better consistency, the following variables have been renamed: + +- `matrix_enable_room_list_search` was renamed to `matrix_synapse_enable_room_list_search` +- `matrix_alias_creation_rules` was renamed to `matrix_synapse_alias_creation_rules` +- `matrix_nginx_proxy_matrix_room_list_publication_rulesdata_path` was renamed to `matrix_synapse_room_list_publication_rules` + + +# 2019-05-09 + +Besides a myriad of bug fixes and minor improvements, here are the more notable (bigger) features we can announce today. + +## Mautrix Facebook/Messenger bridging support + +The playbook now supports bridging with [Facebook](https://www.facebook.com/) by installing the [mautrix-facebook](https://github.com/tulir/mautrix-facebook) bridge. This playbook functionality is available thanks to [@izissise](https://github.com/izissise). + +Additional details are available in [Setting up Mautrix Facebook bridging](docs/configuring-playbook-bridge-mautrix-facebook.md). + +## mxisd Registration feature integration + +The playbook can now help you integrate with mxisd's [Registration](https://github.com/kamax-matrix/mxisd/blob/master/docs/features/registration.md) feature. + +Learn more in [mxisd-controlled Registration](docs/configuring-playbook-mxisd.md#mxisd-controlled-registration). + + +# 2019-04-16 + +## Caddy webserver examples + +If you prefer using the [Caddy](https://caddyserver.com/) webserver instead of our own integrated nginx, we now have examples for it in the [`examples/caddy`](examples/caddy) directory + +# 2019-04-10 + +## Goofys support for other S3-compatible object stores + +Until now, you could optionally host Synapse's media repository on Amazon S3, but we now also support [using other S3-compatible object stores](docs/configuring-playbook-s3.md), + + +# 2019-04-03 + +## Ansible >= 2.5 is required + +Due to recent playbook improvements and the fact that the world keeps turning, we're bumping the [version requirement for Ansible](docs/ansible.md#supported-ansible-versions) (2.4 -> 2.5). + +We've also started building our own Docker image of Ansible ([devture/ansible](https://hub.docker.com/r/devture/ansible/)), which is useful for people who can't upgrade their local Ansible installation (see [Using Ansible via Docker](docs/ansible.md#using-ansible-via-docker)). + + +# 2019-03-19 + +## TLS support for Coturn + +We've added TLS support to the Coturn TURN server installed by the playbook by default. +The certificates from the Matrix domain will be used for the Coturn server. + +This feature is enabled by default for new installations. +To make use of TLS support for your existing Matrix server's Coturn, make sure to rebuild both Coturn and Synapse: + +```bash +ansible-playbook -i inventory/hosts setup.yml --tags=setup-coturn,setup-synapse,start +``` + +People who have an extra firewall (besides the iptables firewall, which Docker manages automatically), will need to open these additional firewall ports: `5349/tcp` (TURN over TCP) and `5349/udp` (TURN over UDP). + +People who build their own custom playbook from our roles should be aware that: + +- the `matrix-coturn` role and actually starting Coturn (e.g. `--tags=start`), requires that certificates are already put in place. For this reason, it's usually a good idea to have the `matrix-coturn` role execute after `matrix-nginx-proxy` (which retrieves the certificates). + +- there are a few variables that can help you enable TLS support for Coturn. See the `matrix-coturn` section in [group_vars/matrix-servers](./group_vars/matrix-servers). + + +# 2019-03-12 + +## matrix-nginx-proxy support for serving the base domain + +If you don't have a dedicated server for your base domain and want to set up [Server Delegation via a well-known file](docs/howto-server-delegation.md#server-delegation-via-a-well-known-file), the playbook has got you covered now. + +It's now possible for the playbook to obtain an SSL certificate and serve the necessary files for Matrix Server Delegation on your base domain. +Take a look at the new [Serving the base domain](docs/configuring-playbook-base-domain-serving.md) documentation page. + + +## (BC break) matrix-nginx-proxy data variable renamed + +`matrix_nginx_proxy_data_path` was renamed to `matrix_nginx_proxy_base_path`. + +There's a new `matrix_nginx_proxy_data_path` variable, which has a different use-purpose now (it's a subdirectory of `matrix_nginx_proxy_base_path` and is meant for storing various data files). + + +# 2019-03-10 + +## Dimension Integration Manager support + +Thanks to [NullIsNot0](https://github.com/NullIsNot0), the playbook can now (optionally) install the [Dimension](https://dimension.t2bot.io/) Integration Manager. +To learn more, see the [Setting up Dimension](docs/configuring-playbook-dimension.md) documentation page. + + +# 2019-03-07 + +## Ability to customize mxisd's email templates + +Thanks to [Sylvia van Os](https://github.com/TheLastProject), mxisd's email templates can now be customized easily. +To learn more, see the [Customizing email templates](docs/configuring-playbook-mxisd.md#customizing-email-templates) documentation page. + + +# 2019-03-05 + +## Discord bridging support + +[@Lionstiger](https://github.com/Lionstiger) has done some great work adding Discord bridging support via [matrix-appservice-discord](https://github.com/Half-Shot/matrix-appservice-discord). +To learn more, see the [Setting up Appservice Discord bridging](docs/configuring-playbook-bridge-appservice-discord.md) documentation page. + + +# 2019-02-19 + +## Renaming variables + +The following playbook variables were renamed: + +- from `host_specific_hostname_identity` to `matrix_domain` +- from `hostname_identity` to `matrix_domain` +- from `hostname_matrix` to `matrix_server_fqn_matrix` +- from `hostname_riot` to `matrix_server_fqn_riot` +- from `host_specific_matrix_ssl_lets_encrypt_support_email` to `matrix_ssl_lets_encrypt_support_email` + +Doing that, we've simplified things, made names less confusing (hopefully) and moved all variable names under the `matrix_` prefix. + + +# 2019-02-16 + +## Riot v1.0.1 support + +You can now use the brand new and redesigned Riot. + +The new version no longer has a homepage by default, so we've also removed the custom homepage that we've been installing. + +However, we still provide you with hooks to install your own `home.html` file by specifying the `matrix_riot_web_embedded_pages_home_path` variable (used to be called `matrix_riot_web_homepage_template` before). + + +# 2019-02-14 + +## Synapse v0.99.1 + +As we're moving toward Synapse v1.0, things are beginning to stabilize. +Upgrading from v0.99.0 to v0.99.1 should be painless. + +If you've been overriding the default configuration so that you can terminate TLS at the Synapse side (`matrix_synapse_no_tls: false`), you'll now have to replace this custom configuration with `matrix_synapse_tls_federation_listener_enabled: true`. The `matrix_synapse_no_tls` variable is no more. + + +# 2019-02-06 + +## Synapse v0.99 support and preparation for Synapse v1.0 + +Matrix is undergoing a lot of changes as it matures towards Synapse v1.0. +The first step is the Synapse v0.99 transitional release, which this playbook now supports. + +If you've been using this playbook successfully until now, you'd be aware that we've been doing [Server Delegation](docs/howto-server-delegation.md) using a `_matrix._tcp` DNS SRV record (as per [Configuring DNS](docs/configuring-dns.md)). + +Due to changes related to certificate file requirements that will affect us at Synapse v1.0, we'll have to stop using a **`_matrix._tcp` DNS SRV record in the future** (when Synapse goes to v1.0 - around 5th of March 2019). We **still need to keep the SRV record for now**, for backward compatibility with older Synapse versions (lower than v0.99). + +**What you need to do now** is make use of this transitional Synapse v0.99 release to **prepare your federation settings for the future**. You have 2 choices to prepare yourself for compatibility with the future Synapse v1.0: + +- (recommended) set up [Server Delegation via a well-known file](docs/howto-server-delegation.md#server-delegation-via-a-well-known-file), unless you are affected by the [Downsides of well-known-based Server Delegation](docs/howto-server-delegation.md#downsides-of-well-known-based-server-delegation). If you had previously set up the well-known `client` file, depending on how you've done it, it may be that there is nothing new required of you (besides [upgrading](docs/maintenance-upgrading-services.md)). After upgrading, you can [run a self-check](docs/maintenance-checking-services.md), which will tell you if you need to do anything extra with regard to setting up [Server Delegation via a well-known file](docs/howto-server-delegation.md#server-delegation-via-a-well-known-file). After some time, when most people have upgraded to Synapse v0.99 and older releases have disappeared, be prepared to drop your `_matrix._tcp` SRV record. + +- (more advanced) if the [Downsides of well-known-based Server Delegation](docs/howto-server-delegation.md#downsides-of-well-known-based-server-delegation) are not to your liking, **as an alternative**, you can set up [Server Delegation via a DNS SRV record](docs/howto-server-delegation.md#server-delegation-via-a-dns-srv-record-advanced). In such a case, you get to keep using your existing `_matrix._tcp` DNS SRV record forever and need to NOT set up a `/.well-known/matrix/server` file. Don't forget that you need to do certificate changes though. Follow the guide at [Server Delegation via a DNS SRV record](docs/howto-server-delegation.md#server-delegation-via-a-dns-srv-record-advanced). + + +# 2019-02-01 + +## TLS v1.3 support + +Now that the [nginx Docker image](https://hub.docker.com/_/nginx) has [added support for TLS v1.3](https://github.com/nginxinc/docker-nginx/issues/190), we have enabled that protocol by default. + +When using: + +- the **integrated nginx server**: TLS v1.3 support might not kick in immediately, because the nginx version hasn't been bumped and you may have an older build of the nginx Docker image (currently `nginx:1.15.8-alpine`). Typically, we do not re-pull images that you already have. When the nginx version gets bumped in the future, everyone will get the update. Until then, you could manually force-pull the rebuilt Docker image by running this on the server: `docker pull nginx:1.15.8-alpine`. + +- **your own external nginx server**: if your external nginx server is too old, the new configuration we generate for you in `/matrix/nginx-proxy/conf.d/` might not work anymore, because it mentions `TLSv1.3` and your nginx version might not support that. You can adjust the SSL protocol list by overriding the `matrix_nginx_proxy_ssl_protocols` variable. Learn more in the documentation page for [Using your own webserver, instead of this playbook's nginx proxy](docs/configuring-playbook-own-webserver.md) + +- **another web server**: you don't need to do anything to accommodate this change + + +# 2019-01-31 + +## IRC bridging support + +[Devon Maloney (@Plailect)](https://github.com/Plailect) has done some great work bringing IRC bridging support via [matrix-appservice-irc](https://github.com/TeDomum/matrix-appservice-irc). +To learn more, see the [Setting up Appservice IRC](docs/configuring-playbook-bridge-appservice-irc.md) documentation page. + + +# 2019-01-29 + +## Running container processes as non-root, without capabilities and read-only + +To improve security, this playbook no longer starts container processes as the `root` user. +Most containers were dropping privileges anyway, but we were trusting them with `root` privileges until they would do that. +Not anymore -- container processes now start as a non-root user (usually `matrix`) from the get-go. + +For additional security, various capabilities are also dropped (see [why it's important](https://github.com/projectatomic/atomic-site/issues/203)) for all containers. + +Additionally, most containers now use a read-only filesystem (see [why it's important](https://www.projectatomic.io/blog/2015/12/making-docker-images-write-only-in-production/)). +Containers are given write access only to the directories they need to write to. + +A minor breaking change is the `matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size` variable having being renamed to `matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb` (note the `_mb` suffix). The new variable expects a number value (e.g. `25M` -> `25`). +If you weren't customizing this variable, this wouldn't affect you. + + +## matrix-mailer is now based on Exim, not Postfix + +While we would have preferred to stay with [Postfix](http://www.postfix.org/), we found out that it cannot run as a non-root user. +We've had to replace it with [Exim](https://www.exim.org/) (via the [devture/exim-relay](https://hub.docker.com/r/devture/exim-relay) container image). + +The internal `matrix-mailer` service (running in a container) now listens on port `8025` (used to be `587` before). +The playbook will update your Synapse and mxisd email settings to match (`matrix-mailer:587` -> `matrix-mailer:8025`). + +Using the [devture/exim-relay](https://hub.docker.com/r/devture/exim-relay) container image instead of [panubo/postfix](https://hub.docker.com/r/panubo/postfix/) also gives us a nice disk usage reduction (~200MB -> 8MB). + + +# 2019-01-17 + +## (BC Break) Making the playbook's roles more independent of one another + +The following change **affects people running a more non-standard setup** - external Postgres or using our roles in their own other playbook. +**Most users don't need to do anything**, besides becoming aware of the new glue variables file [`group_vars/matrix-servers`](group_vars/matrix-servers). + +Because people like using the playbook's components independently (outside of this playbook) and because it's much better for maintainability, we've continued working on separating them. +Still, we'd like to offer a turnkey solution for running a fully-featured Matrix server, so this playbook remains important for wiring up the various components. + +With the new changes, **all roles are now only dependent on the minimal `matrix-base` role**. They are no longer dependent among themselves. + +In addition, the following components can now be completely disabled (for those who want/need to): +- `matrix-coturn` by using `matrix_coturn_enabled: false` +- `matrix-mailer` by using `matrix_mailer_enabled: false` +- `matrix-postgres` by using `matrix_postgres_enabled: false` + +The following changes had to be done: + +- glue variables had to be introduced to the playbook, so it can wire together the various components. Those glue vars are stored in the [`group_vars/matrix-servers`](group_vars/matrix-servers) file. When overriding variables for a given component (role), you need to be aware of both the role defaults (`role/ROLE/defaults/main.yml`) and the role's corresponding section in the [`group_vars/matrix-servers`](group_vars/matrix-servers) file. + +- `matrix_postgres_use_external` has been superceeded by the more consistently named `matrix_postgres_enabled` variable and a few other `matrix_synapse_database_` variables. See the [Using an external PostgreSQL server (optional)](docs/configuring-playbook-external-postgres.md) documentation page for an up-to-date replacement. + +- Postgres tools (`matrix-postgres-cli` and `matrix-make-user-admin`) are no longer installed if you're not enabling the `matrix-postgres` role (`matrix_postgres_enabled: false`) + +- roles, being more independent now, are more minimal and do not do so much magic for you. People that are building their own playbook using our roles will definitely need to take a look at the [`group_vars/matrix-servers`](group_vars/matrix-servers) file and adapt their playbooks with the same (or similar) wiring logic. + + +# 2019-01-16 + +## Splitting the playbook into multiple roles + +For better maintainability, the playbook logic (which all used to reside in a single `matrix-server` role) +has been split out into a number of different roles: `matrix-synapse`, `matrix-postgres`, `matrix-riot-web`, `matrix-mxisd`, etc. (see the `roles/` directory). + +To keep the filesystem more consistent with this separation, the **Postgres data had to be relocated**. + +The default value of `matrix_postgres_data_path` was changed from `/matrix/postgres` to `/matrix/postgres/data`. The `/matrix/postgres` directory is what we consider a base path now (new variable `matrix_postgres_base_path`). **Your Postgres data files will automatically be relocated by the playbook** (`/matrix/postgres/*` -> `/matrix/postgres/data/`) when you run with `--tags=setup-all` (or `--tags=setup-postgres`). While this shouldn't cause data-loss, **it's better if you do a Postgres backup just in case**. You'd need to restart all services after this migration (`--tags=start`). + + +# 2019-01-11 + +## (BC Break) mxisd configuration changes + +To be more flexible and to support the upcoming [mxisd](https://github.com/kamax-io/mxisd) 1.3.0 (when it gets released), +we've had to redo how mxisd gets configured. + +The following variables are no longer supported by this playbook: + +- `matrix_mxisd_ldap_enabled` +- `matrix_mxisd_ldap_connection_host` +- `matrix_mxisd_ldap_connection_tls` +- `matrix_mxisd_ldap_connection_port` +- `matrix_mxisd_ldap_connection_baseDn` +- `matrix_mxisd_ldap_connection_baseDns` +- `matrix_mxisd_ldap_connection_bindDn` +- `matrix_mxisd_ldap_connection_bindDn` +- `matrix_mxisd_ldap_connection_bindPassword` +- `matrix_mxisd_ldap_filter` +- `matrix_mxisd_ldap_attribute_uid_type` +- `matrix_mxisd_ldap_attribute_uid_value` +- `matrix_mxisd_ldap_connection_bindPassword` +- `matrix_mxisd_ldap_attribute_name` +- `matrix_mxisd_ldap_attribute_threepid_email` +- `matrix_mxisd_ldap_attribute_threepid_msisdn` +- `matrix_mxisd_ldap_identity_filter` +- `matrix_mxisd_ldap_identity_medium` +- `matrix_mxisd_ldap_auth_filter` +- `matrix_mxisd_ldap_directory_filter` +- `matrix_mxisd_template_config` + +You are encouraged to use the `matrix_mxisd_configuration_extension_yaml` variable to define your own mxisd configuration additions and overrides. +Refer to the [default variables file](roles/matrix/matrix-mxisd/defaults/main.yml) for more information. + +This new way of configuring mxisd is beneficial because: + +- it lets us support all mxisd configuration options, as the playbook simply forwards them to mxisd without needing to care or understand them +- it lets you upgrade to newer mxisd versions and make use of their features, without us having to add support for them explicitly + + +# 2019-01-08 + +## (BC Break) Cronjob schedule no longer configurable + +Due to the way we manage cronjobs now, you can no longer configure the schedule they're invoked at. + +If you were previously using `matrix_ssl_lets_encrypt_renew_cron_time_definition` or `matrix_nginx_proxy_reload_cron_time_definition` +to set a custom schedule, you should note that these variables don't affect anything anymore. + +If you miss this functionality, please [open an Issue](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/new) and let us know about your use case! + + +# 2018-12-23 + +## (BC Break) More SSL certificate retrieval methods + +The playbook now lets you decide between 3 different SSL certificate retrieval methods: +- (default) obtaining free SSL certificates from Let's Encrypt +- generating self-signed SSL certificates +- managing SSL certificates manually + +Learn more in [Adjusting SSL certificate retrieval](docs/configuring-playbook-ssl-certificates.md). + +For people who use Let's Encrypt (mostly everyone, since it's the default), you'll also have to rename a variable in your configuration: + +- before: `host_specific_matrix_ssl_support_email` +- after: `host_specific_matrix_ssl_lets_encrypt_support_email` + + +## (BC Break) mxisd upgrade with multiple base DN support + +mxisd has bee upgraded to [version 1.2.2](https://github.com/kamax-matrix/mxisd/releases/tag/v1.2.2), which supports [multiple base DNs](https://github.com/kamax-matrix/mxisd/blob/v1.2.2/docs/stores/ldap.md#base). + +If you were configuring this playbook's `matrix_mxisd_ldap_connection_baseDn` variable until now (a string containing a single base DN), you'll need to change to configuring the `matrix_mxisd_ldap_connection_baseDns` variable (an array containing multiple base DNs). + +Example change: + +- before: `matrix_mxisd_ldap_connection_baseDn: OU=Users,DC=example,DC=org` +- after: `matrix_mxisd_ldap_connection_baseDns: ['OU=Users,DC=example,DC=org']` + + +# 2018-12-21 + +## Synapse 0.34.0 and Python 3 + +Synapse has been upgraded to 0.34.0 and now uses Python 3. +Based on feedback from others, running Synapse on Python 3 is supposed to decrease memory usage significantly (~2x). + + +# 2018-12-12 + +## Riot homepage customization + +You can now customize some parts of the Riot homepage (or even completely replace it with your own custom page). +See the `matrix_riot_web_homepage_` variables in `roles/matrix/matrix-riot-web/defaults/main.yml`. + + +# 2018-12-04 + +## mxisd extensibility + +The [LDAP identity store for mxisd](https://github.com/kamax-matrix/mxisd/blob/master/docs/stores/ldap.md) can now be configured easily using playbook variables (see the `matrix_mxisd_ldap_` variables in `roles/matrix/matrix-server/defaults/main.yml`). + + +# 2018-11-28 + +## More scripts + +* matrix-remove-all allows to uninstall everything with a single command +* matrix-make-user-admin allows to upgrade a user's privileges + +## LDAP auth support via matrix-synapse-ldap3 + +The playbook can now install and configure [LDAP auth support](https://github.com/matrix-org/matrix-synapse-ldap3) for you. + +Additional details are available in [Setting up the LDAP authentication password provider module](docs/configuring-playbook-ldap-auth.md). + + +# 2018-11-23 + +## Support for controlling public registration and room auto-join + +The playbook now lets you enable public registration for users (controlled via `matrix_synapse_enable_registration`). +By default, public registration is forbidden. + +You can also make people automatically get auto-joined to rooms (controlled via `matrix_synapse_auto_join_rooms`). + +## Support for changing the welcome user id (welcome bot) + +By default, `@riot-bot:matrix.org` is used to welcome newly registered users. +This can be changed to something else (or disabled) via the new `matrix_riot_web_welcome_user_id` variable. + + +# 2018-11-14 + +## Ability to set Synapse log levels + +The playbook now allows you to set the log levels used by Synapse. The default logging levels remain the same. + +You can now override following variables with any of the supported log levels listed here: https://docs.python.org/3/library/logging.html#logging-levels + +``` +matrix_synapse_log_level: "INFO" +matrix_synapse_storage_sql_log_level: "INFO" +matrix_synapse_root_log_level: "INFO" +``` + + +# 2018-11-03 + +## Customize parts of Riot's config + +You can now customize some parts of Riot's `config.json`. These playbook variables, with these default values, have been added: + +``` +matrix_riot_web_disable_custom_urls: true +matrix_riot_web_disable_guests: true +matrix_riot_web_integrations_ui_url: "https://scalar.vector.im/" +matrix_riot_web_integrations_rest_url: "https://scalar.vector.im/api" +matrix_riot_web_integrations_widgets_urls: "https://scalar.vector.im/api" +matrix_riot_web_integrations_jitsi_widget_url: "https://scalar.vector.im/api/widgets/jitsi.html" +``` + +This now allows you use a custom integrations manager like [Dimesion](https://dimension.t2bot.io). For example, if you wish to use the Dimension instance hosted at dimension.t2bot.io, you can set the following in your vars.yml file: + +``` +matrix_riot_web_integrations_ui_url: "https://dimension.t2bot.io/riot" +matrix_riot_web_integrations_rest_url: "https://dimension.t2bot.io/api/v1/scalar" +matrix_riot_web_integrations_widgets_urls: "https://dimension.t2bot.io/widgets" +matrix_riot_web_integrations_jitsi_widget_url: "https://dimension.t2bot.io/widgets/jitsi" +``` + +## SSL protocols used to serve Riot and Synapse + +There's now a new `matrix_nginx_proxy_ssl_protocols` playbook variable, which controls the SSL protocols used to serve Riot and Synapse. Its default value is `TLSv1.1 TLSv1.2`. This playbook previously used `TLSv1 TLSv1.1 TLSv1.2` to serve Riot and Synapse. + +You may wish to reenable TLSv1 if you need to access Riot in older browsers. + +Note: Currently the dockerized nginx doesn't support TLSv1.3. See https://github.com/nginxinc/docker-nginx/issues/190 for more details. + + +# 2018-11-01 + +## Postgres 11 support + +The playbook now installs [Postgres 11](https://www.postgresql.org/about/news/1894/) by default. + +If you have have an existing setup, it's likely running on an older Postgres version (9.x or 10.x). You can easily upgrade by following the [upgrading PostgreSQL guide](docs/maintenance-postgres.md#upgrading-postgresql). + + +## (BC Break) Renaming playbook variables + +Due to the large amount of features added to this playbook lately, to keep things manageable we've had to reorganize its configuration variables a bit. + +The following playbook variables were renamed: + +- from `matrix_docker_image_mxisd` to `matrix_mxisd_docker_image` +- from `matrix_docker_image_mautrix_telegram` to `matrix_mautrix_telegram_docker_image` +- from `matrix_docker_image_mautrix_whatsapp` to `matrix_mautrix_whatsapp_docker_image` +- from `matrix_docker_image_mailer` to `matrix_mailer_docker_image` +- from `matrix_docker_image_coturn` to `matrix_coturn_docker_image` +- from `matrix_docker_image_goofys` to `matrix_s3_goofys_docker_image` +- from `matrix_docker_image_riot` to `matrix_riot_web_docker_image` +- from `matrix_docker_image_nginx` to `matrix_nginx_proxy_docker_image` +- from `matrix_docker_image_synapse` to `matrix_synapse_docker_image` +- from `matrix_docker_image_postgres_v9` to `matrix_postgres_docker_image_v9` +- from `matrix_docker_image_postgres_v10` to `matrix_postgres_docker_image_v10` +- from `matrix_docker_image_postgres_latest` to `matrix_postgres_docker_image_latest` + + +# 2018-10-26 + +## Mautrix Whatsapp bridging support + +The playbook now supports bridging with [Whatsapp](https://www.whatsapp.com/) by installing the [mautrix-whatsapp](https://github.com/tulir/mautrix-whatsapp) bridge. This playbook functionality is available thanks to [@izissise](https://github.com/izissise). + +Additional details are available in [Setting up Mautrix Whatsapp bridging](docs/configuring-playbook-bridge-mautrix-whatsapp.md). + + +# 2018-10-25 + +## Support for controlling Matrix federation + +The playbook can now help you with [Controlling Matrix federation](docs/configuring-playbook-federation), should you wish to run a more private (isolated) server. + + +# 2018-10-24 + +## Disabling riot-web guests + +From now on, Riot's configuration setting `disable_guests` would be set to `true`. +The homeserver was rejecting guests anyway, so this is just a cosmetic change affecting Riot's UI. + + +# 2018-10-21 + +## Self-check maintenance command + +The playbook can now [check if services are configured correctly](docs/maintenance-checking-services.md). + + +# 2018-10-05 + +## Presence tracking made configurable + +The playbook can now enable/disable user presence-status tracking in Synapse, through the playbook's `matrix_synapse_use_presence` variable (having a default value of `true` - enabled). + +If users participate in large rooms with many other servers, disabling presence will decrease server load significantly. + + +# 2018-09-27 + +## Synapse Cache Factor made configurable + +The playbook now makes the Synapse cache factor configurable, through the playbook's `matrix_synapse_cache_factor` variable (having a default value of `0.5`). + +Changing that value allows you to potentially decrease RAM usage or to increase performance by caching more stuff. +Some information on it is available here: https://github.com/matrix-org/synapse#help-synapse-eats-all-my-ram + + +# 2018-09-26 + +## Disabling Docker container logging + +`--log-driver=none` is used for all Docker containers now. + +All these containers are started through systemd anyway and get logged in journald, so there's no need for Docker to be logging the same thing using the default `json-file` driver. Doing that was growing `/var/lib/docker/containers/..` infinitely until service/container restart. + +As a result of this, things like `docker logs matrix-synapse` won't work anymore. `journalctl -u matrix-synapse` is how one can see the logs. + + +# 2018-09-17 + +## Service discovery support + +The playbook now helps you set up [service discovery](https://matrix.org/docs/spec/client_server/r0.4.0.html#server-discovery) using a `/.well-known/matrix/client` file. + +Additional details are available in [Configuring service discovery via .well-known](docs/configuring-well-known.md). + + +## (BC Break) Renaming playbook variables + +The following playbook variables were renamed: + +- from `matrix_nginx_riot_web_data_path` to `matrix_riot_web_data_path` +- from `matrix_riot_web_default_identity_server_url` to `matrix_identity_server_url` + + +# 2018-09-07 + +## Mautrix Telegram bridging support + +The playbook now supports bridging with [Telegram](https://telegram.org/) by installing the [mautrix-telegram](https://github.com/tulir/mautrix-telegram) bridge. This playbook functionality is available thanks to [@izissise](https://github.com/izissise). + +Additional details are available in [Setting up Mautrix Telegram bridging](docs/configuring-playbook-bridge-mautrix-telegram.md). + + +## Events cache size increase and configurability for Matrix Synapse + +The playbook now lets you configure Matrix Synapse's `event_cache_size` configuration via the `matrix_synapse_event_cache_size` playbook variable. + +Previously, this value was hardcoded to `"10K"`. From now on, a more reasonable default of `"100K"` is used. + + +## Password-peppering support for Matrix Synapse + +The playbook now supports enabling password-peppering for increased security in Matrix Synapse via the `matrix_synapse_password_config_pepper` playbook variable. Using a password pepper is disabled by default (just like it used to be before this playbook variable got introduced) and is not to be enabled/disabled after initial setup, as that would invalidate all existing passwords. + + +## Statistics-reporting support for Matrix Synapse + +There's now a new `matrix_synapse_report_stats` playbook variable, which controls the `report_stats` configuration option for Matrix Synapse. It defaults to `false`, so no change is required to retain your privacy. + +If you'd like to start reporting statistics about your homeserver (things like number of users, number of messages sent, uptime, load, etc.) to matrix.org, you can turn on stats reporting. + + +# 2018-08-29 + +## Changing the way SSL certificates are retrieved + +We've been using [acmetool](https://github.com/hlandau/acme) (with the [willwill/acme-docker](https://hub.docker.com/r/willwill/acme-docker/) Docker image) until now. + +Due to the Docker image being deprecated, and things looking bleak for acmetool's support of the newer ACME v2 API endpoint, we've switched to using [certbot](https://certbot.eff.org/) (with the [certbot/certbot](https://hub.docker.com/r/certbot/certbot/) Docker image). + +Simply re-running the playbook will retrieve new certificates (via certbot) for you. +To ensure you don't leave any old files behind, though, you'd better do this: + +- `systemctl stop 'matrix*'` +- stop your custom webserver, if you're running one (only affects you if you've installed with `matrix_nginx_proxy_enabled: false`) +- `mv /matrix/ssl /matrix/ssl-acmetool-delete-later` +- re-run the playbook's [installation](docs/installing.md) +- possibly delete `/matrix/ssl-acmetool-delete-later` + + +# 2018-08-21 + +## Matrix Corporal support + +The playbook can now install and configure [matrix-corporal](https://github.com/devture/matrix-corporal) for you. + +Additional details are available in [Setting up Matrix Corporal](docs/configuring-playbook-matrix-corporal.md). + + +# 2018-08-20 + +## Matrix Synapse rate limit control variables + +The following new variables can now be configured to control Matrix Synapse's rate-limiting (default values are shown below). + +```yaml +matrix_synapse_rc_messages_per_second: 0.2 +matrix_synapse_rc_message_burst_count: 10.0 +``` + +## Shared Secret Auth support via matrix-synapse-shared-secret-auth + +The playbook can now install and configure [matrix-synapse-shared-secret-auth](https://github.com/devture/matrix-synapse-shared-secret-auth) for you. + +Additional details are available in [Setting up the Shared Secret Auth password provider module](docs/configuring-playbook-shared-secret-auth.md). + + +# 2018-08-17 + +## REST auth support via matrix-synapse-rest-auth + +The playbook can now install and configure [matrix-synapse-rest-auth](https://github.com/kamax-io/matrix-synapse-rest-auth) for you. + +Additional details are available in [Setting up the REST authentication password provider module](docs/configuring-playbook-rest-auth.md). + + +## Compression improvements + +Shifted Matrix Synapse compression from happening in the Matrix Synapse, +to happening in the nginx proxy that's in front of it. + +Additionally, `riot-web` also gets compressed now (in the nginx proxy), +which drops the initial page load's size from 5.31MB to 1.86MB. + + +## Disabling some unnecessary Synapse services + +The following services are not necessary, so they have been disabled: +- on the federation port (8448): the `client` service +- on the http port (8008, exposed over 443): the old Angular `webclient` and the `federation` service + +Federation runs only on the federation port (8448) now. +The Client APIs run only on the http port (8008) now. + + +# 2018-08-15 + +## mxisd Identity Server support + +The playbook now sets up an [mxisd](https://github.com/kamax-io/mxisd) Identity Server for you by default. +Additional details are available in [Adjusting mxisd Identity Server configuration](docs/configuring-playbook-mxisd.md). + + +# 2018-08-14 + +## Email-sending support + +The playbook now configures an email-sending service (postfix) by default. +Additional details are available in [Adjusting email-sending settings](docs/configuring-playbook-email.md). + +With this, Matrix Synapse is able to send email notifications for missed messages, etc. + + +# 2018-08-08 + + +## (BC Break) Renaming playbook variables + +The following playbook variables were renamed: + +- from `matrix_max_upload_size_mb` to `matrix_synapse_max_upload_size_mb` +- from `matrix_max_log_file_size_mb` to `matrix_synapse_max_log_file_size_mb` +- from `matrix_max_log_files_count` to `matrix_synapse_max_log_files_count` +- from `docker_matrix_image` to `matrix_docker_image_synapse` +- from `docker_nginx_image` to `matrix_docker_image_nginx` +- from `docker_riot_image` to `matrix_docker_image_riot` +- from `docker_goofys_image` to `matrix_docker_image_goofys` +- from `docker_coturn_image` to `matrix_docker_image_coturn` + +If you're overriding any of them in your `vars.yml` file, you'd need to change to the new names. + + +## Renaming Ansible playbook tag + +The command for executing the whole playbook has changed. +The `setup-main` tag got renamed to `setup-all`. + + +## Docker container linking + +Changed the way the Docker containers are linked together. The ones that need to communicate with others operate in a `matrix` network now and not in the default bridge network. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0ad25db --- /dev/null +++ b/LICENSE @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..24351a0 --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ +.PHONY: roles lint + +help: ## Show this help. + @grep -F -h "##" $(MAKEFILE_LIST) | grep -v grep | sed -e 's/\\$$//' | sed -e 's/##//' + +roles: ## Pull roles + rm -rf roles/galaxy + ansible-galaxy install -r requirements.yml -p roles/galaxy/ --force + ansible-galaxy collection install -r requirements.yml --force + +lint: ## Runs ansible-lint against all roles in the playbook + ansible-lint roles/matrix + ansible-lint roles/keycloak diff --git a/README.md b/README.md new file mode 100644 index 0000000..177c2a0 --- /dev/null +++ b/README.md @@ -0,0 +1,181 @@ +[![Support room on Matrix](https://img.shields.io/matrix/matrix-docker-ansible-deploy:devture.com.svg?label=%23matrix-docker-ansible-deploy%3Adevture.com&logo=matrix&style=for-the-badge&server_fqdn=matrix.devture.com)](https://matrix.to/#/#matrix-docker-ansible-deploy:devture.com) [![donate](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/s.pantaleev/donate) + +# Matrix (An open network for secure, decentralized communication) server setup using Ansible and Docker + +## Purpose + +This [Ansible](https://www.ansible.com/) playbook is meant to help you run your own [Matrix](http://matrix.org/) homeserver, along with the [various services](#supported-services) related to that. + +That is, it lets you join the Matrix network using your own `@:` identifier, all hosted on your own server (see [prerequisites](docs/prerequisites.md)). + +We run all services in [Docker](https://www.docker.com/) containers (see [the container images we use](docs/container-images.md)), which lets us have a predictable and up-to-date setup, across multiple supported distros (see [prerequisites](docs/prerequisites.md)) and [architectures](docs/alternative-architectures.md) (x86/amd64 being recommended). + +[Installation](docs/README.md) (upgrades) and some maintenance tasks are automated using [Ansible](https://www.ansible.com/) (see [our Ansible guide](docs/ansible.md)). + + +## Supported services + +Using this playbook, you can get the following list of services configured on your server. Basically, this playbook aims to get you up-and-running with all the necessities around Matrix, without you having to do anything else. + +**Note**: the list below is exhaustive. It includes optional or even some advanced components that you will most likely not need. +Sticking with the defaults (which install a subset of the above components) is the best choice, especially for a new installation. +You can always re-run the playbook later to add or remove components. + + +### Homeserver + +The homeserver is the backbone of your matrix system. Choose one from the following list. + +| Name | Default? | Description | Documentation | +| ---- | -------- | ----------- | ------------- | +| [Synapse](https://github.com/matrix-org/synapse) | ✓ | Storing your data and managing your presence in the [Matrix](http://matrix.org/) network | [Link](docs/configuring-playbook-synapse.md) | +| [Conduit](https://conduit.rs) | x | Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. Conduit is a lightweight open-source server implementation of the Matrix Specification with a focus on easy setup and low system requirements | [Link](docs/configuring-playbook-conduit.md) | +| [Dendrite](https://github.com/matrix-org/dendrite) | x | Storing your data and managing your presence in the [Matrix](http://matrix.org/) network. Dendrite is a second-generation Matrix homeserver written in Go, an alternative to Synapse. | [Link](docs/configuring-playbook-dendrite.md) | + +### Clients + +Web clients for matrix that you can host on your own domains. + +| Name | Default? | Description | Documentation | +| ---- | -------- | ----------- | ------------- | +[Element](https://app.element.io/) | ✓ | Web UI, which is configured to connect to your own Synapse server by default | [Link](docs/configuring-playbook-client-element.md) | +| [Hydrogen](https://github.com/vector-im/hydrogen-web) | x | Web client | [Link](docs/configuring-playbook-client-hydrogen.md) | +| [Cinny](https://github.com/ajbura/cinny) | x | Web client | [Link](docs/configuring-playbook-client-cinny.md) | + + + +### Server Components + +Services that run on the server to make the various parts of your installation work. + +| Name | Default? | Description | Documentation | +| ---- | -------- | ----------- | ------------- | +| [PostgreSQL](https://www.postgresql.org/)| ✓ | Database for Synapse. [Using an external PostgreSQL server](docs/configuring-playbook-external-postgres.md) is also possible. | [Link](docs/configuring-playbook-external-postgres.md) | +| [Coturn](https://github.com/coturn/coturn) | ✓ | STUN/TURN server for WebRTC audio/video calls | [Link](docs/configuring-playbook-turn.md) | +| [nginx](http://nginx.org/) | ✓ | Web server, listening on ports 80 and 443 - standing in front of all the other services. Using your own webserver [is possible](docs/configuring-playbook-own-webserver.md) | [Link](docs/configuring-playbook-nginx.md) | +| [Let's Encrypt](https://letsencrypt.org/) | ✓ | Free SSL certificate, which secures the connection to the Synapse server and the Element web UI | [Link](docs/configuring-playbook-ssl-certificates.md) | +| [ma1sd](https://github.com/ma1uta/ma1sd) | x | Matrix Identity Server | [Link](docs/configuring-playbook-ma1sd.md) +| [Exim](https://www.exim.org/) | ✓ | Mail server, through which all Matrix services send outgoing email (can be configured to relay through another SMTP server) | - | +| [Dimension](https://github.com/turt2live/matrix-dimension) | x | An open source integrations manager for matrix clients | [Link](docs/configuring-playbook-dimension.md) | +| [Sygnal](https://github.com/matrix-org/sygnal) | x | Push gateway | [Link](docs/configuring-playbook-sygnal.md) | +| [ntfy](https://ntfy.sh) | x | Push notifications server | [Link](docs/configuring-playbook-ntfy.md) | + + +### Authentication + +Extend and modify how users are authenticated on your homeserver. + +| Name | Default? | Description | Documentation | +| ---- | -------- | ----------- | ------------- | +| [matrix-synapse-rest-auth](https://github.com/ma1uta/matrix-synapse-rest-password-provider) (advanced) | x | REST authentication password provider module | [Link](docs/configuring-playbook-rest-auth.md) | +|[matrix-synapse-shared-secret-auth](https://github.com/devture/matrix-synapse-shared-secret-auth) (advanced) | x | Password provider module | [Link](docs/configuring-playbook-shared-secret-auth.md) | +| [matrix-synapse-ldap3](https://github.com/matrix-org/matrix-synapse-ldap3) (advanced) | x | LDAP Auth password provider module | [Link](configuring-playbook-ldap-auth.md) | +| [matrix-ldap-registration-proxy](https://gitlab.com/activism.international/matrix_ldap_registration_proxy) (advanced) | x | A proxy that handles Matrix registration requests and forwards them to LDAP. | [Link](docs/configuring-playbook-matrix-ldap-registration-proxy.md) | +| [matrix-registration](https://github.com/ZerataX/matrix-registration) | x | A simple python application to have a token based matrix registration | [Link](docs/configuring-playbook-matrix-registration.md) | + + +### File Storage + +Use alternative file storage to the default `media_store` folder. + +| Name | Default? | Description | Documentation | +| ---- | -------- | ----------- | ------------- | +| [Goofys](https://github.com/kahing/goofys) | x | [Amazon S3](https://aws.amazon.com/s3/) (or other S3-compatible object store) storage for Synapse's content repository (`media_store`) files | [Link](docs/configuring-playbook-s3-goofys.md) | +| [synapse-s3-storage-provider](https://github.com/matrix-org/synapse-s3-storage-provider) | x | [Amazon S3](https://aws.amazon.com/s3/) (or other S3-compatible object store) storage for Synapse's content repository (`media_store`) files | [Link](docs/configuring-playbook-s3.md) | + +### Bridges + +Bridges can be used to connect your matrix installation with third-party communication networks. + +| Name | Default? | Description | Documentation | +| ---- | -------- | ----------- | ------------- | +[mautrix-discord](https://github.com/mautrix/discord) | x | Bridge for bridging your Matrix server to [Discord](https://discord.com/) | [Link](docs/configuring-playbook-bridge-mautrix-discord.md) | +| [mautrix-telegram](https://github.com/mautrix/telegram) | x | Bridge for bridging your Matrix server to [Telegram](https://telegram.org/) | [Link](docs/configuring-playbook-bridge-mautrix-telegram.md) | +| [mautrix-whatsapp](https://github.com/mautrix/whatsapp) | x | Bridge for bridging your Matrix server to [WhatsApp](https://www.whatsapp.com/) | [Link](docs/configuring-playbook-bridge-mautrix-whatsapp.md) | +| [mautrix-facebook](https://github.com/mautrix/facebook) | x | Bridge for bridging your Matrix server to [Facebook](https://facebook.com/) | [Link](docs/configuring-playbook-bridge-mautrix-facebook.md) | +| [mautrix-twitter](https://github.com/mautrix/twitter) | x | Bridge for bridging your Matrix server to [Twitter](https://twitter.com/) | [Link](docs/configuring-playbook-bridge-mautrix-twitter.md) | +| [mautrix-hangouts](https://github.com/mautrix/hangouts) | x | Bridge for bridging your Matrix server to [Google Hangouts](https://en.wikipedia.org/wiki/Google_Hangouts) | [Link](docs/configuring-playbook-bridge-mautrix-hangouts.md) | +| [mautrix-googlechat](https://github.com/mautrix/googlechat) | x | Bridge for bridging your Matrix server to [Google Chat](https://en.wikipedia.org/wiki/Google_Chat) | [Link](docs/configuring-playbook-bridge-mautrix-googlechat.md) | +| [mautrix-instagram](https://github.com/mautrix/instagram) | x | Bridge for bridging your Matrix server to [Instagram](https://instagram.com/) | [Link](docs/configuring-playbook-bridge-mautrix-instagram.md) | +| [mautrix-signal](https://github.com/mautrix/signal) | x | Bridge for bridging your Matrix server to [Signal](https://www.signal.org/) | [Link](docs/configuring-playbook-bridge-mautrix-signal.md) | +| [beeper-linkedin](https://github.com/beeper/linkedin) | x | Bridge for bridging your Matrix server to [LinkedIn](https://www.linkedin.com/) | [Link](docs/configuring-playbook-bridge-beeper-linkedin.md) | +| [matrix-appservice-irc](https://github.com/matrix-org/matrix-appservice-irc) | x | Bridge for bridging your Matrix server to [IRC](https://wikipedia.org/wiki/Internet_Relay_Chat) | [Link](docs/configuring-playbook-bridge-appservice-irc.md) | +| [matrix-appservice-discord](https://github.com/Half-Shot/matrix-appservice-discord) | x | Bridge for bridging your Matrix server to [Discord](https://discordapp.com/) | [Link](docs/configuring-playbook-bridge-appservice-discord.md) | +| [matrix-appservice-slack](https://github.com/matrix-org/matrix-appservice-slack) | x | Bridge for bridging your Matrix server to [Slack](https://slack.com/) | [Link](docs/configuring-playbook-bridge-appservice-slack.md) | +| [matrix-appservice-webhooks](https://github.com/turt2live/matrix-appservice-webhooks) | x | Bridge for slack compatible webhooks ([ConcourseCI](https://concourse-ci.org/), [Slack](https://slack.com/) etc. pp.) | [Link](docs/configuring-playbook-bridge-appservice-webhooks.md) | +| [matrix-hookshot](https://github.com/Half-Shot/matrix-hookshot) | x | Bridge for bridging Matrix to generic webhooks and multiple project management services, such as GitHub, GitLab, Figma, and Jira in particular | [Link](docs/configuring-playbook-bridge-hookshot.md) | +| [matrix-sms-bridge](https://github.com/benkuly/matrix-sms-bridge) | x | Bridge for bridging your Matrix server to SMS | [Link](docs/configuring-playbook-bridge-matrix-bridge-sms.md) | +| [Heisenbridge](https://github.com/hifi/heisenbridge) | x | Bridge for bridging your Matrix server to IRC bouncer-style | [Link](docs/configuring-playbook-bridge-heisenbridge.md) | +| [go-skype-bridge](https://github.com/kelaresg/go-skype-bridge) | x | Bridge for bridging your Matrix server to [Skype](https://www.skype.com) | [Link](docs/configuring-playbook-bridge-go-skype-bridge.md) | +| [mx-puppet-slack](https://hub.docker.com/r/sorunome/mx-puppet-slack) | x | Bridge for bridging your Matrix server to [Slack](https://slack.com) | [Link](docs/configuring-playbook-bridge-mx-puppet-slack.md) | +| [mx-puppet-instagram](https://github.com/Sorunome/mx-puppet-instagram) | x | Bridge for Instagram-DMs ([Instagram](https://www.instagram.com/)) | [Link](docs/configuring-playbook-bridge-mx-puppet-instagram.md) | +| [mx-puppet-twitter](https://github.com/Sorunome/mx-puppet-twitter) | x | Bridge for Twitter-DMs ([Twitter](https://twitter.com/)) | [Link](docs/configuring-playbook-bridge-mx-puppet-twitter.md) | +| [mx-puppet-discord](https://github.com/matrix-discord/mx-puppet-discord) | x | Bridge for [Discord](https://discordapp.com/) | [Link](docs/configuring-playbook-bridge-mx-puppet-discord.md) | +| [mx-puppet-groupme](https://gitlab.com/xangelix-pub/matrix/mx-puppet-groupme) | x | Bridge for [GroupMe](https://groupme.com/) | [Link](docs/configuring-playbook-bridge-mx-puppet-groupme.md) | +| [mx-puppet-steam](https://github.com/icewind1991/mx-puppet-steam) | x | Bridge for [Steam](https://steamapp.com/) | [Link](docs/configuring-playbook-bridge-mx-puppet-steam.md) | +| [Email2Matrix](https://github.com/devture/email2matrix) | x | Bridge for relaying email messages to Matrix rooms | [Link](docs/configuring-playbook-email2matrix.md) | + + +### Bots + +Bots provide various additional functionality to your installation. + +| Name | Default? | Description | Documentation | +| ---- | -------- | ----------- | ------------- | +| [matrix-reminder-bot](https://github.com/anoadragon453/matrix-reminder-bot) | x | Bot for scheduling one-off & recurring reminders and alarms | [Link](docs/configuring-playbook-bot-matrix-reminder-bot.md) | +| [matrix-registration-bot](https://github.com/moan0s/matrix-registration-bot) | x | Bot for invitations by creating and managing registration tokens | [Link](docs/configuring-playbook-bot-matrix-registration-bot.md) | +| [maubot](https://github.com/maubot/maubot) | x | A plugin-based Matrix bot system | [Link](docs/configuring-playbook-bot-maubot.md) | +| [honoroit](https://gitlab.com/etke.cc/honoroit) | x | A helpdesk bot | [Link](docs/configuring-playbook-bot-honoroit.md) | +| [Postmoogle](https://gitlab.com/etke.cc/postmoogle) | x | Email to matrix bot | [Link](docs/configuring-playbook-bot-postmoogle.md) | +| [Go-NEB](https://github.com/matrix-org/go-neb) | x | A multi functional bot written in Go | [Link](docs/configuring-playbook-bot-go-neb.md) | +| [Mjolnir](https://github.com/matrix-org/mjolnir) | x | A moderation tool for Matrix | [Link](docs/configuring-playbook-bot-mjolnir.md) | +| [Buscarron](https://gitlab.com/etke.cc/buscarron) | x | Web forms (HTTP POST) to matrix | [Link](docs/configuring-playbook-bot-buscarron.md) | + +### Administration + +Services that help you in administrating and monitoring your matrix installation. + + +| Name | Default? | Description | Documentation | +| ---- | -------- | ----------- | ------------- | +| [synapse-admin](https://github.com/Awesome-Technologies/synapse-admin) | x | A web UI tool for administrating users and rooms on your Matrix server | [Link](docs/configuring-playbook-synapse-admin.md) | +| Metrics and Graphs | x | Consists of the [Prometheus](https://prometheus.io) time-series database server, the Prometheus [node-exporter](https://prometheus.io/docs/guides/node-exporter/) host metrics exporter, and the [Grafana](https://grafana.com/) web UI | [Link](docs/configuring-playbook-prometheus-grafana.md) | +| [Borg](https://borgbackup.org) | x | Backups | [Link](docs/configuring-playbook-backup-borg.md) | + +### Misc + +Various services that don't fit any other category. + +| Name | Default? | Description | Documentation | +| ---- | -------- | ----------- | ------------- | +| [synapse-simple-antispam](https://github.com/t2bot/synapse-simple-antispam) (advanced) | x | A spam checker module | [Link](docs/configuring-playbook-synapse-simple-antispam.md) | +| [Matrix Corporal](https://github.com/devture/matrix-corporal) (advanced) | x | Reconciliator and gateway for a managed Matrix server | [Link](docs/configuring-playbook-matrix-corporal.md) | +| [Etherpad](https://etherpad.org) | x | An open source collaborative text editor | [Link](docs/configuring-playbook-etherpad.md) | +| [Jitsi](https://jitsi.org/) | x | An open source video-conferencing platform | [Link](docs/configuring-playbook-jitsi.md) | +| [Cactus Comments](https://cactus.chat) | x | A federated comment system built on matrix | [Link](docs/configuring-playbook-cactus-comments.md) | + + +## Installation + +To configure and install Matrix on your own server, follow the [README in the docs/ directory](docs/README.md). + + +## Changes + +This playbook evolves over time, sometimes with backward-incompatible changes. + +When updating the playbook, refer to [the changelog](CHANGELOG.md) to catch up with what's new. + + +## Support + +- Matrix room: [#matrix-docker-ansible-deploy:devture.com](https://matrix.to/#/#matrix-docker-ansible-deploy:devture.com) + +- IRC channel: `#matrix-docker-ansible-deploy` on the [Libera Chat](https://libera.chat/) IRC network (irc.libera.chat:6697) + +- GitHub issues: [spantaleev/matrix-docker-ansible-deploy/issues](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues) + + +## Services by the community + +- [etke.cc](https://etke.cc) - matrix-docker-ansible-deploy and system stuff "as a service". That service will create your matrix homeserver on your domain and server (doesn't matter if it's cloud provider or on an old laptop in the corner of your room), (optional) maintains it (server's system updates, cleanup, security adjustments, tuning, etc.; matrix homeserver updates & maintenance) and (optional) provide full-featured email service for your domain diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 0000000..360ce15 --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,6 @@ +[defaults] +retry_files_enabled = False +stdout_callback = yaml + +[connection] +pipelining = True diff --git a/collections/requirements.yml b/collections/requirements.yml new file mode 100644 index 0000000..483ed15 --- /dev/null +++ b/collections/requirements.yml @@ -0,0 +1,4 @@ +--- +collections: + - name: community.general + - name: community.docker diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..77c5099 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,39 @@ +# Table of Contents + +- [FAQ](faq.md) - lots of questions and answers. Jump to [Prerequisites](prerequisites.md) to avoid reading too much and to just start a guided installation. + +- [Prerequisites](prerequisites.md) - go here to a guided installation using this Ansible playbook + +- [Configuring your DNS server](configuring-dns.md) + +- [Getting this playbook's source code](getting-the-playbook.md) + +- [Configuring the playbook](configuring-playbook.md) + +- [Installing](installing.md) + +- **Importing data from another server installation** + + - [Importing an existing SQLite database (from another Synapse installation)](importing-synapse-sqlite.md) (optional) + + - [Importing an existing Postgres database (from another installation)](importing-postgres.md) (optional) + + - [Importing `media_store` data files from an existing Synapse installation](importing-synapse-media-store.md) (optional) + +- [Registering users](registering-users.md) + +- [Updating users passwords](updating-users-passwords.md) + +- [Configuring service discovery via .well-known](configuring-well-known.md) + +- [Maintenance / checking if services work](maintenance-checking-services.md) + +- [Maintenance / upgrading services](maintenance-upgrading-services.md) + +- [Maintenance / Synapse](maintenance-synapse.md) + +- [Maintenance / PostgreSQL](maintenance-postgres.md) + +- [Maintenance and Troubleshooting](maintenance-and-troubleshooting.md) + +- [Uninstalling](uninstalling.md) diff --git a/docs/alternative-architectures.md b/docs/alternative-architectures.md new file mode 100644 index 0000000..0865de1 --- /dev/null +++ b/docs/alternative-architectures.md @@ -0,0 +1,18 @@ +# Alternative architectures + +As stated in the [Prerequisites](prerequisites.md), currently only `amd64` (`x86_64`) is fully supported. + +The playbook automatically determines the target server's architecture (the `matrix_architecture` variable) to be one of the following: + +- `amd64` (`x86_64`) +- `arm32` +- `arm64` + +Some tools and container images can be built on the host or other measures can be used to install on that architecture. + + +## Implementation details + +For `amd64`, prebuilt container images (see the [container images we use](container-images.md)) are used for all components (except [Hydrogen](configuring-playbook-client-hydrogen.md), which goes through self-building). + +For other architecture (`arm64`, `arm32`), components which have a prebuilt image make use of it. If the component is not available for the specific architecture, [self-building](self-building.md) will be used. Not all components support self-building though, so your mileage may vary. diff --git a/docs/ansible.md b/docs/ansible.md new file mode 100644 index 0000000..2212228 --- /dev/null +++ b/docs/ansible.md @@ -0,0 +1,121 @@ + +# Running this playbook + +This playbook is meant to be run using [Ansible](https://www.ansible.com/). + +Ansible typically runs on your local computer and carries out tasks on a remote server. +If your local computer cannot run Ansible, you can also run Ansible on some server somewhere (including the server you wish to install to). + + +## Supported Ansible versions + +To manually check which version of Ansible you're on, run: `ansible --version`. + +For the **best experience**, we recommend getting the **latest version of Ansible available**. + +We're not sure what's the minimum version of Ansible that can run this playbook successfully. +The lowest version that we've confirmed (on 2022-11-26) to be working fine is: `ansible-core` (`2.11.7`) combined with `ansible` (`4.10.0`). + +If your distro ships with an Ansible version older than this, you may run into issues. Consider [Upgrading Ansible](#upgrading-ansible) or [using Ansible via Docker](#using-ansible-via-docker). + + +## Upgrading Ansible + +Depending on your distribution, you may be able to upgrade Ansible in a few different ways: + +- by using an additional repository (PPA, etc.), which provides newer Ansible versions. See instructions for [CentOS](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#installing-ansible-on-rhel-centos-or-fedora), [Debian](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#installing-ansible-on-debian), or [Ubuntu](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#installing-ansible-on-ubuntu) on the Ansible website. + +- by removing the Ansible package (`yum remove ansible` or `apt-get remove ansible`) and installing via [pip](https://pip.pypa.io/en/stable/installation/) (`pip install ansible`). + +If using the `pip` method, do note that the `ansible-playbook` binary may not be on the `$PATH` (https://linuxconfig.org/linux-path-environment-variable), but in some more special location like `/usr/local/bin/ansible-playbook`. You may need to invoke it using the full path. + + +**Note**: Both of the above methods are a bad way to run system software such as Ansible. +If you find yourself needing to resort to such hacks, please consider reporting a bug to your distribution and/or switching to a sane distribution, which provides up-to-date software. + + +## Using Ansible via Docker + +Alternatively, you can run Ansible inside a Docker container (powered by the [devture/ansible](https://hub.docker.com/r/devture/ansible/) Docker image). + +This ensures that you're using a very recent Ansible version, which is less likely to be incompatible with the playbook. + +You can either [run Ansible in a container on the Matrix server itself](#running-ansible-in-a-container-on-the-matrix-server-itself) or [run Ansible in a container on another computer (not the Matrix server)](#running-ansible-in-a-container-on-another-computer-not-the-matrix-server). + + +### Running Ansible in a container on the Matrix server itself + +To run Ansible in a (Docker) container on the Matrix server itself, you need to have a working Docker installation. +Docker is normally installed by the playbook, so this may be a bit of a chicken and egg problem. To solve it: + +- you **either** need to install Docker manually first. Follow [the upstream instructions](https://docs.docker.com/engine/install/) for your distribution and consider setting `matrix_playbook_docker_installation_enabled: false` in your `vars.yml` file, to prevent the playbook from installing Docker +- **or** you need to run the playbook in another way (e.g. [Running Ansible in a container on another computer (not the Matrix server)](#running-ansible-in-a-container-on-another-computer-not-the-matrix-server)) at least the first time around + +Once you have a working Docker installation on the server, **clone the playbook** somewhere on the server and configure it as per usual (`inventory/hosts`, `inventory/host_vars/..`, etc.), as described in [configuring the playbook](configuring-playbook.md). + +You would then need to add `ansible_connection=community.docker.nsenter` to the host line in `inventory/hosts`. This tells Ansible to connect to the "remote" machine by switching Linux namespaces with [nsenter](https://man7.org/linux/man-pages/man1/nsenter.1.html), instead of using SSH. +Alternatively, you can leave your `inventory/hosts` as is and specify the connection type in **each** `ansible-playbook` call you do later, like this: `ansible-playbook --connection=community.docker.nsenter ...` + +Run this from the playbook's directory: + +```bash +docker run -it --rm \ +--privileged \ +--pid=host \ +-w /work \ +-v `pwd`:/work \ +--entrypoint=/bin/sh \ +docker.io/devture/ansible:2.13.6-r0 +``` + +Once you execute the above command, you'll be dropped into a `/work` directory inside a Docker container. +The `/work` directory contains the playbook's code. + +First, consider running `git config --global --add safe.directory /work` to [resolve directory ownership issues](#resolve-directory-ownership-issues). + +Finally, you can execute `ansible-playbook ...` (or `ansible-playbook --connection=community.docker.nsenter ...`) commands as per normal now. + + +### Running Ansible in a container on another computer (not the Matrix server) + +Run this from the playbook's directory: + +```bash +docker run -it --rm \ +-w /work \ +-v `pwd`:/work \ +-v $HOME/.ssh/id_rsa:/root/.ssh/id_rsa:ro \ +--entrypoint=/bin/sh \ +docker.io/devture/ansible:2.13.6-r0 +``` + +The above command tries to mount an SSH key (`$HOME/.ssh/id_rsa`) into the container (at `/root/.ssh/id_rsa`). +If your SSH key is at a different path (not in `$HOME/.ssh/id_rsa`), adjust that part. + +Once you execute the above command, you'll be dropped into a `/work` directory inside a Docker container. +The `/work` directory contains the playbook's code. + +First, consider running `git config --global --add safe.directory /work` to [resolve directory ownership issues](#resolve-directory-ownership-issues). + +Finally, you execute `ansible-playbook ...` commands as per normal now. + + +#### If you don't use SSH keys for authentication + +If you don't use SSH keys for authentication, simply remove that whole line (`-v $HOME/.ssh/id_rsa:/root/.ssh/id_rsa:ro`). +To authenticate at your server using a password, you need to add a package. So, when you are in the shell of the ansible docker container (the previously used `docker run -it ...` command), run: +```bash +apk add sshpass +``` +Then, to be asked for the password whenever running an `ansible-playbook` command add `--ask-pass` to the arguments of the command. + + +#### Resolve directory ownership issues + +Because you're `root` in the container running Ansible and this likely differs fom the owner (your regular user account) of the playbook directory outside of the container, certain playbook features which use `git` locally may report warnings such as: + +> fatal: unsafe repository ('/work' is owned by someone else) +> To add an exception for this directory, call: +> git config --global --add safe.directory /work + +These errors can be resolved by making `git` trust the playbook directory by running `git config --global --add safe.directory /work` diff --git a/docs/configuring-captcha.md b/docs/configuring-captcha.md new file mode 100644 index 0000000..173b34f --- /dev/null +++ b/docs/configuring-captcha.md @@ -0,0 +1,52 @@ +(Adapted from the [upstream project](https://github.com/matrix-org/synapse/blob/develop/docs/CAPTCHA_SETUP.md)) + +# Overview +Captcha can be enabled for this home server. This file explains how to do that. +The captcha mechanism used is Google's [ReCaptcha](https://www.google.com/recaptcha/). This requires API keys from Google. If your homeserver is Dendrite then [hCapcha](https://www.hcaptcha.com) can be used instead. + +## ReCaptcha + +### Getting keys + +Requires a site/secret key pair from: + + + +Must be a reCAPTCHA **v2** key using the "I'm not a robot" Checkbox option + +### Setting ReCaptcha keys + +Once registered as above, set the following values: + +```yaml +# for Synapse +matrix_synapse_enable_registration_captcha: true +matrix_synapse_recaptcha_public_key: 'YOUR_SITE_KEY' +matrix_synapse_recaptcha_private_key: 'YOUR_SECRET_KEY' + +# for Dendrite +matrix_dendrite_client_api_enable_registration_captcha: true +matrix_dendrite_client_api_recaptcha_public_key: 'YOUR_SITE_KEY' +matrix_dendrite_client_api_recaptcha_private_key: 'YOUR_SECRET_KEY' +``` + +## hCaptcha + +### Getting keys + +Requires a site/secret key pair from: + + + +### Setting hCaptcha keys + +```yaml +matrix_dendrite_client_api_enable_registration_captcha: true +matrix_dendrite_client_api_recaptcha_public_key: 'YOUR_SITE_KEY' +matrix_dendrite_client_api_recaptcha_private_key: 'YOUR_SECRET_KEY' + +matrix_dendrite_client_api_recaptcha_siteverify_api: 'https://hcaptcha.com/siteverify' +matrix_dendrite_client_api_recaptcha_api_js_url: 'https://js.hcaptcha.com/1/api.js' +matrix_dendrite_client_api_recaptcha_form_field: 'h-captcha-response' +matrix_dendrite_client_api_recaptcha_sitekey_class: 'h-captcha' +``` diff --git a/docs/configuring-dns.md b/docs/configuring-dns.md new file mode 100644 index 0000000..d7ccf17 --- /dev/null +++ b/docs/configuring-dns.md @@ -0,0 +1,95 @@ +# Configuring your DNS server + +To set up Matrix on your domain, you'd need to do some DNS configuration. + +To use an identifier like `@:`, you don't actually need +to install anything on the actual `` server. + +You do, however need to instruct the Matrix network that Matrix services for `` are delegated +over to `matrix.`. +As we discuss in [Server Delegation](howto-server-delegation.md), there are 2 different ways to set up such delegation: + +- either by serving a `https:///.well-known/matrix/server` file (from the base domain!) +- or by using a `_matrix._tcp` DNS SRV record (don't confuse this with the `_matrix-identity._tcp` SRV record described below) + +This playbook mostly discusses the well-known file method, because it's easier to manage with regard to certificates. +If you decide to go with the alternative method ([Server Delegation via a DNS SRV record (advanced)](howto-server-delegation.md#server-delegation-via-a-dns-srv-record-advanced)), please be aware that the general flow that this playbook guides you through may not match what you need to do. + +## DNS settings for services enabled by default + +| Type | Host | Priority | Weight | Port | Target | +| ----- | ---------------------------- | -------- | ------ | ---- | ---------------------- | +| A | `matrix` | - | - | - | `matrix-server-IP` | +| CNAME | `element` | - | - | - | `matrix.` | + +Be mindful as to how long it will take for the DNS records to propagate. + +If you are using Cloudflare DNS, make sure to disable the proxy and set all records to `DNS only`. Otherwise, fetching certificates will fail. + +When you're done configuring DNS, proceed to [Configuring the playbook](configuring-playbook.md). + +## DNS settings for optional services/features + +| Used by component | Type | Host | Priority | Weight | Port | Target | +| ----------------------------------------------------------------------------------------------------------------------- | ----- | ------------------------------ | -------- | ------ | ---- | --------------------------- | +| [ma1sd](configuring-playbook-ma1sd.md) identity server | SRV | `_matrix-identity._tcp` | 10 | 0 | 443 | `matrix.` | +| [Dimension](configuring-playbook-dimension.md) integration server | CNAME | `dimension` | - | - | - | `matrix.` | +| [Jitsi](configuring-playbook-jitsi.md) video-conferencing platform | CNAME | `jitsi` | - | - | - | `matrix.` | +| [Prometheus/Grafana](configuring-playbook-prometheus-grafana.md) monitoring system | CNAME | `stats` | - | - | - | `matrix.` | +| [Go-NEB](configuring-playbook-bot-go-neb.md) bot | CNAME | `goneb` | - | - | - | `matrix.` | +| [Sygnal](configuring-playbook-sygnal.md) push notification gateway | CNAME | `sygnal` | - | - | - | `matrix.` | +| [ntfy](configuring-playbook-ntfy.md) push notifications server | CNAME | `ntfy` | - | - | - | `matrix.` | +| [Etherpad](configuring-playbook-etherpad.md) collaborative text editor | CNAME | `etherpad` | - | - | - | `matrix.` | +| [Hydrogen](configuring-playbook-client-hydrogen.md) web client | CNAME | `hydrogen` | - | - | - | `matrix.` | +| [Cinny](configuring-playbook-client-cinny.md) web client | CNAME | `cinny` | - | - | - | `matrix.` | +| [Buscarron](configuring-playbook-bot-buscarron.md) helpdesk bot | CNAME | `buscarron` | - | - | - | `matrix.` | +| [Postmoogle](configuring-playbook-bot-postmoogle.md)/[Email2Matrix](configuring-playbook-email2matrix.md) email bridges | MX | `matrix` | 10 | 0 | - | `matrix.` | +| [Postmoogle](configuring-playbook-bot-postmoogle.md) email bridge | TXT | `matrix` | - | - | - | `v=spf1 ip4: -all` | +| [Postmoogle](configuring-playbook-bot-postmoogle.md) email bridge | TXT | `_dmarc.matrix` | - | - | - | `v=DMARC1; p=quarantine;` | +| [Postmoogle](configuring-playbook-bot-postmoogle.md) email bridge | TXT | `postmoogle._domainkey.matrix` | - | - | - | get it from `!pm dkim` | + +When setting up a SRV record, if you are asked for a service and protocol instead of a hostname split the host value from the table where the period is. For example use service as `_matrix-identity` and protocol as `_tcp`. + +## Subdomains setup + +As the table above illustrates, you need to create 2 subdomains (`matrix.` and `element.`) and point both of them to your new server's IP address (DNS `A` record or `CNAME` record is fine). + +The `element.` subdomain may be necessary, because this playbook installs the [Element](https://github.com/vector-im/element-web) web client for you. +If you'd rather instruct the playbook not to install Element (`matrix_client_element_enabled: false` when [Configuring the playbook](configuring-playbook.md) later), feel free to skip the `element.` DNS record. + +The `dimension.` subdomain may be necessary, because this playbook could install the [Dimension integrations manager](http://dimension.t2bot.io/) for you. Dimension installation is disabled by default, because it's only possible to install it after the other Matrix services are working (see [Setting up Dimension](configuring-playbook-dimension.md) later). If you do not wish to set up Dimension, feel free to skip the `dimension.` DNS record. + +The `jitsi.` subdomain may be necessary, because this playbook could install the [Jitsi video-conferencing platform](https://jitsi.org/) for you. Jitsi installation is disabled by default, because it may be heavy and is not a core required component. To learn how to install it, see our [Jitsi](configuring-playbook-jitsi.md) guide. If you do not wish to set up Jitsi, feel free to skip the `jitsi.` DNS record. + +The `stats.` subdomain may be necessary, because this playbook could install [Grafana](https://grafana.com/) and setup performance metrics for you. Grafana installation is disabled by default, it is not a core required component. To learn how to install it, see our [metrics and graphs guide](configuring-playbook-prometheus-grafana.md). If you do not wish to set up Grafana, feel free to skip the `stats.` DNS record. It is possible to install Prometheus without installing Grafana, this would also not require the `stats.` subdomain. + +The `goneb.` subdomain may be necessary, because this playbook could install the [Go-NEB](https://github.com/matrix-org/go-neb) bot. The installation of Go-NEB is disabled by default, it is not a core required component. To learn how to install it, see our [configuring Go-NEB guide](configuring-playbook-bot-go-neb.md). If you do not wish to set up Go-NEB, feel free to skip the `goneb.` DNS record. + +The `sygnal.` subdomain may be necessary, because this playbook could install the [Sygnal](https://github.com/matrix-org/sygnal) push gateway. The installation of Sygnal is disabled by default, it is not a core required component. To learn how to install it, see our [configuring Sygnal guide](configuring-playbook-sygnal.md). If you do not wish to set up Sygnal (you probably don't, unless you're also developing/building your own Matrix apps), feel free to skip the `sygnal.` DNS record. + +The `ntfy.` subdomain may be necessary, because this playbook could install the [ntfy](https://ntfy.sh/) UnifiedPush-compatible push notifications server. The installation of ntfy is disabled by default, it is not a core required component. To learn how to install it, see our [configuring ntfy guide](configuring-playbook-ntfy.md). If you do not wish to set up ntfy, feel free to skip the `ntfy.` DNS record. + +The `etherpad.` subdomain may be necessary, because this playbook could install the [Etherpad](https://etherpad.org/) a highly customizable open source online editor providing collaborative editing in really real-time. The installation of etherpad is disabled by default, it is not a core required component. To learn how to install it, see our [configuring etherpad guide](configuring-playbook-etherpad.md). If you do not wish to set up etherpad, feel free to skip the `etherpad.` DNS record. + +The `hydrogen.` subdomain may be necessary, because this playbook could install the [Hydrogen](https://github.com/vector-im/hydrogen-web) web client. The installation of Hydrogen is disabled by default, it is not a core required component. To learn how to install it, see our [configuring Hydrogen guide](configuring-playbook-client-hydrogen.md). If you do not wish to set up Hydrogen, feel free to skip the `hydrogen.` DNS record. + +The `cinny.` subdomain may be necessary, because this playbook could install the [Cinny](https://github.com/ajbura/cinny) web client. The installation of cinny is disabled by default, it is not a core required component. To learn how to install it, see our [configuring cinny guide](configuring-playbook-client-cinny.md). If you do not wish to set up cinny, feel free to skip the `cinny.` DNS record. + +The `buscarron.` subdomain may be necessary, because this playbook could install the [buscarron](https://gitlab.com/etke.cc/buscarron) bot. The installation of buscarron is disabled by default, it is not a core required component. To learn how to install it, see our [configuring buscarron guide](configuring-playbook-bot-buscarron.md). If you do not wish to set up buscarron, feel free to skip the `buscarron.` DNS record. + +## `_matrix-identity._tcp` SRV record setup + +To make the [ma1sd](https://github.com/ma1uta/ma1sd) Identity Server (which this playbook may optionally install for you) enable its federation features, set up an SRV record that looks like this: +- Name: `_matrix-identity._tcp` (use this text as-is) +- Content: `10 0 443 matrix.` (replace `` with your own) + +This is an optional feature for the optionally-installed [ma1sd service](configuring-playbook-ma1sd.md). See [ma1sd's documentation](https://github.com/ma1uta/ma1sd/wiki/mxisd-and-your-privacy#choices-are-never-easy) for information on the privacy implications of setting up this SRV record. + +Note: This `_matrix-identity._tcp` SRV record for the identity server is different from the `_matrix._tcp` that can be used for Synapse delegation. See [howto-server-delegation.md](howto-server-delegation.md) for more information about delegation. + +When you're done with the DNS configuration and ready to proceed, continue with [Getting the playbook](getting-the-playbook.md). + +## `_dmarc`, `postmoogle._domainkey` TXT and `matrix` MX records setup + +To make the [postmoogle](configuring-playbook-bot-postmoogle.md) email bridge enable its email sending features, you need to configure +SPF (TXT), DMARC (TXT), DKIM (TXT) and MX records diff --git a/docs/configuring-playbook-backup-borg.md b/docs/configuring-playbook-backup-borg.md new file mode 100644 index 0000000..7beabec --- /dev/null +++ b/docs/configuring-playbook-backup-borg.md @@ -0,0 +1,81 @@ +# Setting up borg backup (optional) + +The playbook can install and configure [borgbackup](https://www.borgbackup.org/) with [borgmatic](https://torsion.org/borgmatic/) for you. +BorgBackup is a deduplicating backup program with optional compression and encryption. +That means your daily incremental backups can be stored in a fraction of the space and is safe whether you store it at home or on a cloud service. + +You will need a remote server where borg will store the backups. There are hosted, borg compatible solutions available, such as [BorgBase](https://www.borgbase.com). + +The backup will run based on `matrix_backup_borg_schedule` var (systemd timer calendar), default: 4am every day. + +By default, if you're using the integrated Postgres database server (as opposed to [an external Postgres server](configuring-playbook-external-postgres.md)), Borg backups will also include dumps of your Postgres database. An alternative solution for backing up the Postgres database is [postgres backup](configuring-playbook-postgres-backup.md). If you decide to go with another solution, you can disable Postgres-backup support for Borg using the `matrix_backup_borg_postgresql_enabled` variable. + + +## Prerequisites + +1. Create a new SSH key: + +```bash +ssh-keygen -t ed25519 -N '' -f matrix-borg-backup -C matrix +``` + +This can be done on any machine and you don't need to place the key in the `.ssh` folder. It will be added to the Ansible config later. + +2. Add the **public** part of this SSH key (the `matrix-borg-backup.pub` file) to your borg provider/server: + +If you plan to use a hosted solution, follow their instructions. If you have your own server, copy the key over: + +```bash +# example to append the new PUBKEY contents, where: +# PUBKEY is path to the public key, +# USER is a ssh user on a provider / server +# HOST is a ssh host of a provider / server +cat PUBKEY | ssh USER@HOST 'dd of=.ssh/authorized_keys oflag=append conv=notrunc' +``` + +## Adjusting the playbook configuration + +Minimal working configuration (`inventory/host_vars/matrix.DOMAIN/vars.yml`) to enable borg backup: + +```yaml +matrix_backup_borg_enabled: true +matrix_backup_borg_location_repositories: + - ssh://USER@HOST/./REPO +matrix_backup_borg_storage_encryption_passphrase: "PASSPHRASE" +matrix_backup_borg_ssh_key_private: | + -----BEGIN OPENSSH PRIVATE KEY----- + TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZW + xpdCwgc2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFib3JlIGV0IGRv + bG9yZSBtYWduYSBhbGlxdWEuIFV0IGVuaW0gYWQgbWluaW0gdmVuaWFtLCBxdWlzIG5vc3 + RydWQgZXhlcmNpdGF0aW9uIHVsbGFtY28gbGFib3JpcyBuaXNpIHV0IGFsaXF1aXAgZXgg + ZWEgY29tbW9kbyBjb25zZXF1YXQuIA== + -----END OPENSSH PRIVATE KEY----- +``` + +where: + +* USER - SSH user of a provider/server +* HOST - SSH host of a provider/server +* REPO - borg repository name, it will be initialized on backup start, eg: `matrix`, regarding Syntax see [Remote repositories](https://borgbackup.readthedocs.io/en/stable/usage/general.html#repository-urls) +* PASSPHRASE - passphrase used for encrypting backups, you may generate it with `pwgen -s 64 1` or use any password manager +* PRIVATE KEY - the content of the **private** part of the SSH key you created before. The whole key (all of its belonging lines) under `matrix_backup_borg_ssh_key_private` needs to be indented with 2 spaces + +To backup without encryption, add `matrix_backup_borg_encryption: 'none'` to your vars. This will also enable the `matrix_backup_borg_unknown_unencrypted_repo_access_is_ok` variable. + +`matrix_backup_borg_location_source_directories` defines the list of directories to back up: it's set to `{{ matrix_base_data_path }}` by default, which is the base directory for every service's data, such as Synapse, Postgres and the bridges. You might want to exclude certain directories or file patterns from the backup using the `matrix_backup_borg_location_exclude_patterns` variable. + +Check the `roles/matrix/matrix-backup-borg/defaults/main.yml` file for the full list of available options. + +## Installing + +After configuring the playbook, run the [installation](installing.md) command again: + +``` +ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start +``` + +## Manually start a backup + +For testing your setup it can be helpful to not wait until 4am. If you want to run the backup immediately, log onto the server +and run `systemctl start matrix-backup-borg`. This will not return until the backup is done, so possibly a long time. +Consider using [tmux](https://en.wikipedia.org/wiki/Tmux) if your SSH connection is unstable. diff --git a/docs/configuring-playbook-base-domain-serving.md b/docs/configuring-playbook-base-domain-serving.md new file mode 100644 index 0000000..a5df4ec --- /dev/null +++ b/docs/configuring-playbook-base-domain-serving.md @@ -0,0 +1,52 @@ +# Serving the base domain + +This playbook sets up services on your Matrix server (`matrix.DOMAIN`). +To have this server officially be responsible for Matrix services for the base domain (`DOMAIN`), you need to set up [Server Delegation](howto-server-delegation.md). +This is normally done by [configuring well-known](configuring-well-known.md) files on the base domain. + +People who don't have a separate server to dedicate to the base domain have trouble arranging this. + +Usually, there are 2 options: + +- either get a separate server for the base domain, just for serving the files necessary for [Server Delegation via a well-known file](howto-server-delegation.md#server-delegation-via-a-well-known-file) + +- or, arrange for the Matrix server to serve the base domain. This either involves you [using your own webserver](configuring-playbook-own-webserver.md) or making the integrated webserver (`matrix-nginx-proxy`) serve the base domain for you. + +This documentation page tells you how to do the latter. With some easy changes, we make it possible to serve the base domain from the Matrix server via the integrated webserver (`matrix-nginx-proxy`). + +Just **adjust your DNS records**, so that your base domain is pointed to the Matrix server's IP address (using a DNS `A` record) **and then use the following configuration**: + +```yaml +matrix_nginx_proxy_base_domain_serving_enabled: true +``` + +Doing this, the playbook will: + +- obtain an SSL certificate for the base domain, just like it does for all other domains (see [how we handle SSL certificates](configuring-playbook-ssl-certificates.md)) + +- serve the `/.well-known/matrix/*` files which are necessary for [Federation Server Discovery](configuring-well-known.md#introduction-to-client-server-discovery) (also see [Server Delegation](howto-server-delegation.md)) and [Client-Server discovery](configuring-well-known.md#introduction-to-client-server-discovery) + +- serve a simple homepage at `https://DOMAIN` with content `Hello from DOMAIN` (configurable via the `matrix_nginx_proxy_base_domain_homepage_template` variable). You can also [serve a more complicated static website](#serving-a-static-website-at-the-base-domain). + + +## Serving a static website at the base domain + +By default, when "serving the base domain" is enabled, the playbook hosts a simple `index.html` webpage in `/matrix/nginx-proxy/data/matrix-domain`. +The content of this page is taken from the `matrix_nginx_proxy_base_domain_homepage_template` variable. + +If you'd like to host your own static website (more than a single `index.html` page) at the base domain, you can disable the creation of this default `index.html` page like this: + +```yaml +matrix_nginx_proxy_base_domain_homepage_enabled: false +``` + +With this configuration, Ansible will no longer mess around with the `/matrix/nginx-proxy/data/matrix-domain/index.html` file. + +You are then free to upload any static website files to `/matrix/nginx-proxy/data/matrix-domain` and they will get served at the base domain. + + +## Serving a more complicated website at the base domain + +If you'd like to serve an even more complicated (dynamic) website from the Matrix server, relying on the playbook to serve the base domain is not the best choice. + +Instead, we recommend that you switch to [using your own webserver](configuring-playbook-own-webserver.md) (preferrably nginx). You can then make that webserver host anything you wish, and still easily plug in Matrix services into it. diff --git a/docs/configuring-playbook-bot-buscarron.md b/docs/configuring-playbook-bot-buscarron.md new file mode 100644 index 0000000..0b80ba4 --- /dev/null +++ b/docs/configuring-playbook-bot-buscarron.md @@ -0,0 +1,70 @@ +# Setting up Buscarron (optional) + +The playbook can install and configure [buscarron](https://gitlab.com/etke.cc/buscarron) for you. + +It's a bot you can use to setup **your own helpdesk on matrix** +It's a bot you can use to send any form (HTTP POST, HTML) to a (encrypted) matrix room + + +## Adjusting the playbook configuration + +Add the following configuration to your `inventory/host_vars/matrix.DOMAIN/vars.yml` file: + +```yaml +matrix_bot_buscarron_enabled: true + +# Uncomment and adjust this part if you'd like to use a username different than the default +# matrix_bot_buscarron_login: bot.buscarron + +# Generate a strong password here. Consider generating it with `pwgen -s 64 1` +matrix_bot_buscarron_password: PASSWORD_FOR_THE_BOT + +# Adjust accepted forms +matrix_bot_buscarron_forms: + - name: contact # (mandatory) Your form name, will be used as endpoint, eg: buscarron.DOMAIN/contact + room: "!yourRoomID:DOMAIN" # (mandatory) Room ID where form submission will be posted + redirect: https://DOMAIN # (mandatory) To what page user will be redirected after the form submission + ratelimit: 1r/m # (optional) rate limit of the form, format: r/, eg: 1r/s or 54r/m + hasemail: 1 # (optional) form has "email" field that should be validated + extensions: [] # (optional) list of form extensions (not used yet) + +matrix_bot_buscarron_spamlist: [] # (optional) list of emails/domains/hosts (with wildcards support) that should be rejected automatically +``` + +You will also need to add a DNS record so that buscarron can be accessed. +By default buscarron will use https://buscarron.DOMAIN so you will need to create an CNAME record for `buscarron`. +See [Configuring DNS](configuring-dns.md). + +If you would like to use a different domain, add the following to your configuration file (changing it to use your preferred domain): + +```yaml +matrix_server_fqn_buscarron: "form.{{ matrix_domain }}" +``` + + +## Installing + +After configuring the playbook, run the [installation](installing.md) command again: + +```sh +ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,ensure-matrix-users-created,start +``` + +**Notes**: + +- the `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account + +- if you change the bot password (`matrix_bot_buscarron_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_buscarron_password` to let the bot know its new password + + +## Usage + +To use the bot, invite the `@bot.buscarron:DOMAIN` to the room you specified in a config, after that any point your form to the form url, example for the `contact` form: + +```html +
+ +
+``` + +You can also refer to the upstream [documentation](https://gitlab.com/etke.cc/buscarron). diff --git a/docs/configuring-playbook-bot-go-neb.md b/docs/configuring-playbook-bot-go-neb.md new file mode 100644 index 0000000..6ec2056 --- /dev/null +++ b/docs/configuring-playbook-bot-go-neb.md @@ -0,0 +1,213 @@ +# Setting up Go-NEB (optional) + +The playbook can install and configure [Go-NEB](https://github.com/matrix-org/go-neb) for you. + +Go-NEB is a Matrix bot written in Go. It is the successor to Matrix-NEB, the original Matrix bot written in Python. + +See the project's [documentation](https://github.com/matrix-org/go-neb) to learn what it does and why it might be useful to you. + + +## Registering the bot user + +The playbook does not automatically create users for you. The bot requires at least 1 access token to be able to connect to your homeserver. + +You **need to register the bot user manually** before setting up the bot. + +Choose a strong password for the bot. You can generate a good password with a command like this: `pwgen -s 64 1`. + +You can use the playbook to [register a new user](registering-users.md): + +``` +ansible-playbook -i inventory/hosts setup.yml --extra-vars='username=bot.go-neb password=PASSWORD_FOR_THE_BOT admin=no' --tags=register-user +``` + +Once the user is created you can [obtain an access token](obtaining-access-tokens.md). + + +## Adjusting the playbook configuration + +Add the following configuration to your `inventory/host_vars/matrix.DOMAIN/vars.yml` file (adapt to your needs): + +```yaml +matrix_bot_go_neb_enabled: true + +# You need at least 1 client. +# Use the access token you obtained in the step above. +matrix_bot_go_neb_clients: + - UserID: "@goneb:{{ matrix_domain }}" + AccessToken: "MDASDASJDIASDJASDAFGFRGER" + DeviceID: "DEVICE1" + HomeserverURL: "{{ matrix_homeserver_container_url }}" + Sync: true + AutoJoinRooms: true + DisplayName: "Go-NEB!" + AcceptVerificationFromUsers: [":{{ matrix_domain }}"] + + - UserID: "@another_goneb:{{ matrix_domain }}" + AccessToken: "MDASDASJDIASDJASDAFGFRGER" + DeviceID: "DEVICE2" + HomeserverURL: "{{ matrix_homeserver_container_url }}" + Sync: false + AutoJoinRooms: false + DisplayName: "Go-NEB!" + AcceptVerificationFromUsers: ["^@admin:{{ matrix_domain }}"] + +# Optional, for use with the github_cmd, github_webhooks or jira services +matrix_bot_go_neb_realms: + - ID: "github_realm" + Type: "github" + Config: {} # No need for client ID or Secret as Go-NEB isn't generating OAuth URLs + +# Optional. The list of *authenticated* sessions which Go-NEB is aware of. +matrix_bot_go_neb_sessions: + - SessionID: "your_github_session" + RealmID: "github_realm" + UserID: "@YOUR_USER_ID:{{ matrix_domain }}" # This needs to be the username of the person that's allowed to use the !github commands + Config: + # Populate these fields by generating a "Personal Access Token" on github.com + AccessToken: "YOUR_GITHUB_ACCESS_TOKEN" + Scopes: "admin:org_hook,admin:repo_hook,repo,user" + +# The list of services which Go-NEB is aware of. +# Delete or modify this list as appropriate. +# See the docs for /configureService for the full list of options: +# https://matrix-org.github.io/go-neb/pkg/github.com/matrix-org/go-neb/api/index.html#ConfigureServiceRequest +# You need at least 1 service. +matrix_bot_go_neb_services: + - ID: "echo_service" + Type: "echo" + UserID: "@goneb:{{ matrix_domain }}" + Config: {} + +# Can be obtained from https://developers.giphy.com/dashboard/ + - ID: "giphy_service" + Type: "giphy" + UserID: "@goneb:{{ matrix_domain }}" # requires a Syncing client + Config: + api_key: "qwg4672vsuyfsfe" + use_downsized: false + +# This service has been dead for over a year :/ + - ID: "guggy_service" + Type: "guggy" + UserID: "@goneb:{{ matrix_domain }}" # requires a Syncing client + Config: + api_key: "2356saaqfhgfe" + +# API Key via https://developers.google.com/custom-search/v1/introduction +# CX via http://www.google.com/cse/manage/all +# https://stackoverflow.com/questions/6562125/getting-a-cx-id-for-custom-search-google-api-python +# 'Search the entire web' and 'Image search' enabled for best results + - ID: "google_service" + Type: "google" + UserID: "@goneb:{{ matrix_domain }}" # requires a Syncing client + Config: + api_key: "AIzaSyA4FD39m9" + cx: "AIASDFWSRRtrtr" + +# Get a key via https://api.imgur.com/oauth2/addclient +# Select "oauth2 without callback url" + - ID: "imgur_service" + Type: "imgur" + UserID: "@imgur:{{ matrix_domain }}" # requires a Syncing client + Config: + client_id: "AIzaSyA4FD39m9" + client_secret: "somesecret" + + - ID: "wikipedia_service" + Type: "wikipedia" + UserID: "@goneb:{{ matrix_domain }}" # requires a Syncing client + Config: + + - ID: "rss_service" + Type: "rssbot" + UserID: "@another_goneb:{{ matrix_domain }}" + Config: + feeds: + "http://lorem-rss.herokuapp.com/feed?unit=second&interval=60": + rooms: ["!qmElAGdFYCHoCJuaNt:{{ matrix_domain }}"] + must_include: + author: + - author1 + description: + - lorem + - ipsum + must_not_include: + title: + - Lorem + - Ipsum + + - ID: "github_cmd_service" + Type: "github" + UserID: "@goneb:{{ matrix_domain }}" # requires a Syncing client + Config: + RealmID: "github_realm" + + # Make sure your BASE_URL can be accessed by Github! + - ID: "github_webhook_service" + Type: "github-webhook" + UserID: "@another_goneb:{{ matrix_domain }}" + Config: + RealmID: "github_realm" + ClientUserID: "@YOUR_USER_ID:{{ matrix_domain }}" # needs to be an authenticated user so Go-NEB can create webhooks. Check the UserID field in the github_realm in matrix_bot_go_neb_sessions. + Rooms: + "!someroom:id": + Repos: + "matrix-org/synapse": + Events: ["push", "issues"] + "matrix-org/dendron": + Events: ["pull_request"] + "!anotherroom:id": + Repos: + "matrix-org/synapse": + Events: ["push", "issues"] + "matrix-org/dendron": + Events: ["pull_request"] + + - ID: "slackapi_service" + Type: "slackapi" + UserID: "@slackapi:{{ matrix_domain }}" + Config: + Hooks: + "hook1": + RoomID: "!someroom:id" + MessageType: "m.text" # default is m.text + + - ID: "alertmanager_service" + Type: "alertmanager" + UserID: "@alertmanager:{{ matrix_domain }}" + Config: + # This is for information purposes only. It should point to Go-NEB path as follows: + # `/services/hooks/` + # Where in this case "service ID" is "alertmanager_service" + # Make sure your BASE_URL can be accessed by the Alertmanager instance! + webhook_url: "http://localhost/services/hooks/YWxlcnRtYW5hZ2VyX3NlcnZpY2U" + # Each room will get the notification with the alert rendered with the given template + rooms: + "!someroomid:domain.tld": + text_template: "{% raw %}{{range .Alerts -}} [{{ .Status }}] {{index .Labels \"alertname\" }}: {{index .Annotations \"description\"}} {{ end -}}{% endraw %}" + html_template: "{% raw %}{{range .Alerts -}} {{ $severity := index .Labels \"severity\" }} {{ if eq .Status \"firing\" }} {{ if eq $severity \"critical\"}} [FIRING - CRITICAL] {{ else if eq $severity \"warning\"}} [FIRING - WARNING] {{ else }} [FIRING - {{ $severity }}] {{ end }} {{ else }} [RESOLVED] {{ end }} {{ index .Labels \"alertname\"}} : {{ index .Annotations \"description\"}} source
{{end -}}{% endraw %}" + msg_type: "m.text" # Must be either `m.text` or `m.notice` +``` + + +## Installing + +Don't forget to add `goneb.` to DNS as described in [Configuring DNS](configuring-dns.md) before running the playbook. + +After configuring the playbook, run the [installation](installing.md) command again: + +``` +ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start +``` + + +## Usage + +To use the bot, invite it to any existing Matrix room (`/invite @whatever_you_chose:DOMAIN` where `YOUR_DOMAIN` is your base domain, not the `matrix.` domain, make sure you have permission from the room owner if that's not you). + +Basic usage is like this: `!echo hi` or `!imgur puppies` or `!giphy matrix` + +If you enabled the github_cmd service you can get the supported commands via `!github help` + +You can also refer to the upstream [Documentation](https://github.com/matrix-org/go-neb). diff --git a/docs/configuring-playbook-bot-honoroit.md b/docs/configuring-playbook-bot-honoroit.md new file mode 100644 index 0000000..42f31d4 --- /dev/null +++ b/docs/configuring-playbook-bot-honoroit.md @@ -0,0 +1,49 @@ +# Setting up Honoroit (optional) + +The playbook can install and configure [Honoroit](https://gitlab.com/etke.cc/honoroit) for you. + +It's a bot you can use to setup **your own helpdesk on matrix** + +See the project's [documentation](https://gitlab.com/etke.cc/honoroit#how-it-looks-like) to learn what it does with screenshots and why it might be useful to you. + + +## Adjusting the playbook configuration + +Add the following configuration to your `inventory/host_vars/matrix.DOMAIN/vars.yml` file: + +```yaml +matrix_bot_honoroit_enabled: true + +# Uncomment and adjust this part if you'd like to use a username different than the default +# matrix_bot_honoroit_login: honoroit + +# Generate a strong password here. Consider generating it with `pwgen -s 64 1` +matrix_bot_honoroit_password: PASSWORD_FOR_THE_BOT + +# Adjust this to your room ID +matrix_bot_honoroit_roomid: "!yourRoomID:DOMAIN" +``` + + +## Installing + +After configuring the playbook, run the [installation](installing.md) command again: + +```sh +ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,ensure-matrix-users-created,start +``` + +**Notes**: + +- the `ensure-matrix-users-created` playbook tag makes the playbook automatically create the bot's user account + +- if you change the bot password (`matrix_bot_honoroit_password` in your `vars.yml` file) subsequently, the bot user's credentials on the homeserver won't be updated automatically. If you'd like to change the bot user's password, use a tool like [synapse-admin](configuring-playbook-synapse-admin.md) to change it, and then update `matrix_bot_honoroit_password` to let the bot know its new password + + +## Usage + +To use the bot, invite the `@honoroit:DOMAIN` to the room you specified in config, after that any matrix user can send a message to the `@honoroit:DOMAIN` to start a new thread in that room. + +Send `!ho help` to the room to see the bot's help menu for additional commands. + +You can also refer to the upstream [documentation](https://gitlab.com/etke.cc/honoroit#features). diff --git a/docs/configuring-playbook-bot-maubot.md b/docs/configuring-playbook-bot-maubot.md new file mode 100644 index 0000000..11ab1cc --- /dev/null +++ b/docs/configuring-playbook-bot-maubot.md @@ -0,0 +1,58 @@ +# Setting up maubot (optional) + +The playbook can install and configure [maubot](https://github.com/maubot/maubot) for you. + +After setting up maubot, you can use the web management interface to make it do things. +The default location of the management interface is `matrix./_matrix/maubot/` + +See the project's [documentation](https://docs.mau.fi/maubot/usage/basic.html) to learn what it +does and why it might be useful to you. + +## Adjusting the playbook configuration + +Add the following configuration to your `inventory/host_vars/matrix.DOMAIN/vars.yml` file: + +```yaml +matrix_bot_maubot_enabled: true +matrix_bot_maubot_admins: + - yourusername: securepassword +``` + +You can add multiple admins. The admin accounts are not connected to any matrix ID and are only used to access the +maubot administration interface. + + +## Installing + +After configuring the playbook, run the [installation](installing.md) command again: + +``` +ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start +``` + +## Usage + +You can visit `matrix./_matrix/maubot/` to manage your available plugins, clients and instances. + +You should start in the following order +1. **Create one or more clients:** A client is a matrix account which the bot will use to message. +2. **Upload some Plugins:** Plugins can be obtained from [here](https://github.com/maubot/maubot#plugins) or any other source. +3. **Create an instance:** An instance is the actual bot. You have to specify a client which the bot instance will use +and the plugin (how the bot will behave) + +To add a client you first need to create an account and obtain a valid access token. + +## Registering the bot user + +You **need to register the bot user manually** before setting up the bot. You can use the playbook to [register a new user](registering-users.md): + +``` +ansible-playbook -i inventory/hosts setup.yml --extra-vars='username=bot.maubot password=PASSWORD_FOR_THE_BOT admin=yes' --tags=register-user +``` + +Choose a strong password for the bot. You can generate a good password with a command like this: `pwgen -s 64 1`. + +## Obtaining an admin access token + +This can be done via `mbc login` then `mbc auth` (see the [maubot documentation](https://docs.mau.fi/maubot/usage/cli/auth.html)). To run these commands you'll need to open the bot docker container with `docker exec -it matrix-bot-maubot sh` +Alternatively, use Element or curl to [obtain an access token](obtaining-access-tokens.md). However these two methods won't allow the bot to work in encrypted rooms. diff --git a/docs/configuring-playbook-bot-mjolnir.md b/docs/configuring-playbook-bot-mjolnir.md new file mode 100644 index 0000000..5fc6331 --- /dev/null +++ b/docs/configuring-playbook-bot-mjolnir.md @@ -0,0 +1,122 @@ +# Setting up Mjolnir (optional) + +The playbook can install and configure the [Mjolnir](https://github.com/matrix-org/mjolnir) moderation bot for you. + +See the project's [documentation](https://github.com/matrix-org/mjolnir) to learn what it does and why it might be useful to you. + + +## 1. Register the bot account + +The playbook does not automatically create users for you. The bot requires an access token to be able to connect to your homeserver. + +You **need to register the bot user manually** before setting up the bot. + +Choose a strong password for the bot. You can generate a good password with a command like this: `pwgen -s 64 1`. + +You can use the playbook to [register a new user](registering-users.md): + +``` +ansible-playbook -i inventory/hosts setup.yml --extra-vars='username=bot.mjolnir password=PASSWORD_FOR_THE_BOT admin=no' --tags=register-user +``` + +If you would like Mjolnir to be able to deactivate users, move aliases, shutdown rooms, etc then it must be a server admin so you need to change `admin=no` to `admin=yes` in the command above. + + +## 2. Get an access token + +Refer to the documentation on [how to obtain an access token](obtaining-access-tokens.md). + + +## 3. Make sure the account is free from rate limiting + +You will need to prevent Synapse from rate limiting the bot's account. This is not an optional step. If you do not do this step Mjolnir will crash. This can be done using Synapse's [admin API](https://matrix-org.github.io/synapse/latest/admin_api/user_admin_api.html#override-ratelimiting-for-users). This can also be manually done by editing the Synapse database. Manually editing the Synapse database is rarely a good idea. Please ask for help if you are uncomfortable with these steps. + +1. Copy the statement below into a text editor. + + ``` + INSERT INTO ratelimit_override VALUES ('@bot.mjolnir:DOMAIN', 0, 0); + ``` + +1. Change the username (`@bot.mjolnir:DOMAIN`) to the username you used when you registered the bot's account. You must change `DOMAIN` to your server's domain. + +1. Get a database terminal by following these steps: [maintenance-postgres.md#getting-a-database-terminal](maintenance-postgres.md#getting-a-database-terminal) + +1. Connect to Synapse's database by typing `\connect synapse` into the database terminal + +1. Paste in the `INSERT INTO` command that you edited and press enter. + +You can run `SELECT * FROM ratelimit_override;` to see if it worked. If the output looks like this: + +``` + user_id | messages_per_second | burst_count +-----------------------+---------------------+------------- + @bot.mjolnir:raim.ist | 0 | 0` +``` +then you did it correctly. + + +## 4. Create a management room + +Using your own account, create a new invite only room that you will use to manage the bot. This is the room where you will see the status of the bot and where you will send commands to the bot, such as the command to ban a user from another room. Anyone in this room can control the bot so it is important that you only invite trusted users to this room. The room must be unencrypted since the playbook does not support installing Pantalaimon yet. + +Once you have created the room you need to copy the room ID so you can tell the bot to use that room. In Element you can do this by going to the room's settings, clicking Advanced, and then coping the internal room ID. The room ID will look something like `!QvgVuKq0ha8glOLGMG:DOMAIN`. + +Finally invite the `@bot.mjolnir:DOMAIN` account you created earlier into the room. + + +## 5. Adjusting the playbook configuration + +Add the following configuration to your `inventory/host_vars/matrix.DOMAIN/vars.yml` file (adapt to your needs): + +You must replace `ACCESS_TOKEN_FROM_STEP_2_GOES_HERE` and `ROOM_ID_FROM_STEP_4_GOES_HERE` with the your own values. + +```yaml +matrix_bot_mjolnir_enabled: true + +matrix_bot_mjolnir_access_token: "ACCESS_TOKEN_FROM_STEP_2_GOES_HERE" + +matrix_bot_mjolnir_management_room: "ROOM_ID_FROM_STEP_4_GOES_HERE" +``` + +## 6. Adding mjolnir synapse antispam module (optional) + +Add the following configuration to your `inventory/host_vars/matrix.DOMAIN/vars.yml` file (adapt to your needs): + + +```yaml +matrix_synapse_ext_spam_checker_mjolnir_antispam_enabled: true +matrix_synapse_ext_spam_checker_mjolnir_antispam_config_block_invites: true +matrix_synapse_ext_spam_checker_mjolnir_antispam_config_block_messages: false +matrix_synapse_ext_spam_checker_mjolnir_antispam_config_block_usernames: false +matrix_synapse_ext_spam_checker_mjolnir_antispam_config_ban_lists: [] +``` + + +## 7. Installing + +After configuring the playbook, run the [installation](installing.md) command: + +``` +ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start +``` + + +## Usage + +You can refer to the upstream [documentation](https://github.com/matrix-org/mjolnir) for additional ways to use and configure mjolnir. Check out their [quickstart guide](https://github.com/matrix-org/mjolnir#quickstart-guide) for some basic commands you can give to the bot. + +You can configure additional options by adding the `matrix_bot_mjolnir_configuration_extension_yaml` variable to your `inventory/host_vars/matrix.DOMAIN/vars.yml` file. + +For example to change mjolnir's `recordIgnoredInvites` option to `true` you would add the following to your `vars.yml` file. + +```yaml +matrix_bot_mjolnir_configuration_extension_yaml: | + # Your custom YAML configuration goes here. + # This configuration extends the default starting configuration (`matrix_bot_mjolnir_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_bot_mjolnir_configuration_yaml`. + recordIgnoredInvites: true +``` diff --git a/docs/configuring-playbook-conduit.md b/docs/configuring-playbook-conduit.md new file mode 100644 index 0000000..8739a56 --- /dev/null +++ b/docs/configuring-playbook-conduit.md @@ -0,0 +1,58 @@ +# Configuring Conduit (optional) + +By default, this playbook configures the [Synapse](https://github.com/matrix-org/synapse) Matrix server, but you can also use [Conduit](https://conduit.rs). + +**NOTES**: + +- **You can't switch an existing Matrix server's implementation** (e.g. Synapse -> Conduit). Proceed below only if you're OK with losing data or you're dealing with a server on a new domain name, which hasn't participated in the Matrix federation yet. + +- **homeserver implementations other than Synapse may not be fully functional**. The playbook may also not assist you in an optimal way (like it does with Synapse). Make yourself familiar with the downsides before proceeding + + +## Installation + +To use Conduit, you **generally** need the following additional `vars.yml` configuration: + +```yaml +matrix_homeserver_implementation: conduit +``` + +However, since Conduit is difficult (see [famedly/conduit#276](https://gitlab.com/famedly/conduit/-/issues/276) and [famedly/conduit#354](https://gitlab.com/famedly/conduit/-/merge_requests/354)) when it comes to creating the first user account and does not support [registering users](registering-users.md) (via the command line or via the playbook) like Synapse and Dendrite do, we recommend the following flow: + +1. Add `matrix_conduit_allow_registration: true` to your `vars.yml` the first time around, temporarily +2. Run the playbook (`ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start` - see [Installing](installing.md)) +3. Create your first user via Element or any other client which supports creating users +4. Get rid of `matrix_conduit_allow_registration: true` from your `vars.yml` +5. Run the playbook again (`ansible-playbook -i inventory/hosts setup.yml --tags=setup-conduit,start` would be enough this time) +6. You can now use your server safely. Additional users can be created by messaging the internal Conduit bot + + +## Configuring bridges / appservices + +Automatic appservice setup is currently unsupported when using conduit. After setting up the service as usual you may notice that it is unable to start. + +You will have to manually register appservices using the the [register-appservice](https://gitlab.com/famedly/conduit/-/blob/next/APPSERVICES.md) command. + +Find the `registration.yaml` in the `/matrix` directory, for example `/matrix/mautrix-signal/bridge/registration.yaml`, then pass the content to conduit: + + + @conduit:your.server.name: register-appservice + ``` + as_token: + de.sorunome.msc2409.push_ephemeral: true + hs_token: + id: signal + namespaces: + aliases: + - exclusive: true + regex: ^#signal_.+:example\.org$ + users: + - exclusive: true + regex: ^@signal_.+:example\.org$ + - exclusive: true + regex: ^@signalbot:example\.org$ + rate_limited: false + sender_localpart: _bot_signalbot + url: http://matrix-mautrix-signal:29328 + ``` + diff --git a/docs/configuring-playbook-dendrite.md b/docs/configuring-playbook-dendrite.md new file mode 100644 index 0000000..06c6e68 --- /dev/null +++ b/docs/configuring-playbook-dendrite.md @@ -0,0 +1,32 @@ +# Configuring Dendrite (optional) + +By default, this playbook configures the [Synapse](https://github.com/matrix-org/synapse) Matrix server, but you can also use [Dendrite](https://github.com/matrix-org/dendrite). + +**NOTES**: + +- **You can't switch an existing Matrix server's implementation** (e.g. Synapse -> Dendrite). Proceed below only if you're OK with losing data or you're dealing with a server on a new domain name, which hasn't participated in the Matrix federation yet. + +- **homeserver implementations other than Synapse may not be fully functional**. The playbook may also not assist you in an optimal way (like it does with Synapse). Make yourself familiar with the downsides before proceeding + +The playbook provided settings for Dendrite are defined in [`roles/matrix/matrix-dendrite/defaults/main.yml`](../roles/matrix/matrix-dendrite/defaults/main.yml) and they ultimately end up in the generated `/matrix/dendrite/config/dendrite.yaml` file (on the server). This file is generated from the [`roles/matrix/matrix-dendrite/templates/dendrite/dendrite.yaml.j2`](../roles/matrix/matrix-dendrite/templates/dendrite/dendrite.yaml.j2) template. + +**If there's an existing variable** which controls a setting you wish to change, you can simply define that variable in your configuration file (`inventory/host_vars/matrix./vars.yml`) and [re-run the playbook](installing.md) to apply the changes. + +Alternatively, **if there is no pre-defined variable** for a Dendrite setting you wish to change: + +- you can either **request a variable to be created** (or you can submit such a contribution yourself). Keep in mind that it's **probably not a good idea** to create variables for each one of Dendrite's various settings that rarely get used. + +- or, you can **extend and override the default configuration** ([`dendrite.yaml.j2`](../roles/matrix/matrix-dendrite/templates/dendrite/dendrite.yaml.j2)) by making use of the `matrix_dendrite_configuration_extension_yaml` variable. You can find information about this in [`roles/matrix/matrix-dendrite/defaults/main.yml`](../roles/matrix/matrix-dendrite/defaults/main.yml). + +- or, if extending the configuration is still not powerful enough for your needs, you can **override the configuration completely** using `matrix_dendrite_configuration` (or `matrix_dendrite_configuration_yaml`). You can find information about this in [`roles/matrix/matrix-dendrite/defaults/main.yml`](../roles/matrix/matrix-dendrite/defaults/main.yml). + + + +## Installation + +To use Dendrite, you **generally** need the following additional `vars.yml` configuration: + +```yaml +matrix_homeserver_implementation: dendrite +``` + diff --git a/docs/configuring-playbook-dimension.md b/docs/configuring-playbook-dimension.md new file mode 100644 index 0000000..353dbcb --- /dev/null +++ b/docs/configuring-playbook-dimension.md @@ -0,0 +1,78 @@ +# Setting up Dimension (optional) + +**[Dimension](https://dimension.t2bot.io) can only be installed after Matrix services are installed and running.** +If you're just installing Matrix services for the first time, please continue with the [Configuration](configuring-playbook.md) / [Installation](installing.md) flow and come back here later. + +**Note**: This playbook now supports running [Dimension](https://dimension.t2bot.io) in both a federated and [unfederated](https://github.com/turt2live/matrix-dimension/blob/master/docs/unfederated.md) environments. This is handled automatically based on the value of `matrix_synapse_federation_enabled`. Enabling Dimension, means that the `openid` API endpoints will be exposed on the Matrix Federation port (usually `8448`), even if [federation](configuring-playbook-federation.md) is disabled. It's something to be aware of, especially in terms of firewall whitelisting (make sure port `8448` is accessible). + + +## Prerequisites + +The `dimension.` DNS record must be created. See [Configuring your DNS server](configuring-dns.md) on how to set up DNS record correctly. + + +## Enable + +[Dimension integrations manager](https://dimension.t2bot.io) installation is disabled by default. You can enable it in your configuration file (`inventory/host_vars/matrix./vars.yml`): + +```yaml +matrix_dimension_enabled: true +``` + + +## Define admin users + +These users can modify the integrations this Dimension supports. +Add this to your configuration file (`inventory/host_vars/matrix./vars.yml`): + +```yaml +matrix_dimension_admins: + - "@user1:{{ matrix_domain }}" + - "@user2:{{ matrix_domain }}" +``` + +The admin interface is accessible within Element by accessing it in any room and clicking the cog wheel/settings icon in the top right. Currently, Dimension can be opened in Element by the "Add widgets, bridges, & bots" link in the room information. + +## Access token + +We recommend that you create a dedicated Matrix user for Dimension (`dimension` is a good username). +Follow our [Registering users](registering-users.md) guide to learn how to register **a regular (non-admin) user**. + +You are required to specify an access token (belonging to this new user) for Dimension to work. +To get an access token for the Dimension user, you can follow the documentation on [how to do obtain an access token](obtaining-access-tokens.md). + +**Access tokens are sensitive information. Do not include them in any bug reports, messages, or logs. Do not share the access token with anyone.** + +Add access token to your configuration file (`inventory/host_vars/matrix./vars.yml`): + +```yaml +matrix_dimension_access_token: "YOUR ACCESS TOKEN HERE" +``` + +For more information on how to acquire an access token, visit [https://t2bot.io/docs/access_tokens](https://t2bot.io/docs/access_tokens). + + +## Installation + +After these variables have been set, please run the following command to re-run setup and to restart Dimension: + +``` +ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start +``` + +After Dimension has been installed you may need to log out and log back in for it to pick up the new integrations manager. Then you can access integrations in Element by opening a room, clicking the Room info button (`i`) button in the top right corner of the screen, and then clicking Add widgets, bridges & bots. + + +## Jitsi domain + +By default Dimension will use [jitsi.riot.im](https://jitsi.riot.im/) as the `conferenceDomain` of [Jitsi](https://jitsi.org/) audio/video conference widgets. For users running [a self-hosted Jitsi instance](./configuring-playbook-jitsi.md), you will likely want the widget to use your own Jitsi instance. Currently there is no way to configure this via the playbook, see [this issue](https://github.com/turt2live/matrix-dimension/issues/345) for details. + +In the interim until the above limitation is resolved, an admin user needs to configure the domain via the admin ui once dimension is running. In Element, go to *Manage Integrations* → *Settings* → *Widgets* → *Jitsi Conference Settings* and set *Jitsi Domain* and *Jitsi Script URL* appropriately. + + +## Additional features + +To use a more custom configuration, you can define a `matrix_dimension_configuration_extension_yaml` string variable and put your configuration in it. +To learn more about how to do this, refer to the information about `matrix_dimension_configuration_extension_yaml` in the [default variables file](../roles/matrix/matrix-dimension/defaults/main.yml) of the Dimension component. + +You can find all configuration options on [GitHub page of Dimension project](https://github.com/turt2live/matrix-dimension/blob/master/config/default.yaml). diff --git a/docs/configuring-playbook-dynamic-dns.md b/docs/configuring-playbook-dynamic-dns.md new file mode 100644 index 0000000..bc58c27 --- /dev/null +++ b/docs/configuring-playbook-dynamic-dns.md @@ -0,0 +1,27 @@ +# Dynamic DNS + +## Setup + +Most cloud providers / ISPs will charge you extra for a static IP address. If you're +not hosting a highly reliable homeserver you can workaround this via dynamic DNS. To +set this up, you'll need to get the username/password from your DNS provider. For +google domains, this process is described [here](https://support.google.com/domains/answer/6147083). +After you've gotten the proper credentials you can add the following config to your `inventory/host_vars/matrix.DOMAIN/vars.yml`: + +```yaml +matrix_dynamic_dns_enabled: true + +matrix_dynamic_dns_domain_configurations: + - provider: domains.google.com + protocol: dyndn2 + username: XXXXXXXXXXXXXXXX + password: XXXXXXXXXXXXXXXX + domain: "{{ matrix_domain }}" +``` + + +## Additional Reading + +Additional resources: + +- https://matrix.org/docs/guides/free-small-matrix-server diff --git a/docs/configuring-playbook-email.md b/docs/configuring-playbook-email.md new file mode 100644 index 0000000..d9721a4 --- /dev/null +++ b/docs/configuring-playbook-email.md @@ -0,0 +1,55 @@ +# Adjusting email-sending settings (optional) + +By default, this playbook sets up an [Exim](https://www.exim.org/) email server through which all Matrix services send emails. + +The email server would attempt to deliver emails directly to their final destination. +This may or may not work, depending on your domain configuration (SPF settings, etc.) + +By default, emails are sent from `matrix@` (as specified by the `matrix_mailer_sender_address` playbook variable). + +**Note**: If you are using a Google Cloud instance, [port 25 is always blocked](https://cloud.google.com/compute/docs/tutorials/sending-mail/), so you need to relay email through another SMTP server as described below. + + +## Firewall settings + +No matter whether you send email directly (the default) or you relay email through another host (see how below), you'll probably need to allow outgoing traffic for TCP ports 25/587 (depending on configuration). + + +## Relaying email through another SMTP server + +If you'd like to relay email through another SMTP server, feel free to redefine a few playbook variables. +Example: + +```yaml +matrix_mailer_sender_address: "another.sender@example.com" +matrix_mailer_relay_use: true +matrix_mailer_relay_host_name: "mail.example.com" +matrix_mailer_relay_host_port: 587 +matrix_mailer_relay_auth: true +matrix_mailer_relay_auth_username: "another.sender@example.com" +matrix_mailer_relay_auth_password: "some-password" +``` + +**Note**: only the secure submission protocol (using `STARTTLS`, usually on port `587`) is supported. **SMTPS** (encrypted SMTP, usually on port `465`) **is not supported**. + + +### Configuations for sending emails using Sendgrid +An easy and free SMTP service to set up is [Sendgrid](https://sendgrid.com/), the free tier allows for up to 100 emails per day to be sent. In the settings below you can provide any email for `matrix_mailer_sender_address`. + +The only other thing you need to change is the `matrix_mailer_relay_auth_password`, which you can generate at https://app.sendgrid.com/settings/api_keys. The API key password looks something like `SG.955oW1mLSfwds7i9Yd6IA5Q.q8GTaB8q9kGDzasegdG6u95fQ-6zkdwrPP8bOeuI`. + +Note that the `matrix_mailer_relay_auth_username` is literally the string `apikey`, it's always the same for Sendgrid. + +```yaml +matrix_mailer_sender_address: "arbitrary@email.com" +matrix_mailer_relay_use: true +matrix_mailer_relay_host_name: "smtp.sendgrid.net" +matrix_mailer_relay_host_port: 587 +matrix_mailer_relay_auth: true +matrix_mailer_relay_auth_username: "apikey" +matrix_mailer_relay_auth_password: "" +``` + +## Troubleshooting + +If you're having trouble with email not being delivered, it may be useful to inspect the mailer logs: `journalctl -f -u matrix-mailer`. diff --git a/docs/configuring-playbook-email2matrix.md b/docs/configuring-playbook-email2matrix.md new file mode 100644 index 0000000..d65d2cc --- /dev/null +++ b/docs/configuring-playbook-email2matrix.md @@ -0,0 +1,76 @@ +# Setting up Email2Matrix (optional) + +**Note**: email bridging can also happen via the [Postmoogle](configuring-playbook-bot-postmoogle.md) bot supported by the playbook. +Postmoogle is much more powerful and easier to use, so we recommend that you use it, instead of Email2Matrix. + +The playbook can install and configure [email2matrix](https://github.com/devture/email2matrix) for you. + +See the project's [documentation](https://github.com/devture/email2matrix/blob/master/docs/README.md) to learn what it does and why it might be useful to you. + + +## Preparation + +### DNS configuration + +It's not strictly necessary, but you may increase the chances that incoming emails reach your server by adding an `MX` record for `matrix.DOMAIN`, as described in the [Configuring DNS](configuring-dns.md) documentation page. + +### Port availability + +Ensure that port 25 is available on your Matrix server and open in your firewall. +If you have `postfix` or some other email server software installed, you may need to manually remove it first (unless you need it, of course). + +If you really need to run an email server on the Matrix machine for other purposes, it may be possible to run Email2Matrix on another port (with a configuration like `matrix_email2matrix_smtp_host_bind_port: "127.0.0.01:2525"`) and have your other email server relay messages there. +For details about using Email2Matrix alongside [Postfix](http://www.postfix.org/), see [here](https://github.com/devture/email2matrix/blob/master/docs/setup_with_postfix.md). + +### Creating a user + +Before enabling Email2Matrix, you'd most likely wish to create a dedicated user (or more) that would be sending messages on the Matrix side. +Refer to [Registering users](registering-users.md) for ways to do that. A regular (non-admin) user works best. + +### Creating a shared room + +After creating a sender user, you should create one or more Matrix rooms that you share with that user. +It doesn't matter who creates and owns the rooms and who joins later (you or the sender user). + +What matters is that both you and the sender user are part of the same room and that the sender user has enough privileges in the room to be able to send messages there. +Inviting additional people to the room is okay too. + +Take note of each room's room id (different clients show the room id in a different place). +You'll need the room id when doing [Configuration](#configuration) below. + + +### Obtaining an access token for the sender user + +In order for the sender user created above to be able to send messages to the room, we'll need to obtain an access token for it. Refer to the documentation on [how to obtain an access token](obtaining-access-tokens.md). + +## Configuration + +After doing the preparation steps above, adjust your `inventory/host_vars/matrix.DOMAIN/vars.yml` configuration like this: + +```yaml +matrix_email2matrix_enabled: true + +matrix_email2matrix_matrix_mappings: + - MailboxName: "my-mailbox" + MatrixRoomId: "!someRoom:DOMAIN" + MatrixHomeserverUrl: "https://matrix.DOMAIN" + MatrixUserId: "@email2matrix:DOMAIN" + MatrixAccessToken: "ACCESS_TOKEN_GOES_HERE" + IgnoreSubject: false + IgnoreBody: false + SkipMarkdown: false + + - MailboxName: "my-mailbox2" + MatrixRoomId: "!anotherRoom:DOMAIN" + MatrixHomeserverUrl: "https://matrix.DOMAIN" + MatrixUserId: "@email2matrix:DOMAIN" + MatrixAccessToken: "ACCESS_TOKEN_GOES_HERE" + IgnoreSubject: true + IgnoreBody: false + SkipMarkdown: true +``` + +You can also set `MatrixHomeserverUrl` to `http://matrix-synapse-reverse-proxy-companion:8008`, instead of the public `https://matrix.DOMAIN`. +However, that's more likely to break in the future if you switch to another server implementation than Synapse. + +Re-run the playbook (`--tags=setup-email2matrix,start`) and try sending an email to `my-mailbox@matrix.DOMAIN`. diff --git a/docs/configuring-playbook-federation.md b/docs/configuring-playbook-federation.md new file mode 100644 index 0000000..5a1e76e --- /dev/null +++ b/docs/configuring-playbook-federation.md @@ -0,0 +1,69 @@ +# Controlling Matrix federation (optional) + +By default, your server federates with the whole Matrix network. +That is, people on your server can communicate with people on any other Matrix server. + + +## Federating only with select servers + +To make your server only federate with servers of your choosing, add this to your configuration file (`inventory/host_vars/matrix./vars.yml`): + +```yaml +matrix_synapse_federation_domain_whitelist: +- example.com +- another.com +``` + +If you wish to disable federation, you can do that with an empty list (`[]`), or better yet by completely disabling federation (see below). + + +## Exposing the room directory over federation + +By default, your server's public rooms directory is not exposed to other servers via federation. + +If you wish to expose it, add this to your configuration file (`inventory/host_vars/matrix./vars.yml`): + +```yaml +matrix_synapse_allow_public_rooms_over_federation: true +``` + + +## Disabling federation + +To completely disable federation, isolating your server from the rest of the Matrix network, add this to your configuration file (`inventory/host_vars/matrix./vars.yml`): + +```yaml +matrix_synapse_federation_enabled: false +``` + +With that, your server's users will only be able to talk among themselves, but not to anyone who is on another server. + +**Disabling federation does not necessarily disable the federation port** (`8448`). Services like [Dimension](configuring-playbook-dimension.md) and [ma1sd](configuring-playbook-ma1sd.md) normally rely on `openid` APIs exposed on that port. Even if you disable federation and only if necessary, we may still be exposing the federation port and serving the `openid` APIs there. To override this and completely disable Synapse's federation port use: + +```yaml +# This stops the federation port on the Synapse side (normally `matrix-synapse:8048` on the container network). +matrix_synapse_federation_port_enabled: false + +# This removes the `8448` virtual host from the matrix-nginx-proxy reverse-proxy server. +matrix_nginx_proxy_proxy_matrix_federation_api_enabled: false + +# This stops the federation port on the synapse-reverse-proxy-companion side (normally `matrix-synapse-reverse-proxy-companion:8048` on the container network). +matrix_synapse_reverse_proxy_companion_federation_api_enabled: false +``` + +## Changing the federation port from 8448 to a different port to use a CDN that only accepts 443/80 ports + +Why? This change could be useful for people running small Synapse instances on small severs/VPSes to avoid being impacted by a simple DOS/DDOS when bandwidth, RAM, an CPU resources are limited and if your hosting provider does not provide a DOS/DDOS protection. + +The following changes in the configuration file (`inventory/host_vars/matrix./vars.yml`) will allow this and make it possible to proxy the federation through a CDN such as CloudFlare or any other: + +``` +matrix_synapse_http_listener_resource_names: ["client","federation"] +# Any port can be used but in this case we use 443 +matrix_federation_public_port: 443 +matrix_synapse_federation_port_enabled: false +# Note that the following change might not be "required per se" but probably will be due to the proxying of the traffic through the CDN proxy servers (CloudFlare for instance). The security impact of doing this should be minimal as your CDN itself will encrypt the traffic no matter what on their proxy servers. You could however first try and see if federation works while setting the following to true. +matrix_synapse_tls_federation_listener_enabled: false +``` + +**Use this at you own risk as all the possible side-effects of doing this are not fully known. However, it has been tested and works fine and passes all the tests on without issues.** diff --git a/docs/configuring-playbook-ldap-auth.md b/docs/configuring-playbook-ldap-auth.md new file mode 100644 index 0000000..ecc0f25 --- /dev/null +++ b/docs/configuring-playbook-ldap-auth.md @@ -0,0 +1,39 @@ +# Setting up the LDAP authentication password provider module (optional, advanced) + +The playbook can install and configure the [matrix-synapse-ldap3](https://github.com/matrix-org/matrix-synapse-ldap3) LDAP Auth password provider for you. + +See that project's documentation to learn what it does and why it might be useful to you. + +If you decide that you'd like to let this playbook install it for you, you need some configuration like this: + +```yaml +matrix_synapse_ext_password_provider_ldap_enabled: true +matrix_synapse_ext_password_provider_ldap_uri: "ldap://ldap.mydomain.tld:389" +matrix_synapse_ext_password_provider_ldap_start_tls: true +matrix_synapse_ext_password_provider_ldap_base: "ou=users,dc=example,dc=com" +matrix_synapse_ext_password_provider_ldap_attributes_uid: "uid" +matrix_synapse_ext_password_provider_ldap_attributes_mail: "mail" +matrix_synapse_ext_password_provider_ldap_attributes_name: "cn" +matrix_synapse_ext_password_provider_ldap_bind_dn: "" +matrix_synapse_ext_password_provider_ldap_bind_password: "" +matrix_synapse_ext_password_provider_ldap_filter: "" +``` + + +## Authenticating only using a password provider + +If you wish for users to **authenticate only against configured password providers** (like this one), **without consulting Synapse's local database**, feel free to disable it: + +```yaml +matrix_synapse_password_config_localdb_enabled: false +``` + + +## Using ma1sd Identity Server for authentication + +If you wish to use the ma1sd Identity Server for LDAP authentication instead of [matrix-synapse-ldap3](https://github.com/matrix-org/matrix-synapse-ldap3) consult [Adjusting ma1sd Identity Server configuration](configuring-playbook-ma1sd.md#authentication). + + +## Handling user registration + +If you wish for users to also be able to make new registrations against LDAP, you may **also** wish to [set up the ldap-registration-proxy](configuring-playbook-matrix-ldap-registration-proxy.md). diff --git a/docs/configuring-playbook-nginx.md b/docs/configuring-playbook-nginx.md new file mode 100644 index 0000000..11eb4d2 --- /dev/null +++ b/docs/configuring-playbook-nginx.md @@ -0,0 +1,84 @@ +# Configure Nginx (optional, advanced) + +By default, this playbook installs its own nginx webserver (in a Docker container) which listens on ports 80 and 443. +If that's alright, you can skip this. + + +## Using Nginx status + +This will serve a statuspage to the hosting machine only. Useful for monitoring software like [longview](https://www.linode.com/docs/platform/longview/longview-app-for-nginx/) + +```yaml +matrix_nginx_proxy_proxy_matrix_nginx_status_enabled: true +``` + +This will serve the status page under the following addresses: +- `http://matrix.DOMAIN/nginx_status` (using HTTP) +- `https://matrix.DOMAIN/nginx_status` (using HTTPS) + +By default, if ```matrix_nginx_proxy_nginx_status_enabled``` is enabled, access to the status page would be allowed from the local IP address of the server. If you wish to allow access from other IP addresses, you can provide them as a list: + +```yaml +matrix_nginx_proxy_proxy_matrix_nginx_status_allowed_addresses: +- 8.8.8.8 +- 1.1.1.1 +``` + +## Adjusting SSL in your server + +You can adjust how the SSL is served by the nginx server using the `matrix_nginx_proxy_ssl_preset` variable. We support a few presets, based on the Mozilla Server Side TLS +Recommended configurations. These presets influence the TLS Protocol, the SSL Cipher Suites and the `ssl_prefer_server_ciphers` variable of nginx. +Possible values are: + +- `"modern"` - For Modern clients that support TLS 1.3, with no need for backwards compatibility +- `"intermediate"` (**default**) - Recommended configuration for a general-purpose server +- `"old"` - Services accessed by very old clients or libraries, such as Internet Explorer 8 (Windows XP), Java 6, or OpenSSL 0.9.8 + +**Be really carefull when setting it to `"modern"`**. This could break comunication with other Matrix servers, limiting your federation posibilities. + +Besides changing the preset (`matrix_nginx_proxy_ssl_preset`), you can also directly override these 3 variables: + +- `matrix_nginx_proxy_ssl_protocols`: for specifying the supported TLS protocols. +- `matrix_nginx_proxy_ssl_prefer_server_ciphers`: for specifying if the server or the client choice when negotiating the cipher. It can set to `on` or `off`. +- `matrix_nginx_proxy_ssl_ciphers`: for specifying the SSL Cipher suites used by nginx. + +For more information about these variables, check the `roles/nginx-proxy/defaults/main.yml` file. + +## Synapse + OpenID Connect for Single-Sign-On + +If you want to use OpenID Connect as an SSO provider (as per the [Synapse OpenID docs](https://github.com/matrix-org/synapse/blob/develop/docs/openid.md)), you need to use the following configuration (in your `vars.yml` file) to instruct nginx to forward `/_synapse/oidc` to Synapse: + +```yaml +matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_synapse_oidc_api_enabled: true +``` + +## Disable Nginx access logs + +This will disable the access logging for nginx. + +```yaml +matrix_nginx_proxy_access_log_enabled: false +``` + +## Additional configuration + +This playbook also allows for additional configuration to be applied to the nginx server. + +If you want this playbook to obtain and renew certificates for other domains, then you can set the `matrix_ssl_additional_domains_to_obtain_certificates_for` variable (as mentioned in the [Obtaining SSL certificates for additional domains](configuring-playbook-ssl-certificates.md#obtaining-ssl-certificates-for-additional-domains) documentation as well). Make sure that you have set the DNS configuration for the domains you want to include to point at your server. + +```yaml +matrix_ssl_additional_domains_to_obtain_certificates_for: + - domain.one.example + - domain.two.example +``` + +You can include additional nginx configuration by setting the `matrix_nginx_proxy_proxy_http_additional_server_configuration_blocks` variable. + +```yaml +matrix_nginx_proxy_proxy_http_additional_server_configuration_blocks: + - | + # These lines will be included in the nginx configuration. + # This is at the top level of the file, so you will need to define all of the `server { ... }` blocks. + - | + # For advanced use, have a look at the template files in `roles/nginx-proxy/templates/nginx/conf.d` +``` diff --git a/docs/configuring-playbook-ntfy.md b/docs/configuring-playbook-ntfy.md new file mode 100644 index 0000000..3090ac5 --- /dev/null +++ b/docs/configuring-playbook-ntfy.md @@ -0,0 +1,94 @@ +# Setting up ntfy (optional) + +The playbook can install and configure the [ntfy](https://ntfy.sh/) push notifications server for you. + +Using the [UnifiedPush](https://unifiedpush.org) standard, ntfy enables self-hosted (Google-free) push notifications from Matrix (and other) servers to UnifiedPush-compatible matrix compatible client apps running on Android and other devices. + +This role is intended to support UnifiedPush notifications for use with the Matrix and Matrix-related services that this playbook installs. This role is not intended to support all of ntfy's other features. + +**Note**: In contrast to push notifications using Google's FCM or Apple's APNs, the use of UnifiedPush allows each end-user to choose the push notification server that they prefer. As a consequence, deploying this ntfy server does not by itself ensure any particular user or device or client app will use it. + + +## Adjusting the playbook configuration + +Add the following configuration to your `inventory/host_vars/matrix.DOMAIN/vars.yml` file (adapt to your needs): + +```yaml +# Enabling it is the only required setting +matrix_ntfy_enabled: true + +# Some other options +matrix_server_fqn_ntfy: "ntfy.{{ matrix_domain }}" +matrix_ntfy_configuration_extension_yaml: | + log_level: DEBUG +``` + +For a more complete list of variables that you could override, see `roles/matrix/matrix-ntfy/defaults/main.yml`. + +For a complete list of ntfy config options that you could put in `matrix_ntfy_configuration_extension_yaml`, see the [ntfy config documentation](https://ntfy.sh/docs/config/#config-options). + + +## Installing + +Don't forget to add `ntfy.` to DNS as described in [Configuring DNS](configuring-dns.md) before running the playbook. + +After configuring the playbook, run the [installation](installing.md) command again: + +``` +ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start +``` + + +## Usage + +To make use of your ntfy installation, on Android for example, you need two things: + +* the `ntfy` app +* a UnifiedPush-compatible matrix app + +You need to install the `ntfy` app on each device on which you want to receive push notifications through your ntfy server. The `ntfy` app will provide UnifiedPush notifications to any number of UnifiedPush-compatible messaging apps installed on the same device. + +### Setting up the `ntfy` Android app + +1. Install the [ntfy Android app](https://ntfy.sh/docs/subscribe/phone/) from F-droid or Google Play. +2. In its Settings -> `General: Default server`, enter your ntfy server URL, such as `https://ntfy.DOMAIN`. +3. In its Settings -> `Advanced: Connection protocol`, choose `WebSockets`. + +That is all you need to do in the ntfy app. It has many other features, but for our purposes you can ignore them. In particular you do not need to follow any instructions about subscribing to a notification topic as UnifiedPush will do that automatically. + +### Setting up a UnifiedPush-compatible matrix app + +Install any UnifiedPush-enabled matrix app on that same device. The matrix app will learn from the `ntfy` app that you have configured UnifiedPush on this device, and then it will tell your matrix server to use it. + +Steps needed for specific matrix apps: + +* FluffyChat-android: + - Should auto-detect and use it. No manual settings. + +* SchildiChat-android: + 1. enable `Settings` -> `Notifications` -> `UnifiedPush: Force custom push gateway`. + 2. choose `Settings` -> `Notifications` -> `UnifiedPush: Re-register push distributor`. *(For info, a more complex alternative to achieve the same is: delete the relevant unifiedpush registration in `ntfy` app, force-close SchildiChat, re-open it.)* + 3. verify `Settings` -> `Notifications` -> `UnifiedPush: Notification targets` as described below in the "Troubleshooting" section. + +* Element-android v1.4.26+: + 1. choose `Settings` -> `Notifications` -> `Notification method` -> `ntfy` + 2. verify `Settings` -> `Troubleshoot` -> `Troubleshoot notification settings` + +If the matrix app asks, "Choose a distributor: FCM Fallback or ntfy", then choose "ntfy". + +If the matrix app doesn't seem to pick it up, try restarting it and try the Troubleshooting section below. + + +## Troubleshooting + +First check that the matrix client app you are using supports UnifiedPush. There may well be different variants of the app. + +Set the ntfy server's log level to 'DEBUG', as shown in the example settings above, and watch the server's logs with `sudo journalctl -fu matrix-ntfy`. + +To check if UnifiedPush is correctly configured on the client device, look at "Settings -> Notifications -> Notification Targets" in Element-Android or SchildiChat, or "Settings -> Notifications -> Devices" in FluffyChat. There should be one entry for each matrix client app that has enabled push notifications, and when that client is using UnifiedPush you should see a URL that begins with your ntfy server's URL. + +In the "Notification Targets" screen in Element-Android or SchildiChat, two relevant URLs are shown, "push\_key" and "Url", and both should begin with your ntfy server's URL. If "push\_key" shows your server but "Url" shows an external server such as `up.schildi.chat` then push notifications will still work but are being routed through that external server before they reach your ntfy server. To rectify that, in SchildiChat (at least around version 1.4.20.sc55) you must enable the `Force custom push gateway` setting as described in the "Usage" section above. + +If it is not working, useful tools are "Settings -> Notifications -> Re-register push distributor" and "Settings -> Notifications -> Troubleshoot Notifications" in SchildiChat (possibly also Element-Android). In particular the "Endpoint/FCM" step of that troubleshooter should display your ntfy server's URL that it has discovered from the ntfy client app. + +The simple [UnifiedPush troubleshooting](https://unifiedpush.org/users/troubleshooting/) app [UP-Example](https://f-droid.org/en/packages/org.unifiedpush.example/) can be used to manually test UnifiedPush registration and operation on an Android device. diff --git a/docs/configuring-playbook-own-webserver.md b/docs/configuring-playbook-own-webserver.md new file mode 100644 index 0000000..9646b73 --- /dev/null +++ b/docs/configuring-playbook-own-webserver.md @@ -0,0 +1,252 @@ +# Using your own webserver, instead of this playbook's nginx proxy (optional, advanced) + +By default, this playbook installs its own nginx webserver (called `matrix-nginx-proxy`, in a Docker container) which listens on ports 80 and 443. +If that's alright, you can skip this. + +If you don't want this playbook's nginx webserver to take over your server's 80/443 ports like that, +and you'd like to use your own webserver (be it nginx, Apache, Varnish Cache, etc.), you can. + +You should note, however, that the playbook's services work best when you keep using the integrated `matrix-nginx-proxy` webserver. +For example, disabling `matrix-nginx-proxy` when running a [Synapse worker setup for load-balancing](configuring-playbook-synapse.md#load-balancing-with-workers) (a more advanced, non-default configuration) is likely to cause various troubles (see [this issue](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/2090)). If you need a such more scalable setup, disabling `matrix-nginx-proxy` will be a bad idea. If yours will be a simple (default, non-worker-load-balancing) deployment, disabling `matrix-nginx-proxy` may be fine. + +There are **2 ways you can go about it**, if you'd like to use your own webserver: + +- [Method 1: Disabling the integrated nginx reverse-proxy webserver](#method-1-disabling-the-integrated-nginx-reverse-proxy-webserver) + +- [Method 2: Fronting the integrated nginx reverse-proxy webserver with another reverse-proxy](#method-2-fronting-the-integrated-nginx-reverse-proxy-webserver-with-another-reverse-proxy) + + +## Method 1: Disabling the integrated nginx reverse-proxy webserver + +This method is about completely disabling the integrated nginx reverse-proxy webserver and replicating its behavior using another webserver. +For an alternative, make sure to check Method #2 as well. + +### Preparation + +No matter which external webserver you decide to go with, you'll need to: + +1) Make sure your web server user (something like `http`, `apache`, `www-data`, `nginx`) is part of the `matrix` group. You should run something like this: `usermod -a -G matrix nginx`. This allows your webserver user to access files owned by the `matrix` group. When using an external nginx webserver, this allows it to read configuration files from `/matrix/nginx-proxy/conf.d`. When using another server, it would make other files, such as `/matrix/static-files/.well-known`, accessible to it. + +2) Edit your configuration file (`inventory/host_vars/matrix./vars.yml`) + - to disable the integrated nginx server: + + ```yaml + matrix_nginx_proxy_enabled: false + ``` + - if using an external server on another host, add the `_http_host_bind_port` or `_http_bind_port` variables for the services that will be exposed by the external server on the other host. The actual name of the variable is listed in the `roles//defaults/vars.yml` file for each service. Most variables follow the `_http_host_bind_port` format. + + These variables will make Docker expose the ports on all network interfaces instead of localhost only. + [Keep in mind that there are some security concerns if you simply proxy everything.](https://github.com/matrix-org/synapse/blob/master/docs/reverse_proxy.md#synapse-administration-endpoints) + + Here are the variables required for the default configuration (Synapse and Element) + ``` + matrix_synapse_reverse_proxy_companion_container_client_api_host_bind_port: '0.0.0.0:8008' + matrix_synapse_reverse_proxy_companion_container_federation_api_host_bind_port: '0.0.0.0:8048' + matrix_client_element_container_http_host_bind_port: "0.0.0.0:8765" + ``` + +3) **If you'll manage SSL certificates by yourself**, edit your configuration file (`inventory/host_vars/matrix./vars.yml`) to disable SSL certificate retrieval: + +```yaml +matrix_ssl_retrieval_method: none +``` + +**Note**: During [installation](installing.md), unless you've disabled SSL certificate management (`matrix_ssl_retrieval_method: none`), the playbook would need 80 to be available, in order to retrieve SSL certificates. **Please manually stop your other webserver while installing**. You can start it back up afterwards. + +### Using your own external nginx webserver + +Once you've followed the [Preparation](#preparation) guide above, it's time to set up your external nginx server. + +Even with `matrix_nginx_proxy_enabled: false`, the playbook still generates some helpful files for you in `/matrix/nginx-proxy/conf.d`. +Those configuration files are adapted for use with an external web server (one not running in the container network). + +You can most likely directly use the config files installed by this playbook at: `/matrix/nginx-proxy/conf.d`. Just include them in your own `nginx.conf` like this: `include /matrix/nginx-proxy/conf.d/*.conf;` + +Note that if your nginx version is old, it might not like our default choice of SSL protocols (particularly the fact that the brand new `TLSv1.3` protocol is enabled). You can override the protocol list by redefining the `matrix_nginx_proxy_ssl_protocols` variable. Example: + +```yaml +# Custom protocol list (removing `TLSv1.3`) to suit your nginx version. +matrix_nginx_proxy_ssl_protocols: "TLSv1.2" +``` + +If you are experiencing issues, try updating to a newer version of Nginx. As a data point in May 2021 a user reported that Nginx 1.14.2 was not working for them. They were getting errors about socket leaks. Updating to Nginx 1.19 fixed their issue. + +### Using your own external Apache webserver + +Once you've followed the [Preparation](#preparation) guide above, you can take a look at the [examples/apache](../examples/apache) directory for a sample configuration. + +### Using your own external caddy webserver + +After following the [Preparation](#preparation) guide above, you can take a look at the [examples/caddy](../examples/caddy) directory and [examples/caddy2](../examples/caddy2) directory for a sample configuration for Caddy v1 and v2, respectively. + +### Using your own HAproxy reverse proxy +After following the [Preparation](#preparation) guide above, you can take a look at the [examples/haproxy](../examples/haproxy) directory for a sample configuration. In this case HAproxy is used as a reverse proxy and a simple Nginx container is used to serve statically `.well-known` files. + +### Using another external webserver + +Feel free to look at the [examples/apache](../examples/apache) directory, or the [template files in the matrix-nginx-proxy role](../roles/nginx-proxy/templates/nginx/conf.d/). + + +## Method 2: Fronting the integrated nginx reverse-proxy webserver with another reverse-proxy + +This method is about leaving the integrated nginx reverse-proxy webserver be, but making it not get in the way (using up important ports, trying to retrieve SSL certificates, etc.). + +If you wish to use another webserver, the integrated nginx reverse-proxy webserver usually gets in the way because it attempts to fetch SSL certificates and binds to ports 80, 443 and 8448 (if Matrix Federation is enabled). + +You can disable such behavior and make the integrated nginx reverse-proxy webserver only serve traffic locally (or over a local network). + +You would need some configuration like this: + +```yaml +# Do not retrieve SSL certificates. This shall be managed by another webserver or other means. +matrix_ssl_retrieval_method: none + +# Do not try to serve HTTPS, since we have no SSL certificates. +# Disabling this also means services will be served on the HTTP port +# (`matrix_nginx_proxy_container_http_host_bind_port`). +matrix_nginx_proxy_https_enabled: false + +# Do not listen for HTTP on port 80 globally (default), listen on the loopback interface. +# If you'd like, you can make it use the local network as well and reverse-proxy from another local machine. +matrix_nginx_proxy_container_http_host_bind_port: '127.0.0.1:81' + +# Likewise, expose the Matrix Federation port on the loopback interface. +# Since `matrix_nginx_proxy_https_enabled` is set to `false`, this federation port will serve HTTP traffic. +# If you'd like, you can make it use the local network as well and reverse-proxy from another local machine. +# +# You'd most likely need to expose it publicly on port 8448 (8449 was chosen for the local port to prevent overlap). +matrix_nginx_proxy_container_federation_host_bind_port: '127.0.0.1:8449' + +# Coturn relies on SSL certificates that have already been obtained. +# Since we don't obtain any certificates (`matrix_ssl_retrieval_method: none` above), it won't work by default. +# An alternative is to tweak some of: `matrix_coturn_tls_enabled`, `matrix_coturn_tls_cert_path` and `matrix_coturn_tls_key_path`. +matrix_coturn_enabled: false + +# Trust the reverse proxy to send the correct `X-Forwarded-Proto` header as it is handling the SSL connection. +matrix_nginx_proxy_trust_forwarded_proto: true + +# Trust and use the other reverse proxy's `X-Forwarded-For` header. +matrix_nginx_proxy_x_forwarded_for: '$proxy_add_x_forwarded_for' +``` + +With this, nginx would still be in use, but it would not bother with anything SSL related or with taking up public ports. + +All services would be served locally on `127.0.0.1:81` and `127.0.0.1:8449` (as per the example configuration above). + +You can then set up another reverse-proxy server on ports 80/443/8448 for all of the expected domains and make traffic go to these local ports. +The expected domains vary depending on the services you have enabled (`matrix.DOMAIN` for sure; `element.DOMAIN`, `dimension.DOMAIN` and `jitsi.DOMAIN` are optional). + +### Sample configuration for running behind Traefik 2.0 + +Below is a sample configuration for using this playbook with a [Traefik](https://traefik.io/) 2.0 reverse proxy. + +```yaml +# Disable generation and retrieval of SSL certs +matrix_ssl_retrieval_method: none + +# Configure Nginx to only use plain HTTP +matrix_nginx_proxy_https_enabled: false + +# Don't bind any HTTP or federation port to the host +# (Traefik will proxy directly into the containers) +matrix_nginx_proxy_container_http_host_bind_port: '' +matrix_nginx_proxy_container_federation_host_bind_port: '' + +# Trust the reverse proxy to send the correct `X-Forwarded-Proto` header as it is handling the SSL connection. +matrix_nginx_proxy_trust_forwarded_proto: true + +# Trust and use the other reverse proxy's `X-Forwarded-For` header. +matrix_nginx_proxy_x_forwarded_for: '$proxy_add_x_forwarded_for' + +# Disable Coturn because it needs SSL certs +# (Clients can, though exposing IP address, use Matrix.org TURN) +matrix_coturn_enabled: false + +# All containers need to be on the same Docker network as Traefik +# (This network should already exist and Traefik should be using this network) +matrix_docker_network: 'traefik' + +matrix_nginx_proxy_container_extra_arguments: + # May be unnecessary depending on Traefik config, but can't hurt + - '--label "traefik.enable=true"' + + # The Nginx proxy container will receive traffic from these subdomains + - '--label "traefik.http.routers.matrix-nginx-proxy.rule=Host(`{{ matrix_server_fqn_matrix }}`,`{{ matrix_server_fqn_element }}`,`{{ matrix_server_fqn_dimension }}`,`{{ matrix_server_fqn_jitsi }}`)"' + # (The 'web-secure' entrypoint must bind to port 443 in Traefik config) + - '--label "traefik.http.routers.matrix-nginx-proxy.entrypoints=web-secure"' + # (The 'default' certificate resolver must be defined in Traefik config) + - '--label "traefik.http.routers.matrix-nginx-proxy.tls.certResolver=default"' + # Traefik requires that we declare which service this router is using + - '--label "traefik.http.routers.matrix-nginx-proxy.service=matrix-nginx-proxy"' + # The Nginx proxy container uses port 8080 internally + - '--label "traefik.http.services.matrix-nginx-proxy.loadbalancer.server.port=8080"' + + # Federation + - '--label "traefik.http.routers.matrix-nginx-proxy-federation.rule=Host(`{{ matrix_server_fqn_matrix }}`)"' + # (The 'federation' entrypoint must bind to port 8448 in Traefik config) + - '--label "traefik.http.routers.matrix-nginx-proxy-federation.entrypoints=federation"' + # (The 'default' certificate resolver must be defined in Traefik config) + - '--label "traefik.http.routers.matrix-nginx-proxy-federation.tls.certResolver=default"' + # Traefik requires that we declare which service this router is using + - '--label "traefik.http.routers.matrix-nginx-proxy-federation.service=matrix-nginx-proxy-federation"' + # The Nginx proxy container uses port `matrix_nginx_proxy_proxy_matrix_federation_port (8448) internally + - '--label "traefik.http.services.matrix-nginx-proxy-federation.loadbalancer.server.port={{ matrix_nginx_proxy_proxy_matrix_federation_port }}"' + - '--label "traefik.http.services.matrix-nginx-proxy-federation.loadbalancer.server.scheme={{ "https" if matrix_nginx_proxy_https_enabled else "http" }}"' +``` + +This method uses labels attached to the Nginx and Synapse containers to provide the Traefik Docker provider with the information it needs to proxy `matrix.DOMAIN`, `element.DOMAIN`, `dimension.DOMAIN` and `jitsi.DOMAIN`. Some [static configuration](https://docs.traefik.io/v2.0/reference/static-configuration/file/) is required in Traefik; namely, having endpoints on ports 443 and 8448 and having a certificate resolver. + +Note that this configuration on its own does **not** redirect traffic on port 80 (plain HTTP) to port 443 for HTTPS, which may cause some issues, since the built-in Nginx proxy usually does this. If you are not already doing this in Traefik, it can be added to Traefik in a [file provider](https://docs.traefik.io/v2.0/providers/file/) as follows: + +```toml +[http] + [http.routers] + [http.routers.redirect-http] + entrypoints = ["web"] # The 'web' entrypoint must bind to port 80 + rule = "HostRegexp(`{host:.+}`)" # Change if you don't want to redirect all hosts to HTTPS + service = "dummy" # Unused, but all routers need services (for now) + middlewares = ["https"] + [http.services] + [http.services.dummy.loadbalancer] + [[http.services.dummy.loadbalancer.servers]] + url = "localhost" + [http.middlewares] + [http.middlewares.https.redirectscheme] + scheme = "https" + permanent = true +``` + +You can use the following `docker-compose.yml` as example to launch Traefik. + +```yaml +version: "3.3" + +services: + + traefik: + image: "traefik:v2.3" + restart: always + container_name: "traefik" + networks: + - traefik + command: + - "--api.insecure=true" + - "--providers.docker=true" + - "--providers.docker.network=traefik" + - "--providers.docker.exposedbydefault=false" + - "--entrypoints.web-secure.address=:443" + - "--entrypoints.federation.address=:8448" + - "--certificatesresolvers.default.acme.tlschallenge=true" + - "--certificatesresolvers.default.acme.email=YOUR EMAIL" + - "--certificatesresolvers.default.acme.storage=/letsencrypt/acme.json" + ports: + - "443:443" + - "8448:8448" + volumes: + - "./letsencrypt:/letsencrypt" + - "/var/run/docker.sock:/var/run/docker.sock:ro" + +networks: + traefik: + external: true +``` diff --git a/docs/configuring-playbook-postgres-backup.md b/docs/configuring-playbook-postgres-backup.md new file mode 100644 index 0000000..2510ecc --- /dev/null +++ b/docs/configuring-playbook-postgres-backup.md @@ -0,0 +1,36 @@ +# Setting up postgres backup (optional) + +The playbook can install and configure [docker-postgres-backup-local](https://github.com/prodrigestivill/docker-postgres-backup-local) for you via the [com.devture.ansible.role.postgres_backup](https://github.com/devture/com.devture.ansible.role.postgres_backup) Ansible role. + +For a more complete backup solution (one that includes not only Postgres, but also other configuration/data files), you may wish to look into [borg backup](configuring-playbook-backup-borg.md) instead. + + +## Adjusting the playbook configuration + +Minimal working configuration (`inventory/host_vars/matrix.DOMAIN/vars.yml`) to enable Postgres backup: + +```yaml +devture_postgres_backup_enabled: true +``` + +Refer to the table below for additional configuration variables and their default values. + + +| Name | Default value | Description | +| :-------------------------------- | :--------------------------- | :--------------------------------------------------------------- | +|`devture_postgres_backup_enabled`|`false`|Set to true to use [docker-postgres-backup-local](https://github.com/prodrigestivill/docker-postgres-backup-local) to create automatic database backups| +|`devture_postgres_backup_schedule`| `'@daily'` |Cron-schedule specifying the interval between postgres backups.| +|`devture_postgres_backup_keep_days`|`7`|Number of daily backups to keep| +|`devture_postgres_backup_keep_weeks`|`4`|Number of weekly backups to keep| +|`devture_postgres_backup_keep_months`|`12`|Number of monthly backups to keep| +|`devture_postgres_base_path` | `"{{ matrix_base_data_path }}/postgres-backup"` | Base path for postgres-backup. Also see `devture_postgres_data_path` | +|`devture_postgres_data_path` | `"{{ devture_postgres_base_path }}/data"` | Storage path for postgres-backup database backups | + + +## Installing + +After configuring the playbook, run the [installation](installing.md) command again: + +``` +ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start +``` diff --git a/docs/configuring-playbook-prometheus-grafana.md b/docs/configuring-playbook-prometheus-grafana.md new file mode 100644 index 0000000..0b785c3 --- /dev/null +++ b/docs/configuring-playbook-prometheus-grafana.md @@ -0,0 +1,138 @@ +# Enabling metrics and graphs for your Matrix server (optional) + +It can be useful to have some (visual) insight into the performance of your homeserver. + +You can enable this with the following settings in your configuration file (`inventory/host_vars/matrix./vars.yml`): + +Remember to add `stats.` to DNS as described in [Configuring DNS](configuring-dns.md) before running the playbook. + +```yaml +matrix_prometheus_enabled: true + +# You can remove this, if unnecessary. +matrix_prometheus_node_exporter_enabled: true + +# You can remove this, if unnecessary. +matrix_prometheus_postgres_exporter_enabled: true + +# You can remove this, if unnecessary. +matrix_prometheus_nginxlog_exporter_enabled: true + +matrix_grafana_enabled: true + +matrix_grafana_anonymous_access: false + +# This has no relation to your Matrix user id. It can be any username you'd like. +# Changing the username subsequently won't work. +matrix_grafana_default_admin_user: "some_username_chosen_by_you" + +# Changing the password subsequently won't work. +matrix_grafana_default_admin_password: "some_strong_password_chosen_by_you" +``` + +By default, a [Grafana](https://grafana.com/) web user-interface will be available at `https://stats.`. + +The retention policy of Prometheus metrics is [15 days by default](https://prometheus.io/docs/prometheus/latest/storage/#operational-aspects). Older data gets deleted automatically. + + +## What does it do? + +Name | Description +-----|---------- +`matrix_prometheus_enabled`|[Prometheus](https://prometheus.io) is a time series database. It holds all the data we're going to talk about. +`matrix_prometheus_node_exporter_enabled`|[Node Exporter](https://prometheus.io/docs/guides/node-exporter/) is an addon of sorts to Prometheus that collects generic system information such as CPU, memory, filesystem, and even system temperatures +`matrix_prometheus_postgres_exporter_enabled`|[Postgres Exporter](configuring-playbook-prometheus-postgres.md) is an addon of sorts to expose Postgres database metrics to Prometheus. +`matrix_prometheus_nginxlog_exporter_enabled`|[NGINX Log Exporter](configuring-playbook-prometheus-nginxlog.md) is an addon of sorts to expose NGINX logs to Prometheus. +`matrix_grafana_enabled`|[Grafana](https://grafana.com/) is the visual component. It shows (on the `stats.` subdomain) the dashboards with the graphs that we're interested in +`matrix_grafana_anonymous_access`|By default you need to log in to see graphs. If you want to publicly share your graphs (e.g. when asking for help in [`#synapse:matrix.org`](https://matrix.to/#/#synapse:matrix.org?via=matrix.org&via=privacytools.io&via=mozilla.org)) you'll want to enable this option. +`matrix_grafana_default_admin_user`
`matrix_grafana_default_admin_password`|By default Grafana creates a user with `admin` as the username and password. If you feel this is insecure and you want to change it beforehand, you can do that here + + +## Security and privacy + +Metrics and resulting graphs can contain a lot of information. This includes system specs but also usage patterns. This applies especially to small personal/family scale homeservers. Someone might be able to figure out when you wake up and go to sleep by looking at the graphs over time. Think about this before enabling anonymous access. And you should really not forget to change your Grafana password. + +Most of our docker containers run with limited system access, but the `prometheus-node-exporter` has access to the host network stack and (readonly) root filesystem. This is required to report on them. If you don't like that, you can set `matrix_prometheus_node_exporter_enabled: false` (which is actually the default). You will still get Synapse metrics with this container disabled. Both of the dashboards will always be enabled, so you can still look at historical data after disabling either source. + + +## Collecting metrics to an external Prometheus server + +**If the integrated Prometheus server is enabled** (`matrix_prometheus_enabled: true`), metrics are collected by it from each service via communication that happens over the container network. Each service does not need to expose its metrics "publicly". + +When you'd like **to collect metrics from an external Prometheus server**, you need to expose service metrics outside of the container network. + +The playbook provides a single endpoint (`https://matrix.DOMAIN/metrics/*`), under which various services may expose their metrics (e.g. `/metrics/node-exporter`, `/metrics/postgres-exporter`, `/metrics/hookshot`, etc). To enable this `/metrics/*` feature, use `matrix_nginx_proxy_proxy_matrix_metrics_enabled`. To protect access using [Basic Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication), see `matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_enabled` below. + +The following variables may be of interest: + +Name | Description +-----|---------- +`matrix_nginx_proxy_proxy_matrix_metrics_enabled`|Set this to `true` to enable metrics exposure for various services on `https://matrix.DOMAIN/metrics/*`. Refer to the individual `matrix_SERVICE_metrics_proxying_enabled` variables below for exposing metrics for each individual service. +`matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_enabled`|Set this to `true` to protect all `https://matrix.DOMAIN/metrics/*` endpoints with [Basic Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication) (see the other variables below for supplying the actual credentials). When enabled, all endpoints beneath `/metrics` will be protected with the same credentials +`matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_username`|Set this to the Basic Authentication username you'd like to protect `/metrics/*` with. You also need to set `matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_password`. If one username/password pair is not enough, you can leave the `username` and `password` variables unset and use `matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_raw_content` instead +`matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_password`|Set this to the Basic Authentication password you'd like to protect `/metrics/*` with +`matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_raw_content`|Set this to the Basic Authentication credentials (raw `htpasswd` file content) used to protect `/metrics/*`. This htpasswd-file needs to be generated with the `htpasswd` tool and can include multiple username/password pairs. If you only need one credential, use `matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_username` and `matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_password` instead. +`matrix_synapse_metrics_enabled`|Set this to `true` to make Synapse expose metrics (locally, on the container network) +`matrix_synapse_metrics_proxying_enabled`|Set this to `true` to expose Synapse's metrics on `https://matrix.DOMAIN/metrics/synapse/main-process` and `https://matrix.DOMAIN/metrics/synapse/worker/TYPE-ID` (only takes effect if `matrix_nginx_proxy_proxy_matrix_metrics_enabled: true`). Read [below](#collecting-synapse-worker-metrics-to-an-external-prometheus-server) if you're running a Synapse worker setup (`matrix_synapse_workers_enabled: true`). +`matrix_prometheus_node_exporter_enabled`|Set this to `true` to enable the node (general system stats) exporter (locally, on the container network) +`matrix_prometheus_node_exporter_metrics_proxying_enabled`|Set this to `true` to expose the node (general system stats) metrics on `https://matrix.DOMAIN/metrics/node-exporter` (only takes effect if `matrix_nginx_proxy_proxy_matrix_metrics_enabled: true`) +`matrix_prometheus_postgres_exporter_enabled`|Set this to `true` to enable the [Postgres exporter](configuring-playbook-prometheus-postgres.md) (locally, on the container network) +`matrix_prometheus_nginxlog_exporter_enabled`|Set this to `true` to enable the [NGINX Log exporter](configuring-playbook-prometheus-nginxlog.md) (locally, on the container network) +`matrix_prometheus_postgres_exporter_metrics_proxying_enabled`|Set this to `true` to expose the [Postgres exporter](configuring-playbook-prometheus-postgres.md) metrics on `https://matrix.DOMAIN/metrics/postgres-exporter` (only takes effect if `matrix_nginx_proxy_proxy_matrix_metrics_enabled: true`) +`matrix_bridge_hookshot_metrics_enabled`|Set this to `true` to make [Hookshot](configuring-playbook-bridge-hookshot.md) expose metrics (locally, on the container network) +`matrix_bridge_hookshot_metrics_proxying_enabled`|Set this to `true` to expose the [Hookshot](configuring-playbook-bridge-hookshot.md) metrics on `https://matrix.DOMAIN/metrics/hookshot` (only takes effect if `matrix_nginx_proxy_proxy_matrix_metrics_enabled: true`) +`matrix_SERVICE_metrics_proxying_enabled`|Various other services/roles may provide similar `_metrics_enabled` and `_metrics_proxying_enabled` variables for exposing their metrics. Refer to each role for details. Only takes effect if `matrix_nginx_proxy_proxy_matrix_metrics_enabled: true` +`matrix_nginx_proxy_proxy_matrix_metrics_additional_user_location_configuration_blocks`|Add nginx `location` blocks to this list if you'd like to expose additional exporters manually (see below) + +Example for how to make use of `matrix_nginx_proxy_proxy_matrix_metrics_additional_user_location_configuration_blocks` for exposing additional metrics locations: +```nginx +matrix_nginx_proxy_proxy_matrix_metrics_additional_user_location_configuration_blocks: + - 'location /metrics/another-service { + resolver 127.0.0.11 valid=5s; + proxy_pass http://matrix-another-service:9100/metrics; + }' +``` + +Using `matrix_nginx_proxy_proxy_matrix_metrics_additional_user_location_configuration_blocks` only takes effect if `matrix_nginx_proxy_proxy_matrix_metrics_enabled: true` (see above). + +Note : The playbook will hash the basic_auth password for you on setup. Thus, you need to give the plain-text version of the password as a variable. + +### Collecting Synapse worker metrics to an external Prometheus server + +If you are using workers (`matrix_synapse_workers_enabled: true`) and have enabled `matrix_synapse_metrics_proxying_enabled` as described above, the playbook will also automatically expose all Synapse worker threads' metrics to `https://matrix.DOMAIN/metrics/synapse/worker/ID`, where `ID` corresponds to the worker `id` as exemplified in `matrix_synapse_workers_enabled_list`. + +The playbook also generates an exemplary config file (`/matrix/synapse/external_prometheus.yml.template`) with all the correct paths which you can copy to your Prometheus server and adapt to your needs. Make sure to edit the specified `password_file` path and contents and path to your `synapse-v2.rules`. +It will look a bit like this: +```yaml +scrape_configs: + - job_name: 'synapse' + metrics_path: /metrics/synapse/main-process + scheme: https + basic_auth: + username: prometheus + password_file: /etc/prometheus/password.pwd + static_configs: + - targets: ['matrix.DOMAIN:443'] + labels: + job: "master" + index: 1 + - job_name: 'matrix-synapse-synapse-worker-generic-worker-0' + metrics_path: /metrics/synapse/worker/generic-worker-0 + scheme: https + basic_auth: + username: prometheus + password_file: /etc/prometheus/password.pwd + static_configs: + - targets: ['matrix.DOMAIN:443'] + labels: + job: "generic_worker" + index: 18111 +``` + + +## More information + +- [Understanding Synapse Performance Issues Through Grafana Graphs](https://github.com/matrix-org/synapse/wiki/Understanding-Synapse-Performance-Issues-Through-Grafana-Graphs) at the Synapse Github Wiki +- [The Prometheus scraping rules](https://github.com/matrix-org/synapse/tree/master/contrib/prometheus) (we use v2) +- [The Synapse Grafana dashboard](https://github.com/matrix-org/synapse/tree/master/contrib/grafana) +- [The Node Exporter dashboard](https://github.com/rfrail3/grafana-dashboards) (for generic non-synapse performance graphs) diff --git a/docs/configuring-playbook-prometheus-nginxlog.md b/docs/configuring-playbook-prometheus-nginxlog.md new file mode 100644 index 0000000..832efbd --- /dev/null +++ b/docs/configuring-playbook-prometheus-nginxlog.md @@ -0,0 +1,59 @@ +# Enabling metrics and graphs for NginX logs (optional) + +It can be useful to have some (visual) insight into NignX logs. + +This adds [prometheus-nginxlog-exporter](https://github.com/martin-helmich/prometheus-nginxlog-exporter/) to your matrix deployment. +It will provide a prometheus 'metrics' endpoint exposing data from both the `matrix-nginx-proxy` and `matrix-synapse-reverse-proxy-companion` logs and automatically aggregates the data with prometheus. +Optionally it visualizes the data, if [`matrix-grafana`](configuring-playbook-prometheus-grafana.md) is enabled, by means of a dedicated Grafana dashboard named `NGINX PROXY` + +You can enable this role by adding the following settings in your configuration file (`inventory/host_vars/matrix./vars.yml`): + +```yaml +matrix_prometheus_nginxlog_exporter_enabled: true + +# required depency +matrix_prometheus_enabled: true + +# optional for visualization +matrix_grafana_enabled: true +``` + +x | Prerequisites | Variable | Description +|:--:|:--:|:--:|:--| +**REQUIRED** | `matrix-prometheus`| `matrix_prometheus_enabled`|[Prometheus](https://prometheus.io) is a time series database. It holds all the data we're going to talk about. +_Optional_ | [`matrix-grafana`](configuring-playbook-prometheus-grafana.md) | [`matrix_grafana_enabled`](configuring-playbook-prometheus-grafana.md)|[Grafana](https://grafana.com) is the visual component. It shows (on the `stats.` subdomain) graphs that we're interested in. When enabled the `NGINX PROXY` dashboard is automatically added. + +## Docker Image Compatibility + +At the moment of writing only images for `amd64` and `arm64` architectures are available + +The playbook currently does not support building an image. +You can however use a custom-build image by setting +```yaml +matrix_prometheus_nginxlog_exporter_docker_image_arch_check_enabled: false +matrix_prometheus_nginxlog_exporter_docker_image: path/to/docker/image:tag +``` + +## Security and privacy + +Metrics and resulting graphs can contain a lot of information. NginX logs contain information like IP address, URLs, UserAgents and more. This information can reveal usage patterns and could be considered Personally Identifiable Information (PII). Think about this before enabling (anonymous) access. +Please make sure you change the default Grafana password. + +## Save metrics on an external Prometheus server + +The playbook will automatically integrate the metrics into the Prometheus server provided with this playbook. You can choose to save data on an external Prometheus instance. + +The metrics of this role will be exposed on `https://matrix.DOMAIN/metrics/nginxlog` when setting +```yaml +matrix_prometheus_nginxlog_exporter_metrics_proxying_enabled: true + +# required dependency +matrix_nginx_proxy_proxy_matrix_metrics_enabled: true +``` +The playbook can provide a single endpoint (`https://matrix.DOMAIN/metrics/*`), under which various services may expose their metrics (e.g. `/metrics/node-exporter`, `/metrics/postgres-exporter`, `/metrics/nginxlog`, etc). To enable this `/metrics/*` feature, use `matrix_nginx_proxy_proxy_matrix_metrics_enabled`. To protect access using [Basic Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication), see `matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_enabled`. + +The following variables may be of interest: + +Name | Description +-----|---------- +`matrix_nginx_proxy_proxy_matrix_metrics_enabled`|Set this to `true` to enable metrics exposure for various services on `https://matrix.DOMAIN/metrics/*`. Refer to the individual `matrix_SERVICE_metrics_proxying_enabled` variables below for exposing metrics for each individual service. \ No newline at end of file diff --git a/docs/configuring-playbook-prometheus-postgres.md b/docs/configuring-playbook-prometheus-postgres.md new file mode 100644 index 0000000..6fd13a9 --- /dev/null +++ b/docs/configuring-playbook-prometheus-postgres.md @@ -0,0 +1,25 @@ +# Enabling metrics and graphs for Postgres (optional) + +Expanding on the metrics exposed by the [synapse exporter and the node exporter](configuring-playbook-prometheus-grafana.md), the playbook enables the [postgres exporter](https://github.com/prometheus-community/postgres_exporter) that exposes more detailed information about what's happening on your postgres database. + +You can enable this with the following settings in your configuration file (`inventory/host_vars/matrix./vars.yml`): + + +```yaml +matrix_prometheus_postgres_exporter_enabled: true +``` + +## What does it do? + +Name | Description +-----|---------- +`matrix_prometheus_postgres_exporter_enabled`|Enable the postgres prometheus exporter. This sets up the docker container, connects it to the database and adds a 'job' to the prometheus config which tells prometheus about this new exporter. The default is 'false' +`matrix_prometheus_postgres_exporter_database_username`| The 'username' for the user that the exporter uses to connect to the database. The default is 'matrix_prometheus_postgres_exporter' +`matrix_prometheus_postgres_exporter_database_password`| The 'password' for the user that the exporter uses to connect to the database. By default, this is auto-generated by the playbook +`matrix_prometheus_postgres_exporter_metrics_proxying_enabled`|If set to `true`, exposes the Postgres exporter metrics on `https://matrix.DOMAIN/metrics/postgres-exporter` for usage with an [external Prometheus server](configuring-playbook-prometheus-grafana.md#collecting-metrics-to-an-external-prometheus-server) (only takes effect if `matrix_nginx_proxy_proxy_matrix_metrics_enabled: true`) + + +## More information + +- [The PostgresSQL dashboard](https://grafana.com/grafana/dashboards/9628) (generic postgres dashboard) + diff --git a/docs/configuring-playbook-rest-auth.md b/docs/configuring-playbook-rest-auth.md new file mode 100644 index 0000000..23644c9 --- /dev/null +++ b/docs/configuring-playbook-rest-auth.md @@ -0,0 +1,24 @@ +# Setting up the REST authentication password provider module (optional, advanced) + +The playbook can install and configure [matrix-synapse-rest-auth](https://github.com/ma1uta/matrix-synapse-rest-password-provider) for you. + +See that project's documentation to learn what it does and why it might be useful to you. + +If you decide that you'd like to let this playbook install it for you, you need some configuration like this: + +```yaml +matrix_synapse_ext_password_provider_rest_auth_enabled: true +matrix_synapse_ext_password_provider_rest_auth_endpoint: "http://matrix-ma1sd:8090" +matrix_synapse_ext_password_provider_rest_auth_registration_enforce_lowercase: false +matrix_synapse_ext_password_provider_rest_auth_registration_profile_name_autofill: true +matrix_synapse_ext_password_provider_rest_auth_login_profile_name_autofill: false +``` + + +## Authenticating only using a password provider + +If you wish for users to **authenticate only against configured password providers** (like this one), **without consulting Synapse's local database**, feel free to disable it: + +```yaml +matrix_synapse_password_config_localdb_enabled: false +``` diff --git a/docs/configuring-playbook-riot-web.md b/docs/configuring-playbook-riot-web.md new file mode 100644 index 0000000..08370e0 --- /dev/null +++ b/docs/configuring-playbook-riot-web.md @@ -0,0 +1,39 @@ +# Configuring Riot-web (optional) + +By default, this playbook **used to install** the [Riot-web](https://github.com/vector-im/riot-web) Matrix client web application. + +Riot has since been [renamed to Element](https://element.io/blog/welcome-to-element/). + +- to learn more about Element and its configuration, see our dedicated [Configuring Element](configuring-playbook-client-element.md) documentation page +- to learn how to migrate from Riot to Element, see [Migrating to Element](#migrating-to-element) below + + +## Migrating to Element + +### Migrating your custom settings + +If you have custom `matrix_riot_web_` variables in your `inventory/host_vars/matrix.DOMAIN/vars.yml` file, you'll need to rename them (`matrix_riot_web_` -> `matrix_client_element_`). + +Some other playbook variables (but not all) with `riot` in their name are also renamed. The playbook checks and warns if you are using the old name for some commonly used ones. + + +### Domain migration + +We used to set up Riot at the `riot.DOMAIN` domain. The playbook now sets up Element at `element.DOMAIN` by default. + +There are a few options for handling this: + +- (**avoiding changes** - using the old `riot.DOMAIN` domain and avoiding DNS changes) -- to keep using `riot.DOMAIN` instead of `element.DOMAIN`, override the domain at which the playbook serves Element: `matrix_server_fqn_element: "riot.{{ matrix_domain }}"` + +- (**embracing changes** - using only `element.DOMAIN`) - set up the `element.DOMAIN` DNS record (see [Configuring DNS](configuring-dns.md)). You can drop the `riot.DOMAIN` in this case. If so, you may also wish to remove old SSL certificates (`rm -rf /matrix/ssl/config/live/riot.DOMAIN`) and renewal configuration (`rm -f /matrix/ssl/config/renewal/riot.DOMAIN.conf`), so that `certbot` would stop trying to renew them. + +- (**embracing changes and transitioning smoothly** - using both `element.DOMAIN` and `riot.DOMAIN`) - to serve Element at the new domain (`element.DOMAIN`) and to also have `riot.DOMAIN` redirect there - set up the `element.DOMAIN` DNS record (see [Configuring DNS](configuring-dns.md)) and enable Riot to Element redirection (`matrix_nginx_proxy_proxy_riot_compat_redirect_enabled: true`). + + +### Re-running the playbook + +As always, after making the necessary DNS and configuration adjustments, re-run the playbook to apply the changes: + +``` +ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start +``` diff --git a/docs/configuring-playbook-s3-goofys.md b/docs/configuring-playbook-s3-goofys.md new file mode 100644 index 0000000..ef8f20c --- /dev/null +++ b/docs/configuring-playbook-s3-goofys.md @@ -0,0 +1,137 @@ +# Storing Matrix media files on Amazon S3 with Goofys (optional) + +If you'd like to store Synapse's content repository (`media_store`) files on Amazon S3 (or other S3-compatible service), +you can let this playbook configure [Goofys](https://github.com/kahing/goofys) for you. + +Another (and better performing) way to use S3 storage with Synapse is [synapse-s3-storage-provider](configuring-playbook-synapse-s3-storage-provider.md). + +Using a Goofys-backed media store works, but performance may not be ideal. If possible, try to use a region which is close to your Matrix server. + +If you'd like to move your locally-stored media store data to Amazon S3 (or another S3-compatible object store), we also provide some migration instructions below. + + +## Usage + +After [creating the S3 bucket and configuring it](configuring-playbook-s3.md#bucket-creation-and-security-configuration), you can proceed to configure Goofys in your configuration file (`inventory/host_vars/matrix./vars.yml`): + +```yaml +matrix_s3_media_store_enabled: true +matrix_s3_media_store_bucket_name: "your-bucket-name" +matrix_s3_media_store_aws_access_key: "access-key-goes-here" +matrix_s3_media_store_aws_secret_key: "secret-key-goes-here" +matrix_s3_media_store_region: "eu-central-1" +``` + +You can use any S3-compatible object store by **additionally** configuring these variables: + +```yaml +matrix_s3_media_store_custom_endpoint_enabled: true +matrix_s3_media_store_custom_endpoint: "https://your-custom-endpoint" +``` + +If you have local media store files and wish to migrate to Backblaze B2 subsequently, follow our [migration guide to Backblaze B2](#migrating-to-backblaze-b2) below instead of applying this configuration as-is. + + +## Migrating from local filesystem storage to S3 + +It's a good idea to [make a complete server backup](faq.md#how-do-i-backup-the-data-on-my-server) before migrating your local media store to an S3-backed one. + +Follow one of the guides below for a migration path from a locally-stored media store to one stored on S3-compatible storage: + +- [Storing Matrix media files on Amazon S3 with Goofys (optional)](#storing-matrix-media-files-on-amazon-s3-with-goofys-optional) + - [Usage](#usage) + - [Migrating from local filesystem storage to S3](#migrating-from-local-filesystem-storage-to-s3) + - [Migrating to any S3-compatible storage (universal, but likely slow)](#migrating-to-any-s3-compatible-storage-universal-but-likely-slow) + - [Migrating to Backblaze B2](#migrating-to-backblaze-b2) + +### Migrating to any S3-compatible storage (universal, but likely slow) + +It's a good idea to [make a complete server backup](faq.md#how-do-i-backup-the-data-on-my-server) before doing this. + +1. Proceed with the steps below without stopping Matrix services + +2. Start by adding the base S3 configuration in your `vars.yml` file (seen above, may be different depending on the S3 provider of your choice) + +3. In addition to the base configuration you see above, add this to your `vars.yml` file: + +```yaml +matrix_s3_media_store_path: /matrix/s3-media-store +``` + +This enables S3 support, but mounts the S3 storage bucket to `/matrix/s3-media-store` without hooking it to your homeserver yet. Your homeserver will still continue using your local filesystem for its media store. + +5. Run the playbook to apply the changes: `ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start` + +6. Do an **initial sync of your files** by running this **on the server** (it may take a very long time): + +```sh +sudo -u matrix -- rsync --size-only --ignore-existing -avr /matrix/synapse/storage/media-store/. /matrix/s3-media-store/. +``` + +You may need to install `rsync` manually. + +7. Stop all Matrix services (`ansible-playbook -i inventory/hosts setup.yml --tags=stop`) + +8. Start the S3 service by running this **on the server**: `systemctl start matrix-goofys` + +9. Sync the files again by re-running the `rsync` command you see in step #6 + +10. Stop the S3 service by running this **on the server**: `systemctl stop matrix-goofys` + +11. Get the old media store out of the way by running this command on the server: + +```sh +mv /matrix/synapse/storage/media-store /matrix/synapse/storage/media-store-local-backup +``` + +12. Remove the `matrix_s3_media_store_path` configuration from your `vars.yml` file (undoing step #3 above) + +13. Run the playbook: `ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start` + +14. You're done! Verify that loading existing (old) media files works and that you can upload new ones. + +15. When confident that it all works, get rid of the local media store directory: `rm -rf /matrix/synapse/storage/media-store-local-backup` + + +### Migrating to Backblaze B2 + +It's a good idea to [make a complete server backup](faq.md#how-do-i-backup-the-data-on-my-server) before doing this. + +1. While all Matrix services are running, run the following command on the server: + +(you need to adjust the 3 `--env` line below with your own data) + +```sh +docker run -it --rm -w /work \ +--env='B2_KEY_ID=YOUR_KEY_GOES_HERE' \ +--env='B2_KEY_SECRET=YOUR_SECRET_GOES_HERE' \ +--env='B2_BUCKET_NAME=YOUR_BUCKET_NAME_GOES_HERE' \ +--mount type=bind,src=/matrix/synapse/storage/media-store,dst=/work,ro \ +--entrypoint=/bin/sh \ +docker.io/tianon/backblaze-b2:3.6.0 \ +-c 'b2 authorize-account $B2_KEY_ID $B2_KEY_SECRET && b2 sync /work b2://$B2_BUCKET_NAME --skipNewer' +``` + +This is some initial file sync, which may take a very long time. + +2. Stop all Matrix services (`ansible-playbook -i inventory/hosts setup.yml --tags=stop`) + +3. Run the command from step #1 again. + +Doing this will sync any new files that may have been created locally in the meantime. + +Now that Matrix services aren't running, we're sure to get Backblaze B2 and your local media store fully in sync. + +4. Get the old media store out of the way by running this command on the server: + +```sh +mv /matrix/synapse/storage/media-store /matrix/synapse/storage/media-store-local-backup +``` + +5. Put the [Backblaze B2 settings seen above](#backblaze-b2) in your `vars.yml` file + +6. Run the playbook: `ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start` + +7. You're done! Verify that loading existing (old) media files works and that you can upload new ones. + +8. When confident that it all works, get rid of the local media store directory: `rm -rf /matrix/synapse/storage/media-store-local-backup` diff --git a/docs/configuring-playbook-s3.md b/docs/configuring-playbook-s3.md new file mode 100644 index 0000000..539f96d --- /dev/null +++ b/docs/configuring-playbook-s3.md @@ -0,0 +1,107 @@ +# Storing Synapse media files on Amazon S3 or another compatible Object Storage (optional) + +By default, this playbook configures your server to store Synapse's content repository (`media_store`) files on the local filesystem. +If that's alright, you can skip this. + +As an alternative to storing media files on the local filesystem, you can store them on [Amazon S3](https://aws.amazon.com/s3/) or another S3-compatible object store. + +First, [choose an Object Storage provider](#choosing-an-object-storage-provider). + +Then, [create the S3 bucket](#bucket-creation-and-security-configuration). + +Finally, [set up S3 storage for Synapse](#setting-up) (with [Goofys](configuring-playbook-s3-goofys.md) or [synapse-s3-storage-provider](configuring-playbook-synapse-s3-storage-provider.md)). + + +## Choosing an Object Storage provider + +You can create [Amazon S3](https://aws.amazon.com/s3/) or another S3-compatible object store like [Backblaze B2](https://www.backblaze.com/b2/cloud-storage.html), [Wasabi](https://wasabi.com), [Digital Ocean Spaces](https://www.digitalocean.com/products/spaces), etc. + +Amazon S3 and Backblaze S3 are pay-as-you with no minimum charges for storing too little data. + +All these providers have different prices, with Backblaze B2 appearing to be the cheapest. + +Wasabi has a minimum charge of 1TB if you're storing less than 1TB, which becomes expensive if you need to store less data than that. + +Digital Ocean Spaces has a minimum charge of 250GB ($5/month as of 2022-10), which is also expensive if you're storing less data than that. + +Important aspects of choosing the right provider are: + +- a provider by a company you like and trust (or dislike less than the others) +- a provider which has a data region close to your Matrix server (if it's farther away, high latency may cause slowdowns) +- a provider which is OK pricewise +- a provider with free or cheap egress (if you need to get the data out often, for some reason) - likely not too important for the common use-case + + +## Bucket creation and Security Configuration + +Now that you've [chosen an Object Storage provider](#choosing-an-object-storage-provider), you need to create a storage bucket. + +How you do this varies from provider to provider, with Amazon S3 being the most complicated due to its vast number of services and complicated security policies. + +Below, we provider some guides for common providers. If you don't see yours, look at the others for inspiration or read some guides online about how to create a bucket. Feel free to contribute to this documentation with an update! + +## Amazon S3 + +You'll need an Amazon S3 bucket and some IAM user credentials (access key + secret key) with full write access to the bucket. Example IAM security policy: + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "Stmt1400105486000", + "Effect": "Allow", + "Action": [ + "s3:*" + ], + "Resource": [ + "arn:aws:s3:::your-bucket-name", + "arn:aws:s3:::your-bucket-name/*" + ] + } + ] +} +``` + +**NOTE**: This policy needs to be attached to an IAM user created from the **Security Credentials** menu. This is not a **Bucket Policy**. + + +## Backblaze B2 + +To use [Backblaze B2](https://www.backblaze.com/b2/cloud-storage.html) you first need to sign up. + +You [can't easily change which region (US, Europe) your Backblaze account stores files in](https://old.reddit.com/r/backblaze/comments/hi1v90/make_the_choice_for_the_b2_data_center_region/), so make sure to carefully choose the region when signing up (hint: it's a hard to see dropdown below the username/password fields in the signup form). + +After logging in to Backblaze: + +- create a new **private** bucket through its user interface (you can call it something like `matrix-DOMAIN-media-store`) +- note the **Endpoint** for your bucket (something like `s3.us-west-002.backblazeb2.com`). +- adjust its Lifecycle Rules to: Keep only the last version of the file +- go to [App Keys](https://secure.backblaze.com/app_keys.htm) and use the **Add a New Application Key** to create a new one + - restrict it to the previously created bucket (e.g. `matrix-DOMAIN-media-store`) + - give it *Read & Write* access + +The `keyID` value is your **Access Key** and `applicationKey` is your **Secret Key**. + +For configuring [Goofys](configuring-playbook-s3-goofys.md) or [s3-synapse-storage-provider](configuring-playbook-synapse-s3-storage-provider.md) you will need: + +- **Endpoint URL** - this is the **Endpoint** value you saw above, but prefixed with `https://` + +- **Region** - use the value you see in the Endpoint (e.g. `us-west-002`) + +- **Storage Class** - use `STANDARD`. Backblaze B2 does not have different storage classes, so it doesn't make sense to use any other value. + + +## Other providers + +For other S3-compatible providers, you may not need to configure security policies, etc. (just like for [Backblaze B2](#backblaze-b2)). + +You most likely just need to create an S3 bucket and get some credentials (access key and secret key) for accessing the bucket in a read/write manner. + + +## Setting up + +To set up Synapse to store files in S3, follow the instructions for the method of your choice: + +- using [synapse-s3-storage-provider](configuring-playbook-synapse-s3-storage-provider.md) (recommended) +- using [Goofys to mount the S3 store to the local filesystem](configuring-playbook-s3-goofys.md) diff --git a/docs/configuring-playbook-shared-secret-auth.md b/docs/configuring-playbook-shared-secret-auth.md new file mode 100644 index 0000000..21d1c33 --- /dev/null +++ b/docs/configuring-playbook-shared-secret-auth.md @@ -0,0 +1,23 @@ +# Setting up the Shared Secret Auth password provider module (optional, advanced) + +The playbook can install and configure [matrix-synapse-shared-secret-auth](https://github.com/devture/matrix-synapse-shared-secret-auth) for you. + +See that project's documentation to learn what it does and why it might be useful to you. + +If you decide that you'd like to let this playbook install it for you, you need some configuration (`inventory/host_vars/matrix./vars.yml`) like this: + +```yaml +matrix_synapse_ext_password_provider_shared_secret_auth_enabled: true +matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret: YOUR_SHARED_SECRET_GOES_HERE +``` + +You can generate a strong shared secret with a command like this: `pwgen -s 64 1` + + +## Authenticating only using a password provider + +If you wish for users to **authenticate only against configured password providers** (like this one), **without consulting Synapse's local database**, feel free to disable it: + +```yaml +matrix_synapse_password_config_localdb_enabled: false +``` diff --git a/docs/configuring-playbook-ssl-certificates.md b/docs/configuring-playbook-ssl-certificates.md new file mode 100644 index 0000000..606160d --- /dev/null +++ b/docs/configuring-playbook-ssl-certificates.md @@ -0,0 +1,112 @@ +# Adjusting SSL certificate retrieval (optional, advanced) + +By default, this playbook retrieves and auto-renews free SSL certificates from [Let's Encrypt](https://letsencrypt.org/) for the domains it needs (`matrix.` and possibly `element.`) + +Those certificates are used when configuring the nginx reverse proxy installed by this playbook. +They can also be used for configuring [your own webserver](configuring-playbook-own-webserver.md), in case you're not using the integrated nginx server provided by the playbook. + +If you need to retrieve certificates for other domains (e.g. your base domain) or more control over certificate retrieval, read below. + +Things discussed in this document: + +- [Using self-signed SSL certificates](#using-self-signed-ssl-certificates), if you can't use Let's Encrypt or just need a test setup + +- [Using your own SSL certificates](#using-your-own-ssl-certificates), if you don't want to or can't use Let's Encrypt certificates, but are still interested in using the integrated nginx reverse proxy server + +- [Not bothering with SSL certificates](#not-bothering-with-ssl-certificates), if you're using [your own webserver](configuring-playbook-own-webserver.md) and would rather this playbook leaves SSL certificate management to you + +- [Obtaining SSL certificates for additional domains](#obtaining-ssl-certificates-for-additional-domains), if you'd like to host additional domains on the Matrix server and would like the playbook to help you obtain and renew certificates for those domains automatically + + +## Using self-signed SSL certificates + +For private deployments (not publicly accessible from the internet), you may not be able to use Let's Encrypt certificates. + +If self-signed certificates are alright with you, you can ask the playbook to generate such for you with the following configuration: + +```yaml +matrix_ssl_retrieval_method: self-signed +``` + +If you get a `Cannot reach homeserver` error in Element, you will have to visit `https://matrix.` in your browser and agree to the certificate exception before you can login. + + +## Using your own SSL certificates + +If you'd like to manage SSL certificates by yourself and have the playbook use your certificate files, you can use the following configuration: + +```yaml +matrix_ssl_retrieval_method: manually-managed +``` + +With such a configuration, the playbook would expect you to drop the SSL certificate files in the directory specified by `matrix_ssl_config_dir_path` (`/matrix/ssl/config` by default) obeying the following hierarchy: + +- `/live//fullchain.pem` +- `/live//privkey.pem` +- `/live//chain.pem` + +where `` refers to the domains that you need (usually `matrix.` and `element.`). + + +## Not bothering with SSL certificates + +If you're [using an external web server](configuring-playbook-own-webserver.md) which is not nginx, or you would otherwise want to manage its certificates without this playbook getting in the way, you can completely disable SSL certificate management with the following configuration: + +```yaml +matrix_ssl_retrieval_method: none +``` + +With such a configuration, no certificates will be retrieved at all. You're free to manage them however you want. + + +## Obtaining SSL certificates for additional domains + +The playbook tries to be smart about the certificates it will obtain for you. + +By default, it obtains certificates for: +- `matrix.` (`matrix_server_fqn_matrix`) +- possibly for `element.`, unless you have disabled the [Element client component](configuring-playbook-client-element.md) using `matrix_client_element_enabled: false` +- possibly for `riot.`, if you have explicitly enabled Riot to Element redirection (for background compatibility) using `matrix_nginx_proxy_proxy_riot_compat_redirect_enabled: true` +- possibly for `hydrogen.`, if you have explicitly [set up Hydrogen client](configuring-playbook-client-hydrogen.md). +- possibly for `cinny.`, if you have explicitly [set up Cinny client](configuring-playbook-client-cinny.md). +- possibly for `dimension.`, if you have explicitly [set up Dimension](configuring-playbook-dimension.md). +- possibly for `goneb.`, if you have explicitly [set up Go-NEB bot](configuring-playbook-bot-go-neb.md). +- possibly for `jitsi.`, if you have explicitly [set up Jitsi](configuring-playbook-jitsi.md). +- possibly for `stats.`, if you have explicitly [set up Grafana](configuring-playbook-prometheus-grafana.md). +- possibly for `sygnal.`, if you have explicitly [set up Sygnal](configuring-playbook-sygnal.md). +- possibly for `ntfy.`, if you have explicitly [set up ntfy](configuring-playbook-ntfy.md). +- possibly for your base domain (``), if you have explicitly configured [Serving the base domain](configuring-playbook-base-domain-serving.md) + +If you are hosting other domains on the Matrix machine, you can make the playbook obtain and renew certificates for those other domains too. +To do that, simply define your own custom configuration like this: + +```yaml +# In this example, we retrieve 2 extra certificates, +# one for the base domain (in the `matrix_domain` variable) and one for a hardcoded domain. +# Adding any other additional domains (hosted on the same machine) is possible. +matrix_ssl_additional_domains_to_obtain_certificates_for: + - '{{ matrix_domain }}' + - 'another.domain.example.com' +``` + +After redefining `matrix_ssl_domains_to_obtain_certificates_for`, to actually obtain certificates you should: + +- make sure the web server occupying port 80 is stopped. If you are using matrix-nginx-proxy server (which is the default for this playbook), you need to stop it temporarily by running `systemctl stop matrix-nginx-proxy` on the server. + +- re-run the SSL part of the playbook and restart all services: `ansible-playbook -i inventory/hosts setup.yml --tags=setup-ssl,start` + +The certificate files would be made available in `/matrix/ssl/config/live//...`. + +For automated certificate renewal to work, each port `80` vhost for each domain you are obtaining certificates for needs to forward requests for `/.well-known/acme-challenge` to the certbot container we use for renewal. + +See how this is configured for the `matrix.` subdomain in `/matrix/nginx-proxy/conf.d/matrix-domain.conf` +Don't be alarmed if the above configuration file says port `8080`, instead of port `80`. It's due to port mapping due to our use of containers. + + +## Specify the SSL private key algorithm + +If you'd like to [specify the private key type](https://eff-certbot.readthedocs.io/en/stable/using.html#using-ecdsa-keys) used with Let's Encrypt, define your own custom configuration like this: + +```yaml +matrix_ssl_lets_encrypt_key_type: ecdsa +``` diff --git a/docs/configuring-playbook-turn.md b/docs/configuring-playbook-turn.md new file mode 100644 index 0000000..c1d777a --- /dev/null +++ b/docs/configuring-playbook-turn.md @@ -0,0 +1,42 @@ +# TURN server + +The playbook installs a [Coturn](https://github.com/coturn/coturn) TURN server by default, so that clients can make audio/video calls even from [NAT](https://en.wikipedia.org/wiki/Network_address_translation)-ed networks. + +By default, the Synapse chat server is configured, so that it points to the Coturn TURN server installed by the playbook. + + +## Disabling Coturn + +If, for some reason, you'd like to prevent the playbook from installing Coturn, you can use the following configuration: + +```yaml +matrix_coturn_enabled: false +``` + +In that case, Synapse would not point to any Coturn servers and audio/video call functionality may fail. + + +## Using your own external Coturn server + +If you'd like to use another TURN server (be it Coturn or some other one), you can configure the playbook like this: + +```yaml +# Disable integrated Coturn server +matrix_coturn_enabled: false + +# Point Synapse to your other Coturn server +matrix_synapse_turn_uris: +- turns:HOSTNAME_OR_IP?transport=udp +- turns:HOSTNAME_OR_IP?transport=tcp +- turn:HOSTNAME_OR_IP?transport=udp +- turn:HOSTNAME_OR_IP?transport=tcp +``` + +If you have or want to enable [Jitsi](configuring-playbook-jitsi.md), you might want to enable the TURN server there too. +If you do not do it, Jitsi will fall back to an upstream service. + +```yaml +matrix_jitsi_web_stun_servers: +- stun:HOSTNAME_OR_IP:PORT +``` +You can put multiple host/port combinations if you like. diff --git a/docs/configuring-playbook.md b/docs/configuring-playbook.md new file mode 100644 index 0000000..fa00c85 --- /dev/null +++ b/docs/configuring-playbook.md @@ -0,0 +1,192 @@ +# Configuring the Ansible playbook + +To configure the playbook, you need to have done the following things: + +- have a server where Matrix services will run +- [configured your DNS records](configuring-dns.md) +- [retrieved the playbook's source code](getting-the-playbook.md) to your computer + +You can then follow these steps inside the playbook directory: + +1. create a directory to hold your configuration (`mkdir inventory/host_vars/matrix.`) + +1. copy the sample configuration file (`cp examples/vars.yml inventory/host_vars/matrix./vars.yml`) + +1. edit the configuration file (`inventory/host_vars/matrix./vars.yml`) to your liking. You may also take a look at the various `roles/ROLE_NAME_HERE/defaults/main.yml` files and see if there's something you'd like to copy over and override in your `vars.yml` configuration file. + +1. copy the sample inventory hosts file (`cp examples/hosts inventory/hosts`) + +1. edit the inventory hosts file (`inventory/hosts`) to your liking + +1. (optional, advanced) to run Ansible against multiple servers with different `sudo` credentials, you can copy the sample inventory hosts yaml file for each of your hosts: (`cp examples/host.yml inventory/my_host1.yml` …) and use the [`ansible-all-hosts.sh`](../inventory/scripts/ansible-all-hosts.sh) script [in the installation step](installing.md). + +For a basic Matrix installation, that's all you need. +For a more custom setup, see the [Other configuration options](#other-configuration-options) below. + +When you're done with all the configuration you'd like to do, continue with [Installing](installing.md). + + +## Other configuration options + +### Additional useful services + +- [Setting up the Dimension Integration Manager](configuring-playbook-dimension.md) (optional, but recommended; after [installing](installing.md)) + +- [Setting up the Jitsi video-conferencing platform](configuring-playbook-jitsi.md) (optional) + +- [Setting up Etherpad](configuring-playbook-etherpad.md) (optional) + +- [Setting up Dynamic DNS](configuring-playbook-dynamic-dns.md) (optional) + +- [Enabling metrics and graphs (Prometheus, Grafana) for your Matrix server](configuring-playbook-prometheus-grafana.md) (optional) + +### Core service adjustments + +- Homeserver configuration: + - [Configuring Synapse](configuring-playbook-synapse.md), if you're going with the default/recommended homeserver implementation (optional) + + - [Configuring Conduit](configuring-playbook-conduit.md), if you've switched to the [Conduit](https://conduit.rs) homeserver implementation (optional) + + - [Configuring Dendrite](configuring-playbook-dendrite.md), if you've switched to the [Dendrite](https://matrix-org.github.io/dendrite) homeserver implementation (optional) + +- [Configuring Element](configuring-playbook-client-element.md) (optional) + +- [Storing Matrix media files on Amazon S3](configuring-playbook-s3.md) (optional) + +- [Using an external PostgreSQL server](configuring-playbook-external-postgres.md) (optional) + +- [Adjusting SSL certificate retrieval](configuring-playbook-ssl-certificates.md) (optional, advanced) + +- [Serving your base domain using this playbook's nginx server](configuring-playbook-base-domain-serving.md) (optional) + +- [Configure Nginx](configuring-playbook-nginx.md) (optional, advanced) + +- [Using your own webserver, instead of this playbook's nginx proxy](configuring-playbook-own-webserver.md) (optional, advanced) + +- [Adjusting TURN server configuration](configuring-playbook-turn.md) (optional, advanced) + + +### Server connectivity + +- [Enabling Telemetry for your Matrix server](configuring-playbook-telemetry.md) (optional) + +- [Controlling Matrix federation](configuring-playbook-federation.md) (optional) + +- [Adjusting email-sending settings](configuring-playbook-email.md) (optional) + +- [Setting up Hydrogen](configuring-playbook-client-hydrogen.md) - a new lightweight matrix client with legacy and mobile browser support (optional) + +- [Setting up Cinny](configuring-playbook-client-cinny.md) - a web client focusing primarily on simple, elegant and secure interface (optional) + + +### Authentication and user-related + +- [Setting up an ma1sd Identity Server](configuring-playbook-ma1sd.md) (optional) + +- [Setting up Synapse Admin](configuring-playbook-synapse-admin.md) (optional) + +- [Setting up matrix-registration](configuring-playbook-matrix-registration.md) (optional) + +- [Setting up the REST authentication password provider module](configuring-playbook-rest-auth.md) (optional, advanced) + +- [Setting up the Shared Secret Auth password provider module](configuring-playbook-shared-secret-auth.md) (optional, advanced) + +- [Setting up the LDAP password provider module](configuring-playbook-ldap-auth.md) (optional, advanced) + +- [Setting up the ldap-registration-proxy](configuring-playbook-matrix-ldap-registration-proxy.md) (optional, advanced) + +- [Setting up Synapse Simple Antispam](configuring-playbook-synapse-simple-antispam.md) (optional, advanced) + +- [Setting up Matrix Corporal](configuring-playbook-matrix-corporal.md) (optional, advanced) + + +### Bridging other networks + +- [Setting up Mautrix Discord bridging](configuring-playbook-bridge-mautrix-discord.md) (optional) + +- [Setting up Mautrix Telegram bridging](configuring-playbook-bridge-mautrix-telegram.md) (optional) + +- [Setting up Mautrix Whatsapp bridging](configuring-playbook-bridge-mautrix-whatsapp.md) (optional) + +- [Setting up Mautrix Facebook bridging](configuring-playbook-bridge-mautrix-facebook.md) (optional) + +- [Setting up Mautrix Hangouts bridging](configuring-playbook-bridge-mautrix-hangouts.md) (optional) + +- [Setting up Mautrix Google Chat bridging](configuring-playbook-bridge-mautrix-googlechat.md) (optional) + +- [Setting up Mautrix Instagram bridging](configuring-playbook-bridge-mautrix-instagram.md) (optional) + +- [Setting up Mautrix Twitter bridging](configuring-playbook-bridge-mautrix-twitter.md) (optional) + +- [Setting up Mautrix Signal bridging](configuring-playbook-bridge-mautrix-signal.md) (optional) + +- [Setting up Appservice IRC bridging](configuring-playbook-bridge-appservice-irc.md) (optional) + +- [Setting up Appservice Discord bridging](configuring-playbook-bridge-appservice-discord.md) (optional) + +- [Setting up Appservice Slack bridging](configuring-playbook-bridge-appservice-slack.md) (optional) + +- [Setting up Appservice Webhooks bridging](configuring-playbook-bridge-appservice-webhooks.md) (optional) + +- [Setting up Appservice Kakaotalk bridging](configuring-playbook-bridge-appservice-kakaotalk.md) (optional) + +- [Setting up Beeper LinkedIn bridging](configuring-playbook-bridge-beeper-linkedin.md) (optional) + +- [Setting up matrix-hookshot](configuring-playbook-bridge-hookshot.md) - a bridge between Matrix and multiple project management services, such as [GitHub](https://github.com), [GitLab](https://about.gitlab.com) and [JIRA](https://www.atlassian.com/software/jira). (optional) + +- ~~[Setting up MX Puppet Skype bridging](configuring-playbook-bridge-mx-puppet-skype.md)~~ (optional) - this component has been broken for a long time, so it has been removed from the playbook. Consider [Setting up Go Skype Bridge bridging](configuring-playbook-bridge-go-skype-bridge.md) + +- [Setting up MX Puppet Slack bridging](configuring-playbook-bridge-mx-puppet-slack.md) (optional) + +- [Setting up MX Puppet Instagram bridging](configuring-playbook-bridge-mx-puppet-instagram.md) (optional) + +- [Setting up MX Puppet Twitter bridging](configuring-playbook-bridge-mx-puppet-twitter.md) (optional) + +- [Setting up MX Puppet Discord bridging](configuring-playbook-bridge-mx-puppet-discord.md) (optional) + +- [Setting up MX Puppet GroupMe bridging](configuring-playbook-bridge-mx-puppet-groupme.md) (optional) + +- [Setting up MX Puppet Steam bridging](configuring-playbook-bridge-mx-puppet-steam.md) (optional) + +- [Setting up Go Skype Bridge bridging](configuring-playbook-bridge-go-skype-bridge.md) (optional) + +- [Setting up Email2Matrix](configuring-playbook-email2matrix.md) (optional) + +- [Setting up Postmoogle email bridging](configuring-playbook-bot-postmoogle.md) (optional) + +- [Setting up Matrix SMS bridging](configuring-playbook-bridge-matrix-bridge-sms.md) (optional) + +- [Setting up Heisenbridge bouncer-style IRC bridging](configuring-playbook-bridge-heisenbridge.md) (optional) + + +### Bots + +- [Setting up matrix-reminder-bot](configuring-playbook-bot-matrix-reminder-bot.md) - a bot to remind you about stuff (optional) + +- [Setting up matrix-registration-bot](configuring-playbook-bot-matrix-registration-bot.md) - a bot to create and manage registration tokens to invite users (optional) + +- [Setting up maubot](configuring-playbook-bot-maubot.md) - a plugin-based Matrix bot system (optional) + +- [Setting up honoroit](configuring-playbook-bot-honoroit.md) - a helpdesk bot (optional) + +- [Setting up Go-NEB](configuring-playbook-bot-go-neb.md) - an extensible multifunctional bot (optional) + +- [Setting up Mjolnir](configuring-playbook-bot-mjolnir.md) - a moderation tool/bot (optional) + +- [Setting up Buscarron](configuring-playbook-bot-buscarron.md) - a bot you can use to send any form (HTTP POST, HTML) to a (encrypted) Matrix room (optional) + + +### Backups + +- [Setting up borg backup](configuring-playbook-backup-borg.md) - a full Matrix server backup solution, including the Postgres database (optional) + +- [Setting up postgres backup](configuring-playbook-postgres-backup.md) - a Postgres-database backup solution (note: does not include other files) (optional) + + +### Other specialized services + +- [Setting up the Sygnal push gateway](configuring-playbook-sygnal.md) (optional) + +- [Setting up the ntfy push notifications server](configuring-playbook-ntfy.md) (optional) + +- [Setting up a Cactus Comments server](configuring-playbook-cactus-comments.md) - a federated comment system built on Matrix (optional) diff --git a/docs/configuring-well-known.md b/docs/configuring-well-known.md new file mode 100644 index 0000000..fd548aa --- /dev/null +++ b/docs/configuring-well-known.md @@ -0,0 +1,201 @@ +# Configuring Service Discovery via .well-known + +Service discovery is a way for the Matrix network to discover where a Matrix server is. + +There are 2 types of well-known service discovery that Matrix makes use of: + +- (important) **Federation Server discovery** (`/.well-known/matrix/server`) -- assists other servers in the Matrix network with finding your server. Without a proper configuration, your server will effectively not be part of the Matrix network. Learn more in [Introduction to Federation Server Discovery](#introduction-to-federation-server-discovery) + +- (not that important) **Client Server discovery** (`/.well-known/matrix/client`) -- assists programs that you use to connect to your server (e.g. Element), so that they can make it more convenient for you by automatically configuring the "Homeserver URL" and "Identity Server URL" addresses. Learn more in [Introduction to Client Server Discovery](#introduction-to-client-server-discovery) + + +## Introduction to Federation Server Discovery + +All services created by this playbook are meant to be installed on their own server (such as `matrix.`). + +As [per the Server-Server specification](https://matrix.org/docs/spec/server_server/r0.1.0.html#server-discovery), to use a Matrix user identifier like `@:` while hosting services on a subdomain like `matrix.`, the Matrix network needs to be instructed of such delegation/redirection. + +Server delegation can be configured using DNS SRV records or by setting up a `/.well-known/matrix/server` file on the base domain (``). + +Both methods have their place and will continue to do so. You only need to use just one of these delegation methods. +For simplicity reasons, our setup advocates for the `/.well-known/matrix/server` method and guides you into using that. + +To learn how to set up `/.well-known/matrix/server`, read the Installing section below. + + +## Introduction to Client Server Discovery + +Client Server Service discovery lets various client programs which support it, to receive a full user id (e.g. `@username:example.com`) and determine where the Matrix server is automatically (e.g. `https://matrix.example.com`). + +This lets you (and your users) easily connect to your Matrix server without having to customize connection URLs. When using client programs that support it, you won't need to point them to `https://matrix.example.com` in Custom Server options manually anymore. The connection URL would be discovered automatically from your full username. + +As [per the Client-Server specification](https://matrix.org/docs/spec/client_server/r0.4.0.html#server-discovery) Matrix does Client Server service discovery using a `/.well-known/matrix/client` file hosted on the base domain (e.g. `example.com`). + +However, this playbook installs your Matrix server on another domain (e.g. `matrix.example.com`) and not on the base domain (e.g. `example.com`), so it takes a little extra manual effort to set up the file. + +To learn how to set it up, read the Installing section below. + + +## (Optional) Introduction to Homeserver Admin Contact and Support page + +[MSC 1929](https://github.com/matrix-org/matrix-spec-proposals/pull/1929) specifies a way to add contact details of admins, as well as a link to a support page for users who are having issues with the service. + +This MSC did not get accepted yet, but we think it might already be useful to Homeserver admins who wish to provide this information to end-users. + +The two playbook variables that you could look for, if you're interested in being an early adopter, are: `matrix_homeserver_admin_contacts` and `matrix_homeserver_support_url`. + +Example snippet for `vars.yml`: +``` +# Enable generation of `/.well-known/matrix/support`. +# This needs to be enabled explicitly for now, because MSC 1929 is not yet accepted. +matrix_well_known_matrix_support_enabled: true + +# Homeserver admin contacts as per MSC 1929 https://github.com/matrix-org/matrix-spec-proposals/pull/1929 +matrix_homeserver_admin_contacts: + - matrix_id: "@admin1:{{ matrix_domain }}" + email_address: admin@domain.tld + role: admin + - matrix_id: "@admin2:{{ matrix_domain }}" + email_address: admin2@domain.tld + role: admin + - email_address: security@domain.tld + role: security + +matrix_homeserver_support_url: "https://example.domain.tld/support" +``` + +To learn how to set up `/.well-known/matrix/support` for the base domain, read the Installing section below. + + +## Installing well-known files on the base domain's server + +To implement the two service discovery mechanisms, your base domain's server (e.g. `example.com`) needs to run an HTTPS-capable webserver. + +If you don't have a server for your base domain at all, you can use the Matrix server for this. +See [Serving the base domain](configuring-playbook-base-domain-serving.md) to learn how the playbook can help you set it up. +If you decide to go this route, you don't need to read ahead in this document. When **Serving the base domain**, the playbook takes care to serve the appropriate well-known files automatically. + +If you're managing the base domain by yourself somehow, you'll need to set up serving of some `/.well-known/matrix/*` files from it via HTTPS. + +To make things easy for you to set up, this playbook generates and hosts 2 well-known files on the Matrix domain's server. The files are generated at `/matrix/static-files/.well-known/matrix/` and hosted at `https://matrix.example.com/.well-known/matrix/server` and `https://matrix.example.com/.well-known/matrix/client`, even though this is the wrong place to host them. + +You have 3 options when it comes to installing the files on the base domain's server: + + +### (Option 1): **Copying the files manually** to your base domain's server + +**Hint**: Option 2 and 3 (below) are generally a better way to do this. Make sure to go with them, if possible. + +All you need to do is: + +- copy `/.well-known/matrix/server` and `/.well-known/matrix/client` from the Matrix server (e.g. `matrix.example.com`) to your base domain's server (`example.com`). You can find these files in the `/matrix/static-files/.well-known/matrix` directory on the Matrix server. They are also accessible on URLs like this: `https://matrix.example.com/.well-known/matrix/server` (same for `client`). + +- set up the server at your base domain (e.g. `example.com`) so that it adds an extra HTTP header when serving the `/.well-known/matrix/client` file. [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS), the `Access-Control-Allow-Origin` header should be set with a value of `*`. If you don't do this step, web-based Matrix clients (like Element) may fail to work. Setting up headers for the `/.well-known/matrix/server` file is not necessary, as this file is only consumed by non-browsers, which don't care about CORS. + +This is relatively easy to do and possibly your only choice if you can only host static files from the base domain's server. +It is, however, **a little fragile**, as future updates performed by this playbook may regenerate the well-known files and you may need to notice that and copy them over again. + + +### (Option 2): **Serving the base domain** from the Matrix server via the playbook + +If you don't need the base domain (e.g. `example.com`) for anything else (hosting a website, etc.), you can point it to the Matrix server's IP address and tell the playbook to configure it. + +This is the easiest way to set up well-known serving -- letting the playbook handle the whole base domain for you (including SSL certificates, etc.). However, if you need to use the base domain for other things (such as hosting some website, etc.), going with Option 1 or Option 3 might be more suitable. + +See [Serving the base domain](configuring-playbook-base-domain-serving.md) to learn how the playbook can help you set it up. + + +### (Option 3): **Setting up reverse-proxying** of the well-known files from the base domain's server to the Matrix server + +This option is less fragile and generally better. + +On the base domain's server (e.g. `example.com`), you can set up reverse-proxying, so that any access for the `/.well-known/matrix` location prefix is forwarded to the Matrix domain's server (e.g. `matrix.example.com`). + +With this method, you **don't need** to add special HTTP headers for [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) reasons (like `Access-Control-Allow-Origin`), because your Matrix server (where requests ultimately go) will be configured by this playbook correctly. + +**For nginx**, it would be something like this: + +```nginx +# This is your HTTPS-enabled server for example.com. +server { + server_name example.com; + + location /.well-known/matrix { + proxy_pass https://matrix.example.com/.well-known/matrix; + proxy_set_header X-Forwarded-For $remote_addr; + } + + # other configuration +} +``` + +**For Apache2**, it would be something like this: + +```apache + + ServerName example.com + + SSLProxyEngine on + ProxyPass /.well-known/matrix https://matrix.example.com/.well-known/matrix nocanon + ProxyPassReverse /.well-known/matrix https://matrix.example.com/.well-known/matrix nocanon + + # other configuration + +``` + +**For Caddy 2**, it would be something like this: + +```caddy +example.com { + reverse_proxy /.well-known/matrix/* https://matrix.example.com { + header_up Host {upstream_hostport} + } +} +``` + +**For HAProxy**, it would be something like this: + +```haproxy +frontend www-https + # Select a Challenge for Matrix federation redirect + acl matrix-acl path_beg /.well-known/matrix/ + # Use the challenge backend if the challenge is set + use_backend matrix-backend if matrix-acl +backend matrix-backend + # Redirects the .well-known matrix to the matrix server for federation. + http-request set-header Host matrix.example.com + server matrix matrix.example.com:80 + # Map url path as ProxyPass does + reqirep ^(GET|POST|HEAD)\ /.well-known/matrix/(.*) \1\ /\2 + # Rewrite redirects as ProxyPassReverse does + acl response-is-redirect res.hdr(Location) -m found + rsprep ^Location:\ (http|https)://matrix.example.com\/(.*) Location:\ \1://matrix.example.com/.well-known/matrix/\2 if response-is-redirect +``` + +**For Netlify**, it would be something like this: + +``` +# In the _redirects file in the website's root +/.well-known/matrix/* https://matrix.example.com/.well-known/matrix/:splat 200! +``` + +**For AWS CloudFront** + + 1. Add a custom origin with matrix. to your distribution + 1. Add two behaviors, one for `.well-known/matrix/client` and one for `.well-known/matrix/server` and point them to your new origin. + +Make sure to: + +- **replace `example.com`** in the server configuration with your actual domain name +- and: to **do this for the HTTPS-enabled server block**, as that's where Matrix expects the file to be + + +## Confirming it works + +No matter which method you've used to set up the well-known files, if you've done it correctly you should be able to see a JSON file at these URLs: + +- `https:///.well-known/matrix/server` +- `https:///.well-known/matrix/client` +- `https:///.well-known/matrix/support` + +You can also check if everything is configured correctly, by [checking if services work](maintenance-checking-services.md). diff --git a/docs/container-images.md b/docs/container-images.md new file mode 100644 index 0000000..737a445 --- /dev/null +++ b/docs/container-images.md @@ -0,0 +1,121 @@ +# Container Images used by the playbook + +This page summarizes the container ([Docker](https://www.docker.com/)) images used by the playbook when setting up your server. + +We try to stick to official images (provided by their respective projects) as much as possible. + + +## Container images used by default + +These services are enabled and used by default, but you can turn them off, if you wish. + +- [matrixdotorg/synapse](https://hub.docker.com/r/matrixdotorg/synapse/) - the official [Synapse](https://github.com/matrix-org/synapse) Matrix homeserver (optional) + +- [coturn/coturn](https://hub.docker.com/r/coturn/coturn/) - the [Coturn](https://github.com/coturn/coturn) STUN/TURN server (optional) + +- [vectorim/element-web](https://hub.docker.com/r/vectorim/element-web/) - the [Element](https://element.io/) web client (optional) + +- [postgres](https://hub.docker.com/_/postgres/) - the [Postgres](https://www.postgresql.org/) database server (optional) + +- [devture/exim-relay](https://hub.docker.com/r/devture/exim-relay/) - the [Exim](https://www.exim.org/) email server (optional) + +- [nginx](https://hub.docker.com/_/nginx/) - the [nginx](http://nginx.org/) web server (optional) + +- [certbot/certbot](https://hub.docker.com/r/certbot/certbot/) - the [certbot](https://certbot.eff.org/) tool for obtaining SSL certificates from [Let's Encrypt](https://letsencrypt.org/) (optional) + + +## Optional other container images we may use + +These services are not part of our default installation, but can be enabled by [configuring the playbook](configuring-playbook.md) (either before the initial installation or any time later): + +- [ma1uta/ma1sd](https://hub.docker.com/r/ma1uta/ma1sd/) - the [ma1sd](https://github.com/ma1uta/ma1sd) Matrix Identity server (optional) + +- [matrixconduit/matrix-conduit](https://hub.docker.com/r/matrixconduit/matrix-conduit) - the [Conduit](https://conduit.rs) Matrix homeserver (optional) + +- [matrixdotorg/dendrite-monolith](https://hub.docker.com/r/matrixdotorg/dendrite-monolith/) - the [Dendrite](https://github.com/matrix-org/dendrite) Matrix homeserver (optional) + +- [ewoutp/goofys](https://hub.docker.com/r/ewoutp/goofys/) - the [Goofys](https://github.com/kahing/goofys) Amazon [S3](https://aws.amazon.com/s3/) file-system-mounting program (optional) + +- [etherpad/etherpad](https://hub.docker.com/r/etherpad/etherpad/) - the [Etherpad](https://etherpad.org) realtime collaborative text editor that can be used in a Jitsi audio/video call or integrated as a widget into Matrix chat rooms via the Dimension integration manager (optional) + +- [devture/email2matrix](https://hub.docker.com/r/devture/email2matrix/) - the [Email2Matrix](https://github.com/devture/email2matrix) email server, which can relay email messages to Matrix rooms (optional) + +- [devture/matrix-corporal](https://hub.docker.com/r/devture/matrix-corporal/) - [Matrix Corporal](https://github.com/devture/matrix-corporal): reconciliator and gateway for a managed Matrix server (optional) + +- [zeratax/matrix-registration](https://hub.docker.com/r/devture/zeratax-matrix-registration/) - [matrix-registration](https://github.com/ZerataX/matrix-registration): a simple python application to have a token based matrix registration (optional) + +- [mautrix/telegram](https://mau.dev/mautrix/telegram/container_registry) - the [mautrix-telegram](https://github.com/mautrix/telegram) bridge to [Telegram](https://telegram.org/) (optional) + +- [mautrix/whatsapp](https://mau.dev/mautrix/whatsapp/container_registry) - the [mautrix-whatsapp](https://github.com/mautrix/whatsapp) bridge to [Whatsapp](https://www.whatsapp.com/) (optional) + +- [mautrix/facebook](https://mau.dev/mautrix/facebook/container_registry) - the [mautrix-facebook](https://github.com/mautrix/facebook) bridge to [Facebook](https://facebook.com/) (optional) + +- [mautrix/twitter](https://mau.dev/mautrix/twitter/container_registry) - the [mautrix-twitter](https://github.com/mautrix/twitter) bridge to [Twitter](https://twitter.com/) (optional) + +- [mautrix/hangouts](https://mau.dev/mautrix/hangouts/container_registry) - the [mautrix-hangouts](https://github.com/mautrix/hangouts) bridge to [Google Hangouts](https://en.wikipedia.org/wiki/Google_Hangouts) (optional) + +- [mautrix/googlechat](https://mau.dev/mautrix/googlechat/container_registry) - the [mautrix-googlechat](https://github.com/mautrix/googlechat) bridge to [Google Chat](https://en.wikipedia.org/wiki/Google_Chat) (optional) + +- [mautrix/instagram](https://mau.dev/mautrix/instagram/container_registry) - the [mautrix-instagram](https://github.com/mautrix/instagram) bridge to [Instagram](https://instagram.com/) (optional) + +- [mautrix/signal](https://mau.dev/mautrix/signal/container_registry) - the [mautrix-signal](https://github.com/mautrix/signal) bridge to [Signal](https://www.signal.org/) (optional) + +- [matrixdotorg/matrix-appservice-irc](https://hub.docker.com/r/matrixdotorg/matrix-appservice-irc) - the [matrix-appservice-irc](https://github.com/matrix-org/matrix-appservice-irc) bridge to [IRC](https://wikipedia.org/wiki/Internet_Relay_Chat) (optional) + +- [halfshot/matrix-appservice-discord](https://hub.docker.com/r/halfshot/matrix-appservice-discord) - the [matrix-appservice-discord](https://github.com/Half-Shot/matrix-appservice-discord) bridge to [Discord](https://discordapp.com/) (optional) + +- [cadair/matrix-appservice-slack](https://hub.docker.com/r/cadair/matrix-appservice-slack) - the [matrix-appservice-slack](https://github.com/matrix-org/matrix-appservice-slack) bridge to [Slack](https://slack.com/) (optional) + +- [turt2live/matrix-appservice-webhooks](https://hub.docker.com/r/turt2live/matrix-appservice-webhooks) - the [Appservice Webhooks](https://github.com/turt2live/matrix-appservice-webhooks) bridge (optional) + +- [folivonet/matrix-sms-bridge](https://hub.docker.com/repository/docker/folivonet/matrix-sms-bridge) - the [matrix-sms-bridge](https://github.com/benkuly/matrix-sms-bridge) (optional) + +- [sorunome/mx-puppet-slack](https://hub.docker.com/r/sorunome/mx-puppet-slack) - the [mx-puppet-slack](https://github.com/Sorunome/mx-puppet-slack) bridge to [Slack](https://slack.com) (optional) + +- [sorunome/mx-puppet-instagram](https://hub.docker.com/r/sorunome/mx-puppet-instagram) - the [mx-puppet-instagram](https://github.com/Sorunome/mx-puppet-instagram) bridge to [Instagram](https://www.instagram.com) (optional) + +- [sorunome/mx-puppet-twitter](https://hub.docker.com/r/sorunome/mx-puppet-twitter) - the [mx-puppet-twitter](https://github.com/Sorunome/mx-puppet-twitter) bridge to [Twitter](https://twitter.com) (optional) + +- [sorunome/mx-puppet-discord](https://hub.docker.com/r/sorunome/mx-puppet-discord) - the [mx-puppet-discord](https://github.com/matrix-discord/mx-puppet-discord) bridge to [Discord](https://discordapp.com) (optional) + +- [xangelix/mx-puppet-groupme](https://hub.docker.com/r/xangelix/mx-puppet-groupme) - the [mx-puppet-groupme](https://gitlab.com/xangelix-pub/matrix/mx-puppet-groupme) bridge to [GroupMe](https://groupme.com/) (optional) + +- [icewind1991/mx-puppet-steam](https://hub.docker.com/r/icewind1991/mx-puppet-steam) - the [mx-puppet-steam](https://github.com/icewind1991/mx-puppet-steam) bridge to [Steam](https://steampowered.com) (optional) + +- [turt2live/matrix-dimension](https://hub.docker.com/r/turt2live/matrix-dimension) - the [Dimension](https://dimension.t2bot.io/) integrations manager (optional) + +- [jitsi/web](https://hub.docker.com/r/jitsi/web) - the [Jitsi](https://jitsi.org/) web UI (optional) + +- [jitsi/jicofo](https://hub.docker.com/r/jitsi/jicofo) - the [Jitsi](https://jitsi.org/) Focus component (optional) + +- [jitsi/prosody](https://hub.docker.com/r/jitsi/prosody) - the [Jitsi](https://jitsi.org/) Prosody XMPP server component (optional) + +- [jitsi/jvb](https://hub.docker.com/r/jitsi/jvb) - the [Jitsi](https://jitsi.org/) Video Bridge component (optional) + +- [anoa/matrix-reminder-bot](https://hub.docker.com/r/anoa/matrix-reminder-bot) - the [matrix-reminder-bot](https://github.com/anoadragon453/matrix-reminder-bot) bot for one-off & recurring reminders and alarms (optional) + +- [moanos/matrix-registration-bot/](https://hub.docker.com/r/moanos/matrix-registration-bot/) - the [matrix-registration-bot](https://github.com/moan0s/matrix-registration-bot) bot (manage registration tokens for invitations to the server) (optional) + +- [dock.mau.dev/maubot/maubot](https://mau.dev/maubot/maubot/container_registry) - the [maubot](https://github.com/maubot/maubot) bot (a plugin-based Matrix bot system) (optional) + +- [etke.cc/honoroit](https://gitlab.com/etke.cc/honoroit/container_registry) - the [honoroit](https://gitlab.com/etke.cc/honoroit) helpdesk bot (optional) + +- [etke.cc/postmoogle](https://gitlab.com/etke.cc/postmoogle/container_registry) - the [Postmoogle](https://gitlab.com/etke.cc/postmoogle) email bridge bot (optional) + +- [matrixdotorg/go-neb](https://hub.docker.com/r/matrixdotorg/go-neb) - the [Go-NEB](https://github.com/matrix-org/go-neb) bot (optional) + +- [matrixdotorg/mjolnir](https://hub.docker.com/r/matrixdotorg/mjolnir) - the [mjolnir](https://github.com/matrix-org/mjolnir) moderation bot (optional) + +- [awesometechnologies/synapse-admin](https://hub.docker.com/r/awesometechnologies/synapse-admin) - the [synapse-admin](https://github.com/Awesome-Technologies/synapse-admin) web UI tool for administrating users and rooms on your Matrix server (optional) + +- [prom/prometheus](https://hub.docker.com/r/prom/prometheus/) - [Prometheus](https://github.com/prometheus/prometheus/) is a systems and service monitoring system + +- [prom/node-exporter](https://hub.docker.com/r/prom/node-exporter/) - [Prometheus Node Exporter](https://github.com/prometheus/node_exporter/) is an addon for Prometheus that gathers standard system metrics + +- [grafana/grafana](https://hub.docker.com/r/grafana/grafana/) - [Grafana](https://github.com/grafana/grafana/) is a graphing tool that works well with the above two images. Our playbook also adds two dashboards for [Synapse](https://github.com/matrix-org/synapse/tree/master/contrib/grafana) and [Node Exporter](https://github.com/rfrail3/grafana-dashboards) + +- [matrixdotorg/sygnal](https://hub.docker.com/r/matrixdotorg/sygnal/) - [Sygnal](https://github.com/matrix-org/sygnal) is a reference Push Gateway for Matrix + +- [binwiederhier/ntfy](https://hub.docker.com/r/binwiederhier/ntfy/) - [ntfy](https://ntfy.sh/) is a self-hosted, UnifiedPush-compatible push notifications server + +- [cactuscomments/cactus-appservice](https://hub.docker.com/r/cactuscomments/cactus-appservice/) - [Cactus Comments](https://cactus.chat) a federated comment system built on Matrix diff --git a/docs/faq.md b/docs/faq.md new file mode 100644 index 0000000..25d02e7 --- /dev/null +++ b/docs/faq.md @@ -0,0 +1,475 @@ +# Frequently Asked Questions + +This documentation page tries to answer various Frequently Asked Questions about all things [Matrix](https://matrix.org/), with a focus on this [Ansible](https://www.ansible.com/) playbook ([What is Ansible? How does it work?](#what-is-ansible-how-does-it-work)). + +This FAQ page does not intend to replace the [matrix.org FAQ](https://matrix.org/faq/) (please see that one too). + +We've only started this FAQ recently, so it's still somewhat empty. + +Also, we encourage you to not dig yourself into a hole by reading way too much. When you've heard enough, proceed to [Prerequisites](prerequisites.md) to get guided into installing Matrix. + + +## Introductory + +## Where do I find more questions and answers about Matrix? + +This is a Frequently Asked Questions page focused on this [Ansible](https://www.ansible.com/) playbook ([What is Ansible? How does it work?](#what-is-ansible-how-does-it-work)) for deploying a [Matrix](https://matrix.org/) server. + +For a lot more generic questions and answers, see the [matrix.org FAQ](https://matrix.org/faq/). + +## What is Matrix? What is Element? What is Synapse? Why are you confusing me with so many terms? + +[Matrix](https://matrix.org/) is a new type of realtime communication (chat) network, the closest analogy to which is probably "email". + +You don't just use the "email" protocols (SMTP, POP3, IMAP) directly though. There's a *server* somewhere which stores your data (`@gmail.com`, `@yahoo.com`, `@hotmail.com`, `@your-company.com`) and you access it by using these "email" protocols via some *client* program (Outlook, Thunderbird, some website, etc). + +In the world of the Matrix chat protocol, there are various client programs. The first and currently most full-featured one is called [Element](https://element.io/) (used to be called Riot.im and Vector.im in the past). There are [many other clients](https://matrix.org/clients/). You can switch clients as much as you want until you find the one that is right for you on a given platform (you may use Element on your desktop, but Fluffychat on your phone, etc). + +Matrix is also like email due to the fact that there are many servers around the world which can all talk to each other (you can send email from `@gmail.com` addresses to `@yahoo.com` and `@hotmail.com` addresses). It's the same with Matrix (`@bob:his-domain.com` can talk to `@alice:her-domain.org`). + +If someone else is hosting your Matrix server (you being `@user:matrix.org` or some other public server like this), all you need is a Matrix client program, like Element. + +If you'd like to host your own server (you being `@user:your-own-domain.com`), you'd need to set up a Matrix server program, like Synapse. + +In short: + +- Matrix is the protocol - a set of rules about how the chat network operates +- Element is a client program you can use to participate on the Matrix chat network via some server (yours or someone else's). There are also [many other client programs](https://matrix.org/clients/). +- Synapse is a server program you can use to host your very own Matrix server. + +This FAQ here mostly focuses on installing various Matrix services using the Ansible automation tool. You can learn much more about Matrix in the [matrix.org FAQ](https://matrix.org/faq/). + +## People I wish to talk to are not on Matrix. Can I talk to them? + +You most likely can. Besides Matrix-native chats, Matrix also supports the concept of "bridging", which allows you to plug other networks into it. + +This Ansible playbook can help you install [tens of bridges for various networks](configuring-playbook.md#bridging-other-networks). + +Besides setting up your own bridges (preferable), you can also use some [public bridges hosted by others](https://publiclist.anchel.nl/#bridges). + +## How do I get started with Matrix? + +One of [Matrix](https://matrix.org/)'s distinguishing strengths (compared to other chat networks) is its decentralized nature. There's not just one entity (company, organization) controlling the servers. Rather there's thousands of servers operated by different people - one server being insecure, slow or disrespective toward its users does not affect the rest of the network. To participate in that decentralization in its fullest, consider hosting your own server or using some public server other than the largest/default one (`matrix.org`). + +There are 3 ways to get into Martix, depending on your technical ability and needs: + +- **using the existing default server** - the easiest way is to use an existing server. The largest public Matrix server is `matrix.org` and it's configured as a default server in clients such as [Element](https://element.io) and many others. Just use Element on the browser via that link (or download the Element app on a smartphone), create an account and start chatting. + +- **using some other server** - instead of using the largest public server (`matrix.org`), you can use another public one. Here's a [list of public Matrix servers](https://joinmatrix.org/servers/) to choose from. Again, you download [Element](https://element.io) or [some other client](https://matrix.org/clients/) of your choosing and adjust the homeserver URL during login. + +- **using your own server** - running your own server puts you in ultimate control of your data. It also lets you have your own user identifiers (e.g. `@bob:your-domain.com`). See [How do I set up my own Matrix server](#how-do-i-set-up-my-own-matrix-server). + +### How do I set up my own Matrix server? + +Normally, you'd first choose the [Matrix](https://matrix.org/) server software you'd like to run. At the time of this writing (January/2021), there's only one fully-featured server program, so there's only one reasonable choice. That's [Synapse](https://github.com/matrix-org/synapse). + +There are [many guides about installing Synapse](https://matrix.org/docs/guides/#installing-synapse). Using this Ansible playbook is just one way of doing it. + +Naturally, we're biased, so our usual recommendation is to go with this [Ansible](https://www.ansible.com/) playbook, instead of installing Synapse (and many many other things around it) manually. +To get started with the playbook, start at the [Prerequisites](prerequisites.md) page. + +### What is Ansible? How does it work? + +[Ansible](https://www.ansible.com/) is an automation program. This "playbook" is a collection of tasks/scripts that will set up a [Matrix](https://matrix.org/) server for you, so you don't have to perform these tasks manually. + +We have written these automated tasks for you and all you need to do is execute them using the Ansible program. + +You can install Ansible and this playbook code repository on your own computer and tell it to install Matrix services at the server living at `matrix.DOMAIN`. We recommend installing Ansible on your own computer. + +Alternatively, you can download Ansible and the playbook itself directly on the `matrix.DOMAIN` server. + +To learn more, see our [dedicated Ansible documentation page](ansible.md). + +### Why use this playbook and not install Synapse and other things manually? + +There are various guides telling you how easy it is to install [Synapse](https://github.com/matrix-org/synapse). + +Reading the documentation of this Ansible playbook, you may also be thinking: + +> I don't know what [Ansible](https://www.ansible.com/) is. I don't know what [Docker](https://www.docker.com/) is. This looks more complicated. + +.. so you may be leaning toward [installing Synapse manually](https://github.com/matrix-org/synapse/blob/master/INSTALL.md). + +The problem with a manual installation is: + +- Synapse is written in Python. If not packaged for your distribution, you'd need to install various Python modules, etc., and keep them updated. +- Synapse requires a [Postgres](https://www.postgresql.org/) database (it can run on SQLite, but that's very much discouraged). So you'd need to install Postgres as well. +- you may also need a reverse-proxy server in front of it (nginx, Apache), so you'd need to be familiar with that +- SSL is required, so you'd need to obtain Let's Encrypt (or other free or non-free) certificates for one or more domain names. You'd need to be familiar with [certbot](https://certbot.eff.org/) (when using Let's Encrypt) or similar software. +- for each additional component you'd like to add (client like [Element](https://element.io), bridge to some other chat network, Integration Manager (sitckers, other services), Identity Manager, etc.), you'll need to spend extra time installing and wiring it with the rest of the system in a way that works. +- you'll likely get slower updates for all of these components, depending on your distro packaging or your own time and ability + +The playbook, on the other hand, installs a bunch of components for you by default, obtains SSL certificates for you, etc. If you'd like, you can enable various bridges and other services with very little effort. All the components are wired to work together. + +All services run in Docker containers (most being officially provided by each component's developers), so we're not at the mercy of distro packaging. + +### Why use this playbook and not just use the Docker image directly? + +Reasons are similar to the reasons for not installing manually. + +Besides Synapse, you'd need other things - a Postgres database, likely the [Element](https://element.io) client, etc., etc. + +Using the playbook, you get all these components in a way that works well together out of the box. + +### What's different about this Ansible playbook compared to [EMnify/matrix-synapse-auto-deploy](https://github.com/EMnify/matrix-synapse-auto-deploy)? + +This is similar to the [EMnify/matrix-synapse-auto-deploy](https://github.com/EMnify/matrix-synapse-auto-deploy) Ansible deployment, but: + +- this one is a complete Ansible playbook (instead of just a role), so it's **easier to run** - especially for folks not familiar with Ansible + +- this one installs and hooks together **a lot more Matrix-related services** for you (see above) + +- this one **can be executed more than once** without causing trouble + +- works on various distros: **CentOS** (7.0+), Debian-based distributions (**Debian** 10/Buster+, **Ubuntu** 18.04+), **Archlinux** + +- this one installs everything in a single directory (`/matrix` by default) and **doesn't "contaminate" your server** with files all over the place + +- this one **doesn't necessarily take over** ports 80 and 443. By default, it sets up nginx for you there, but you can also [use your own webserver](configuring-playbook-own-webserver.md) + +- this one **runs everything in Docker containers**, so it's likely more predictable and less fragile (see [Docker images used by this playbook](container-images.md)) + +- this one retrieves and automatically renews free [Let's Encrypt](https://letsencrypt.org/) **SSL certificates** for you + +- this one optionally can store the `media_store` content repository files on [Amazon S3](https://aws.amazon.com/s3/) (but defaults to storing files on the server's filesystem) + +- this one optionally **allows you to use an external PostgreSQL server** for Synapse's database (but defaults to running one in a container) + +- helps you **import data from a previous installation** (so you can migrate your manual virtualenv/Docker setup to a more managed one) + +- this one is actually **maintained** + +## Server-related + +### What kind of server do I need to install Matrix using this Ansible playbook? + +We list our server requirements in [Prerequisites](prerequisites.md). + +### Why not run Matrix on Kubernetes? + +There's no reason not to run Matrix on [Kubernetes](https://kubernetes.io/). + +However, that's overly complicated for thousands of us who just want to run a single small (and sometimes not so small) Matrix server, either using "cloud" servers or even a [Raspberry Pi](https://www.raspberrypi.org/) at home. + +For us, a Kubernetes-based setup which requires a cluster of multiple computers and is more technically-involved is a no-go. + +There are others working on automating a Matrix-on-Kubernetes setup, such as this [Helm](https://helm.sh/) chart: https://github.com/dacruz21/matrix-chart. + +### Why don't you use Podman instead of Docker? + +We like the philosophy of a daemonless container runtime, but [Podman](https://podman.io) is just not ready for our use case yet. + +Learn more about our past experiences/attempts to give Podman a chance, by reading [this issue](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/520). + +In short, `alias podman=docker` is a lie (for us). + +### Why use Docker? + +[Docker](https://www.docker.com/) is one of our 2 hard dependencies (the other one being [systemd](https://systemd.io/)). + +It lets us run services in an isolated manner and independently of the (usually old) packages available for distributions. + +It also lets us have a unified setup which runs the same across various supported distros (see them on [Prerequisites](prerequisites.md)). + +### Is Docker a hard requirement? + +Yes. See [Why don't you use Podman instead of Docker?](#why-dont-you-use-podman-instead-of-docker) for why we're not using another container runtime. + +All of our services run in containers. It's how we achieve predictability and also how we support tens of different services across lots of distros. + +The only thing we need on the distro is systemd and Python (we install Docker ourselves, unless you ask us not to). + +### Why don't you use docker-compose? + +Instead of using [docker-compose](https://docs.docker.com/compose/), we prefer installing systemd services and scheduling those independently. + +There are people who have worked on turning this setup into a docker-compose-based one. See these experiments [here](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/64#issuecomment-603164625). + +### Can I run this on a distro without systemd? + +No. [systemd](https://systemd.io/) is one of our 2 hard dependencies (the other one being [Docker](https://www.docker.com/)). + +### Can I install this on a Raspberry Pi? + +Yes, you can. See our [Alternative Architectures](alternative-architectures.md) documentation page. + +Whether a Raspberry Pi has enough power to give you a good experience is another question. It depends on your use case. + +Also see: [What kind of server specs do I need?](#what-kind-of-server-specs-do-i-need). + +### What kind of server specs do I need? + +This largely depends on your use case. It's not so much the number of users that you plan to host, but rather the number of large rooms they will join. + +Federated rooms with lots of history and containing hundreds of other servers are very heavy CPU-wise and memory-wise. + +You can probably use a 1 CPU + 1GB memory server to host hundreds of local users just fine, but as soon as one of them joins a federated room like `#matrix:matrix.org` (Matrix HQ) or some IRC-bridged room (say `##linux`), your server will get the need for a lot more power (at least 2GB RAM, etc). + +Running Matrix on a server with 1GB of memory is possible (especially if you disable some not-so-important services). See [How do I optimize this setup for a low-power server?](#how-do-i-optimize-this-setup-for-a-low-power-server). + +**We recommend starting with a server having at least 2GB of memory** and even then using it sparingly. If you know for sure you'll be joining various large rooms, etc., then going for 4GB of memory or more is a good idea. + +Besides the regular Matrix stuff, we also support things like video-conferencing using [Jitsi](configuring-playbook-jitsi.md) and other additional services which (when installed) may use up a lot of memory. Things do add up. Besides the Synapse Matrix server, Jitsi is especially notorious for consuming a lot of resources. If you plan on running Jitsi, we recommend a server with at least 2GB of memory (preferrably more). See our [Jitsi documentation page](configuring-playbook-jitsi.md) to learn how to optimize its memory/CPU usage. + +### Can I run this in an LXC container? + +If your distro runs within an [LXC container](https://linuxcontainers.org/), you may hit [this issue](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/703). It can be worked around, if absolutely necessary, but we suggest that you avoid running from within an LXC container. + + +## Configuration + +### Why install my server at matrix.DOMAIN and not at the base DOMAIN? + +It's the same with email servers. Your email address is likely `name@company.com`, not `name@mail.company.com`, even though it's `mail.company.com` that is really handling your data for `@company.com` email to work. + +Using a separate domain name is easier to manage (although it's a little hard to get right at first) and keeps your Matrix server isolated from your website (if you have one), from your email server (if you have one), etc. + +We allow `matrix.DOMAIN` to be the Matrix server handling Matrix stuff for `DOMAIN` by [Server Delegation](howto-server-delegation.md). During the installation procedure, we recommend that you set up server delegation using the [.well-known](configuring-well-known.md) method. + +If you'd really like to install Matrix services directly on the base domain, see [How do I install on matrix.DOMAIN without involving the base DOMAIN?](#how-do-i-install-on-matrixdomain-without-involving-the-base-domain) + +### I don't control anything on the base domain and can't set up delegation to matrix.DOMAIN. What do I do? + +If you're not in control of your base domain (or the server handling it) at all, you can take a look at [How do I install on matrix.DOMAIN without involving the base DOMAIN?](#how-do-i-install-on-matrixdomain-without-involving-the-base-domain) + +### I can't set up HTTPS on the base domain. How will I get Matrix federating? + +If you really can't obtain an HTTPS certificate for your base domain, you can take a look at [How do I install on matrix.DOMAIN without involving the base DOMAIN?](#how-do-i-install-on-matrixdomain-without-involving-the-base-domain) + +### How do I install on matrix.DOMAIN without involving the base DOMAIN? + +This Ansible playbook guides you into installing a server for `DOMAIN` (user identifiers are like this: `@user:DOMAIN`), while the server is at `matrix.DOMAIN`. + +We allow `matrix.DOMAIN` to be the Matrix server handling Matrix stuff for `DOMAIN` by [Server Delegation](howto-server-delegation.md). During the installation procedure, we recommend that you set up server delegation using the [.well-known](configuring-well-known.md) method. + +If you're fine with uglier identifiers (`@user:matrix.DOMAIN`, which is the equivalent of having an email address like `bob@mail.company.com`, instead of just `bob@company.com`), you can do that as well using the following configuration in your `vars.yml` file: + +```yaml +# This is what your identifiers are like (e.g. `@bob:matrix.YOUR_BASE_DOMAIN`). +matrix_domain: "matrix.YOUR_BASE_DOMAIN" + +# This is where Matrix services +matrix_server_fqn_matrix: "matrix.YOUR_BASE_DOMAIN" + +# This is where you access the Element web UI from (if enabled via `matrix_client_element_enabled: true`; enabled by default). +# This and the Matrix FQN (see above) are expected to be on the same server. +# +# Feel free to use `element.matrix.YOUR_BASE_DOMAIN`, if you'd prefer that. +matrix_server_fqn_element: "element.YOUR_BASE_DOMAIN" + +# This is where you access Dimension (if enabled via `matrix_dimension_enabled: true`; NOT enabled by default). +# +# Feel free to use `dimension.matrix.YOUR_BASE_DOMAIN`, if you'd prefer that. +matrix_server_fqn_dimension: "dimension.YOUR_BASE_DOMAIN" + +# This is where you access Jitsi (if enabled via `matrix_jitsi_enabled: true`; NOT enabled by default). +# +# Feel free to use `jitsi.matrix.YOUR_BASE_DOMAIN`, if you'd prefer that. +matrix_server_fqn_jitsi: "jitsi.YOUR_BASE_DOMAIN" +``` + +### I don't use the base domain for anything. How am I supposed to set up Server Delegation for Matrix services? + +If you don't use your base domain for anything, then it's hard for you to "serve files over HTTPS" on it -- something we ask you to do for the [.well-known](configuring-well-known.md) setup (needed for [Server Delegation](howto-server-delegation.md)). + +Luckily, the playbook can set up your Matrix server (at `matrix.DOMAIN`) to also handle traffic for the base domain (`DOMAIN`). + +See [Serving the base domain](configuring-playbook-base-domain-serving.md). + +### How do I optimize this setup for a low-power server? + +You can disable some not-so-important services to save on memory. + +```yaml +# An identity server is not a must. +matrix_ma1sd_enabled: false + +# Disabling this will prevent email-notifications and other such things from working. +matrix_mailer_enabled: false + +# You can also disable this to save more RAM, +# at the expense of audio/video calls being unreliable. +matrix_coturn_enabled: false + +# This makes Synapse not keep track of who is online/offline. +# +# Keeping track of this and announcing such online-status in federated rooms with +# hundreds of servers inside is insanely heavy (https://github.com/matrix-org/synapse/issues/3971). +# +# If your server does not federate with hundreds of others, enabling this doesn't hurt much. +matrix_synapse_presence_enabled: false +``` + +You can also consider implementing a restriction on room complexity, in order to prevent users from joining very heavy rooms: + +```yaml +matrix_synapse_configuration_extension_yaml: | + limit_remote_rooms: + enabled: true + complexity: 1.0 # this limits joining complex (~large) rooms, can be + # increased, but larger values can require more RAM +``` + +If you've installed [Jitsi](configuring-playbook-jitsi.md) (not installed by default), there are additional optimizations listed on its documentation page that you can perform. + +### I already have Docker on my server. Can you stop installing Docker via the playbook? + +Yes, we can stop installing Docker ourselves. Just use this in your `vars.yml` file: + +```yaml +matrix_playbook_docker_installation_enabled: false +``` + +### I run another webserver on the same server where I wish to install Matrix. What now? + +By default, we install a webserver for you (nginx), but you can also use [your own webserver](configuring-playbook-own-webserver.md). + +### How is the effective configuration determined? + +Configuration variables are defined in multiple places in this playbook and are considered in this order: + +- there are defaults coming from each role's defaults file (`role/matrix*/defaults/main.yml`). These variable values aim to be good defaults for when the role is used standalone (outside of this collection of roles, also called playbook). + +- then, there are overrides in `group_vars/matrix_servers`, which aim to adjust these "standalone role defaults" to something which better fits the playbook in its entirety. + +- finally, there's your `inventory/host_vars/matrix.DOMAIN/vars.yml` file, which is the ultimate override + +### What configuration variables are available? + +You can discover the variables you can override in each role (`role/matrix*/defaults/main.yml`). + +As described in [How is the effective configuration determined?](#how-is-the-effective-configuration-determined), these role-defaults may be overriden by values defined in `group_vars/matrix_servers`. + +Refer to both of these for inspiration. Still, as mentioned in [Configuring the playbook](configuring-playbook.md), you're only ever supposed to edit your own `inventory/host_vars/matrix.DOMAIN/vars.yml` file and nothing else inside the playbook (unless you're meaning to contribute new features). + +### I'd like to adjust some configuration which doesn't have a corresponding variable. How do I do it? + +The playbook doesn't aim to expose all configuration settings for all services using variables. +Doing so would amount to hundreds of variables that we have to create and maintain. + +Instead, we only try to make some important basics configurable using dedicated variables you can see in each role. +See [What configuration variables are available?](#what-configuration-variables-are-available). + +Besides that, each role (component) aims to provide a `matrix_SOME_COMPONENT_configuration_extension_yaml` (or `matrix_SOME_COMPONENT_configuration_extension_json`) variable, which can be used to override the configuration. + +Check each role's `role/matrix*/defaults/main.yml` for the corresponding variable and an example for how use it. + + +## Installation + +### How do I run the installation? + +See [Installing](installing.md) to learn how to use Ansible to install Matrix services. + +Of course, don't just jump straight to Installing. Rather, start at [Prerequisites](prerequisites.md) and get guided from there (into [setting up DNS](configuring-dns.md), [configuring the playbook](configuring-playbook.md), etc). + +### I installed Synapse some other way. Can I migrate such a setup to the playbook? + +Yes, you can. + +You generally need to do a playbook installation (start at the [Prerequisites](prerequisites.md) page), followed by importing your existing data into it. + +This Ansible playbook guides you into installing a server for `DOMAIN` (user identifiers are like this: `@user:DOMAIN`), while the server is at `matrix.DOMAIN`. If your existing setup has a server name (`server_name` configuration setting in Synapse's `homeserver.yaml` file) other than the base `DOMAIN`, you may need to tweak some additional variables. This FAQ entry may be of use if you're dealing with a more complicated setup - [How do I install on matrix.DOMAIN without involving the base DOMAIN?](#how-do-i-install-on-matrixdomain-without-involving-the-base-domain) + +After configuring the playbook and installing and **before starting** services (done with `ansible-playbook ... --tags=start`) you'd import [your SQLite](importing-synapse-sqlite.md) (or [Postgres](importing-postgres.md)) database and also [import your media store](importing-synapse-media-store.md). + +### I've downloaded Ansible and the playbook on the server. It can't connect using SSH. + +If you're using the playbook directly on the server, then Ansible doesn't need to connect using SSH. + +It can perform a local connection instead. Just set `ansible_connection=local` at the end of the server line in `inventory/hosts` and re-run the playbook. + +If you're running Ansible from within a container (one of the possibilities we list on our [dedicated Ansible documentation page](ansible.md)), then using `ansible_connection=local` is not possible. + + +## Troubleshooting + +### I get "Error response from daemon: configured logging driver does not support reading" when I do `docker logs matrix-synapse`. + +See [How can I see the logs?](#how-can-i-see-the-logs). + +### How can I see the logs? + +We utilize [systemd/journald](https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html#Description) for logging. + +To see logs for Synapse, run `journalctl -fu matrix-synapse.service`. You may wish to see the [manual page for journalctl](https://www.commandlinux.com/man-page/man1/journalctl.1.html). + +Available service names can be seen by doing `ls /etc/systemd/system/matrix*.service` on the server. + +Some services also log to files in `/matrix/*/data/..`, but we're slowly moving away from that. + +We also disable Docker logging, so you can't use `docker logs matrix-*` either. We do this to prevent useless double (or even triple) logging and to avoid having to rotate log files. + +We just simply delegate logging to journald and it takes care of persistence and expiring old data. + +Also see: [How long do systemd/journald logs persist for?](#how-long-do-systemdjournald-logs-persist-for) + +### How long do systemd/journald logs persist for? + +On some distros, the journald logs are just in-memory and not persisted to disk. + +Consult (and feel free to adjust) your distro's journald logging configuration in `/etc/systemd/journald.conf`. + +To enable persistence and put some limits on how large the journal log files can become, adjust your configuration like this: + +```ini +[Journal] +RuntimeMaxUse=200M +SystemMaxUse=1G +RateLimitInterval=0 +RateLimitBurst=0 +Storage=persistent +``` + + +## Maintenance + +### Do I need to do anything to keep my Matrix server updated? + +Yes. We don't update anything for you automatically. + +See our [documentation page about upgrading services](maintenance-upgrading-services.md). + +### How do I move my existing installation to another (VM) server? + +If you have an existing installation done using this Ansible playbook, you can easily migrate that to another server using [our dedicated server migration guide](maintenance-migrating.md). + +If your previous installation is done in some other way (not using this Ansible playbook), see [I installed Synapse some other way. Can I migrate such a setup to the playbook?](#i-installed-synapse-some-other-way-can-i-migrate-such-a-setup-to-the-playbook). + +### How do I back up the data on my server? + +We haven't documented this properly yet, but the general advice is to: + +- back up Postgres by making a database dump. See [Backing up PostgreSQL](maintenance-postgres.md#backing-up-postgresql) + +- back up all `/matrix` files, except for `/matrix/postgres/data` (you already have a dump) and `/matrix/postgres/data-auto-upgrade-backup` (this directory may exist and contain your old data if you've [performed a major Postgres upgrade](maintenance-postgres.md#upgrading-postgresql)). + +You can later restore these roughly like this: + +- restore the `/matrix` directory and files on the new server manually +- run the playbook again (see [Installing](installing.md)), but **don't** start services yet (**don't run** `... --tags=start`). This step will fix any file permission mismatches and will also set up additional software (Docker, etc.) and files on the server (systemd service, etc.). +- perform a Postgres database import (see [Importing Postgres](importing-postgres.md)) to restore your database backup +- start services (see [Starting the services](installing.md#starting-the-services)) + +If your server's IP address has changed, you may need to [set up DNS](configuring-dns.md) again. + +### What is this `/matrix/postgres/data-auto-upgrade-backup` directory that is taking up so much space? + +When you [perform a major Postgres upgrade](maintenance-postgres.md#upgrading-postgresql), we save the the old data files in `/matrix/postgres/data-auto-upgrade-backup`, just so you could easily restore them should something have gone wrong. + +After verifying that everything still works after the Postgres upgrade, you can safely delete `/matrix/postgres/data-auto-upgrade-backup` + +### How do I debug or force SSL certificate renewal? + +SSL certificate renewal normally happens automatically via [systemd timers](https://wiki.archlinux.org/index.php/Systemd/Timers). + +If you're having trouble with SSL certificate renewal, you can inspect the renewal logs using: + +- `journalctl -fu matrix-ssl-lets-encrypt-certificates-renew.service` +- *or* by looking at the log files in `/matrix/ssl/log/` + +To trigger renewal, run: `systemctl start matrix-ssl-lets-encrypt-certificates-renew.service`. You can then take a look at the logs again. + +If you're using the integrated webserver (`matrix-nginx-proxy`), you can reload it manually like this: `systemctl reload matrix-nginx-proxy`. Reloading also happens periodically via a systemd timer. + +If you're [using your own webserver](configuring-playbook-own-webserver.md) instead of the integrated one (`matrix-nginx-proxy`) you may also need to reload/restart it, to make it pick up the renewed SSL certificate files. diff --git a/docs/getting-the-playbook.md b/docs/getting-the-playbook.md new file mode 100644 index 0000000..2541da0 --- /dev/null +++ b/docs/getting-the-playbook.md @@ -0,0 +1,41 @@ +# Getting the playbook + +This Ansible playbook is meant to be executed on your own computer (not the Matrix server). + +In special cases (if your computer cannot run Ansible, etc.) you may put the playbook on the server as well. + +You can retrieve the playbook's source code by: + +- [Using git to get the playbook](#using-git-to-get-the-playbook) (recommended) + +- [Downloading the playbook as a ZIP archive](#downloading-the-playbook-as-a-zip-archive) (not recommended) + + +## Using git to get the playbook + +We recommend using the [git](https://git-scm.com/) tool to get the playbook's source code, because it lets you easily keep up to date in the future when [Maintaining services](maintenance-upgrading-services.md). + +Once you've installed git on your computer, you can go to any directory of your choosing and run the following command to retrieve the playbook's source code: + +```bash +git clone https://github.com/spantaleev/matrix-docker-ansible-deploy.git +``` + +This will create a new `matrix-docker-ansible-deploy` directory. +You're supposed to execute all other installation commands inside that directory. + + +## Downloading the playbook as a ZIP archive + +Alternatively, you can download the playbook as a ZIP archive. +This is not recommended, as it's not easy to keep up to date with future updates. We suggest you [use git](#using-git-to-get-the-playbook) instead. + +The latest version is always at the following URL: https://github.com/spantaleev/matrix-docker-ansible-deploy/archive/master.zip + +You can extract this archive anywhere. You'll get a directory called `matrix-docker-ansible-deploy-master`. +You're supposed to execute all other installation commands inside that directory. + + +--------------------------------------------- + +No matter which method you've used to download the playbook, you can proceed by [Configuring the playbook](configuring-playbook.md). diff --git a/docs/howto-server-delegation.md b/docs/howto-server-delegation.md new file mode 100644 index 0000000..e9ca5bd --- /dev/null +++ b/docs/howto-server-delegation.md @@ -0,0 +1,132 @@ +# Server Delegation + +To have a server on a subdomain (e.g. `matrix.`) handle Matrix federation traffic for the base domain (``), we need to instruct the Matrix network of such a delegation. + +By default, this playbook guides you into setting up [Server Delegation via a well-known file](#server-delegation-via-a-well-known-file). +However, that method may have some downsides that are not to your liking. Hence this guide about alternative ways to set up Server Delegation. + +It is a complicated matter, so unless you are affected by the [Downsides of well-known-based Server Delegation](#downsides-of-well-known-based-server-delegation), we suggest you stay on the simple/default path. + + +## Server Delegation via a well-known file + +Serving a `/.well-known/matrix/server` file from the base domain is the most straightforward way to set up server delegation, but it suffers from some problems that we list in [Downsides of well-known-based Server Delegation](#downsides-of-well-known-based-server-delegation). + +As we already mention in [Configuring DNS](configuring-dns.md) and [Configuring Service Discovery via .well-known](configuring-well-known.md), +this playbook already properly guides you into setting up such delegation by means of a `/.well-known/matrix/server` file served from the base domain (``). + +If this is okay with you, feel free to not read ahead. + + +### Downsides of well-known-based Server Delegation + +Server Delegation by means of a `/.well-known/matrix/server` file is the most straightforward, but suffers from the following downsides: + +- you need to have a working HTTPS server for the base domain (``). If you don't have any server for the base domain at all, you can easily solve it by making the playbook [serve the base domain from the Matrix server](configuring-playbook-base-domain-serving.md). + +- any downtime on the base domain (``) or network trouble between the matrix subdomain (`matrix.`) and the base `` may cause Matrix Federation outages. As the [Server-Server spec says](https://matrix.org/docs/spec/server_server/r0.1.0.html#server-discovery): + +> Errors are recommended to be cached for up to an hour, and servers are encouraged to exponentially back off for repeated failures. + +**For most people, this is a reasonable tradeoff** given that it's easy and straightforward to set up. We recommend you stay on this path. + +Otherwise, you can decide to go against the default for this playbook, and instead set up [Server Delegation via a DNS SRV record (advanced)](#server-delegation-via-a-dns-srv-record-advanced) (much more complicated). + + +## Server Delegation via a DNS SRV record (advanced) + +**NOTE**: doing Server Delegation via a DNS SRV record is a more **advanced** way to do it and is not the default for this playbook. This is usually **much more complicated** to set up, so **we don't recommend it**. If you're not an experience sysadmin, you'd better stay away from this. + +As per the [Server-Server spec](https://matrix.org/docs/spec/server_server/r0.1.0.html#server-discovery), it's possible to do Server Delegation using only a SRV record (without a `/.well-known/matrix/server` file). + +This prevents you from suffering the [Downsides of well-known-based Server Delegation](#downsides-of-well-known-based-server-delegation). + +To use DNS SRV record validation, you need to: + +- ensure that `/.well-known/matrix/server` is **not served** from the base domain, as that would interfere with DNS SRV record Server Delegation. To make the playbook **not** generate and serve the file, use the following configuration: `matrix_well_known_matrix_server_enabled: false`. + +- ensure that you have a `_matrix._tcp` DNS SRV record for your base domain (``) with a value of `10 0 8448 matrix.` + +- ensure that you are serving the Matrix Federation API (tcp/8448) with a certificate for `` (not `matrix.`!). Getting this certificate to the `matrix.` server may be complicated. The playbook's automatic SSL obtaining/renewal flow will likely not work and you'll need to copy certificates around manually. See below. + + +### Obtaining certificates + +How you can obtain a valid certificate for `` on the `matrix.` server is up to you. + +If `` and `matrix.` are hosted on the same machine, you can let the playbook obtain the certificate for you, by following our [Obtaining SSL certificates for additional domains](configuring-playbook-ssl-certificates.md#obtaining-ssl-certificates-for-additional-domains) guide. + +If `` and `matrix.` are not hosted on the same machine, you can copy over the certificate files manually. +Don't forget that they may get renewed once in a while, so you may also have to transfer them periodically. How often you do that is up to you, as long as the certificate files don't expire. + + +### Serving the Federation API with your certificates + +Regardless of which method for obtaining certificates you've used, once you've managed to get certificates for your base domain onto the `matrix.` machine you can put them to use. + +Based on your setup, you have different ways to go about it: + +- [Serving the Federation API with your certificates and matrix-nginx-proxy](#serving-the-federation-api-with-your-certificates-and-matrix-nginx-proxy) + +- [Serving the Federation API with your certificates and another webserver](#serving-the-federation-api-with-your-certificates-and-another-webserver) + +- [Serving the Federation API with your certificates and Synapse handling Federation](#serving-the-federation-api-with-your-certificates-and-synapse-handling-federation) + + +### Serving the Federation API with your certificates and matrix-nginx-proxy + +**If you are using matrix-nginx-proxy**, a reverse-proxy webserver used by default in this playbook, you only need to override the certificates used for the Matrix Federation API. You can do that using: + +```yaml +# Adjust paths below to point to your certificate. +# +# NOTE: these are in-container paths. `/matrix/ssl` on the host is mounted into the container +# at the same path (`/matrix/ssl`) by default, so if that's the path you need, it would be seamless. +matrix_nginx_proxy_proxy_matrix_federation_api_ssl_certificate: /matrix/ssl/config/live//fullchain.pem +matrix_nginx_proxy_proxy_matrix_federation_api_ssl_certificate_key: /matrix/ssl/config/live//privkey.pem +``` + +If your files are not in `/matrix/ssl` but in some other location, you would need to mount them into the container: + +```yaml +matrix_nginx_proxy_container_extra_arguments: + - "--mount type=bind,src=/some/path/on/the/host,dst=/some/path/inside/the/container,ro" +``` + +You then refer to them (for `matrix_nginx_proxy_proxy_matrix_federation_api_ssl_certificate` and `matrix_nginx_proxy_proxy_matrix_federation_api_ssl_certificate_key`) by using `/some/path/inside/the/container`. + +Make sure to reload matrix-nginx-proxy once in a while (`systemctl reload matrix-nginx-proxy`), so that newer certificates can kick in. +Reloading doesn't cause any downtime. + + +### Serving the Federation API with your certificates and another webserver + +**If you are NOT using matrix-nginx-proxy**, but rather some other webserver, you can set up reverse-proxying for the `tcp/8448` port by yourself. +Make sure to use the proper certificates for `` (not for `matrix.`) when serving the `tcp/8448` port. + +Proxying needs to happen to `127.0.0.1:8048` (unencrypted Synapse federation listener). + +Make sure to reload/restart your webserver once in a while, so that newer certificates can kick in. + + +### Serving the Federation API with your certificates and Synapse handling Federation + +**Alternatively**, if you are **NOT using matrix-nginx-proxy** and **would rather not use your own webserver for Federation traffic**, you can let Synapse handle Federation by itself. + +To do that, make sure the certificate files are mounted into the Synapse container: + +```yaml +matrix_synapse_container_extra_arguments: + - "--mount type=bind,src=/some/path/on/the/host,dst=/some/path/inside/the/container,ro" +``` + +You can then tell Synapse to serve Federation traffic over TLS on `tcp/8448`: + +```yaml +matrix_synapse_tls_federation_listener_enabled: true +matrix_synapse_tls_certificate_path: /some/path/inside/the/container/certificate.crt +matrix_synapse_tls_private_key_path: /some/path/inside/the/container/private.key +``` + +Make sure to reload Synapse once in a while (`systemctl reload matrix-synapse`), so that newer certificates can kick in. +Reloading doesn't cause any downtime. diff --git a/docs/importing-postgres.md b/docs/importing-postgres.md new file mode 100644 index 0000000..a44afdc --- /dev/null +++ b/docs/importing-postgres.md @@ -0,0 +1,105 @@ +# Importing an existing Postgres database from another installation (optional) + +Run this if you'd like to import your database from a previous installation. +(don't forget to import your Synapse `media_store` files as well - see [the importing-synape-media-store guide](importing-synapse-media-store.md)). + + +## Prerequisites + +For this to work, **the database name in Postgres must match** what this playbook uses. +This playbook uses a Postgres database name of `synapse` by default (controlled by the `matrix_synapse_database_database` variable). +If your database name differs, be sure to change `matrix_synapse_database_database` to your desired name and to re-run the playbook before proceeding. + +The playbook supports importing Postgres dump files in **text** (e.g. `pg_dump > dump.sql`) or **gzipped** formats (e.g. `pg_dump | gzip -c > dump.sql.gz`). + +Importing multiple databases (as dumped by `pg_dumpall`) is also supported. +But the migration might be a good moment, to "reset" a not properly working bridge. Be aware, that it might affect all users (new link to bridge, new rooms, ...) + +Before doing the actual import, **you need to upload your Postgres dump file to the server** (any path is okay). + + +## Importing + +To import, run this command (make sure to replace `` with a file path on your server): + +```sh +ansible-playbook -i inventory/hosts setup.yml \ +--extra-vars='server_path_postgres_dump= postgres_default_import_database=matrix' \ +--tags=import-postgres +``` + +**Notes**: + +- `` must be a file path to a Postgres dump file on the server (not on your local machine!) +- `postgres_default_import_database` defaults to `matrix`, which is useful for importing multiple databases (for dumps made with `pg_dumpall`). If you're importing a single database (e.g. `synapse`), consider changing `postgres_default_import_database` accordingly + + +## Troubleshooting + +### Table Ownership +A table ownership issue can occur if you are importing from a Synapse installation which was both: + + - migrated from SQLite to Postgres, and + - used a username other than 'synapse' + +In this case you may run into the following error during the import task: + +``` +"ERROR: role \"synapse_user\" does not exist" +``` + +where `synapse_user` is the database username from the previous Synapse installation. + +This can be verified by examining the dump for ALTER TABLE statements which set OWNER TO that username: + +```Shell +$ grep "ALTER TABLE" homeserver.sql +ALTER TABLE public.access_tokens OWNER TO synapse_user; +ALTER TABLE public.account_data OWNER TO synapse_user; +ALTER TABLE public.account_data_max_stream_id OWNER TO synapse_user; +ALTER TABLE public.account_validity OWNER TO synapse_user; +ALTER TABLE public.application_services_state OWNER TO synapse_user; +... +``` + +It can be worked around by changing the username to `synapse`, for example by using `sed`: + +```Shell +$ sed -i "s/OWNER TO synapse_user;/OWNER TO synapse;/g" homeserver.sql +``` + +This uses sed to perform an 'in-place' (`-i`) replacement globally (`/g`), searching for `synapse_user` and replacing with `synapse` (`s/synapse_user/synapse`). If your database username was different, change `synapse_user` to that username instead. Expand search/replace statement as shown in example above, in case of old user name like `matrix` - replacing `matrix` only would... well - you can imagine. + +Note that if the previous import failed with an error it may have made changes which are incompatible with re-running the import task right away; if you do so it may fail with an error such as: + +``` +ERROR: relation \"access_tokens\" already exists +``` + +### Repeat import + +In this case you can use the command suggested in the import task to clear the database before retrying the import: + +```Shell +# systemctl stop matrix-postgres +# rm -rf /matrix/postgres/data/* +# systemctl start matrix-postgres +``` + +Now on your local machine run `ansible-playbook -i inventory/hosts setup.yml --tags=setup-postgres` to prepare the database roles etc. + +If not, you probably get this error. `synapse` is the correct table owner, but the role is missing in database. +``` +"ERROR: role synapse does not exist" +``` + +Once the database is clear and the ownership of the tables has been fixed in the SQL file, the import task should succeed. +Check, if `--dbname` is set to `synapse` (not `matrix`) and replace paths (or even better, copy this line from your terminal) + +``` +/usr/bin/env docker run --rm --name matrix-postgres-import --log-driver=none --user=998:1001 --cap-drop=ALL --network=matrix --env-file=/matrix/postgres/env-postgres-psql --mount type=bind,src=/migration/synapse_dump.sql,dst=/synapse_dump.sql,ro --entrypoint=/bin/sh docker.io/postgres:15.0-alpine -c "cat /synapse_dump.sql | grep -vE '^(CREATE|ALTER) ROLE (matrix)(;| WITH)' | grep -vE '^CREATE DATABASE (matrix)\s' | psql -v ON_ERROR_STOP=1 -h matrix-postgres --dbname=synapse" +``` + +### Hints + +To open psql terminal run `/matrix/postgres/bin/cli` diff --git a/docs/importing-synapse-media-store.md b/docs/importing-synapse-media-store.md new file mode 100644 index 0000000..0ba7bac --- /dev/null +++ b/docs/importing-synapse-media-store.md @@ -0,0 +1,22 @@ +# Importing `media_store` data files from an existing Synapse installation (optional) + +Run this if you'd like to import your `media_store` files from a previous installation of Synapse. + + +## Prerequisites + +Before doing the actual data restore, **you need to upload your media store directory to the server** (any path is okay). + +If you are [Storing Matrix media files on Amazon S3](configuring-playbook-s3.md) (optional), restoring with this tool is not possible right now. +As an alternative, you can perform a manual restore using the [AWS CLI tool](https://aws.amazon.com/cli/) (e.g. `aws s3 sync /path/to/server/media_store/. s3://name-of-bucket/`) + +**Note for Mac users**: Due to case-sensitivity issues on certain Mac filesystems (HFS or HFS+), filename corruption may occur if you copy a `media_store` directory to your Mac. If you're transferring a `media_store` directory between 2 servers, make sure you do it directly (from server to server with a tool such as [rsync](https://rsync.samba.org/)), and not by downloading the files to your Mac. + + +## Importing + +Run this command (make sure to replace `` with a path on your server): + + ansible-playbook -i inventory/hosts setup.yml --extra-vars='server_path_media_store=' --tags=import-synapse-media-store + +**Note**: `` must be a file path to a `media_store` directory on the server (not on your local machine!). diff --git a/docs/importing-synapse-sqlite.md b/docs/importing-synapse-sqlite.md new file mode 100644 index 0000000..aade222 --- /dev/null +++ b/docs/importing-synapse-sqlite.md @@ -0,0 +1,26 @@ +# Importing an existing SQLite database from another Synapse installation (optional) + +Run this if you'd like to import your database from a previous default installation of Synapse. +(don't forget to import your `media_store` files as well - see [the importing-synapse-media-store guide](importing-synapse-media-store.md)). + +While this playbook always sets up PostgreSQL, by default a Synapse installation would run +using an SQLite database. + +If you have such a Synapse setup and wish to migrate it here (and over to PostgreSQL), this command is for you. + + +## Prerequisites + +Before doing the actual import, **you need to upload your SQLite database file to the server** (any path is okay). + + +## Importing + +Run this command (make sure to replace `` with a file path on your server): + + ansible-playbook -i inventory/hosts setup.yml --extra-vars='server_path_homeserver_db=' --tags=import-synapse-sqlite-db + +**Notes**: + +- `` must be a file path to a `homeserver.db` **file on the server** (not on your local machine!). +- if the SQLite database is from an older version of Synapse, the **importing procedure may run migrations on it to bring it up to date**. That is, your SQLite database file may get modified and become unusable with your older Synapse version. Keeping a copy of the original is probably wise. diff --git a/docs/installing.md b/docs/installing.md new file mode 100644 index 0000000..3bbc9a4 --- /dev/null +++ b/docs/installing.md @@ -0,0 +1,109 @@ +# Installing + +If you've [configured your DNS](configuring-dns.md) and have [configured the playbook](configuring-playbook.md), you can start the installation procedure. + +**Before installing** and each time you update the playbook in the future, you will need to update the Ansible roles in this playbook by running `make roles`. `make roles` is a shortcut (a `roles` target defined in [`Makefile`](Makefile) and executed by the [`make`](https://www.gnu.org/software/make/) utility) which ultimately runs [ansible-galaxy](https://docs.ansible.com/ansible/latest/cli/ansible-galaxy.html) to download Ansible roles. If you don't have `make`, you can also manually run the `roles` commands seen in the `Makefile`. + + +## Playbook tags introduction + +The Ansible playbook's tasks are tagged, so that certain parts of the Ansible playbook can be run without running all other tasks. + +The general command syntax is: `ansible-playbook -i inventory/hosts setup.yml --tags=COMMA_SEPARATED_TAGS_GO_HERE` + +Here are some playbook tags that you should be familiar with: + +- `setup-all` - runs all setup tasks (installation and uninstallation) for all components, but does not start/restart services + +- `install-all` - like `setup-all`, but skips uninstallation tasks. Useful for maintaining your setup quickly when its components remain unchanged. If you adjust your `vars.yml` to remove components, you'd need to run `setup-all` though, or these components will still remain installed + +- `setup-SERVICE` (e.g. `setup-bot-postmoogle`) - runs the setup tasks only for a given role, but does not start/restart services. You can discover these additional tags in each role (`roles/*/main.yml`). Running per-component setup tasks is **not recommended**, as components sometimes depend on each other and running just the setup tasks for a given component may not be enough. For example, setting up the [mautrix-telegram bridge](configuring-playbook-bridge-mautrix-telegram.md), in addition to the `setup-mautrix-telegram` tag, requires database changes (the `setup-postgres` tag) as well as reverse-proxy changes (the `setup-nginx-proxy` tag). + +- `install-SERVICE` (e.g. `install-bot-postmoogle`) - like `setup-SERVICE`, but skips uninstallation tasks. See `install-all` above for additional information. + +- `start` - starts all systemd services and makes them start automatically in the future + +- `stop` - stops all systemd services + +- `ensure-matrix-users-created` - a special tag which ensures that all special users needed by the playbook (for bots, etc.) are created + +`setup-*` tags and `install-*` tags **do not start services** automatically, because you may wish to do things before starting services, such as importing a database dump, restoring data from another server, etc. + + +## 1. Installing Matrix + +If you **don't** use SSH keys for authentication, but rather a regular password, you may need to add `--ask-pass` to the all Ansible commands + +If you **do** use SSH keys for authentication, **and** use a non-root user to *become* root (sudo), you may need to add `-K` (`--ask-become-pass`) to all Ansible commands + +There 2 ways to start the installation process - depending on whether you're [Installing a brand new server (without importing data)](#installing-a-brand-new-server-without-importing-data) or [Installing a server into which you'll import old data](#installing-a-server-into-which-youll-import-old-data). + + +### Installing a brand new server (without importing data) + +If this is **a brand new** Matrix server and you **won't be importing old data into it**, run all these tags: + +```sh +ansible-playbook -i inventory/hosts setup.yml --tags=install-all,ensure-matrix-users-created,start +``` + +This will do a full installation and start all Matrix services. + +Proceed to [Maintaining your setup in the future](#2-maintaining-your-setup-in-the-future) and [Finalize the installation](#3-finalize-the-installation) + + +### Installing a server into which you'll import old data + +If you will be importing data into your newly created Matrix server, install it, but **do not** start its services just yet. +Starting its services or messing with its database now will affect your data import later on. + +To do the installation **without** starting services, run only the `setup-all` tag: + +```sh +ansible-playbook -i inventory/hosts setup.yml --tags=install-all +``` + +When this command completes, services won't be running yet. + +You can now: + +- [Importing an existing SQLite database (from another Synapse installation)](importing-synapse-sqlite.md) (optional) + +- [Importing an existing Postgres database (from another installation)](importing-postgres.md) (optional) + +- [Importing `media_store` data files from an existing Synapse installation](importing-synapse-media-store.md) (optional) + +.. and then proceed to starting all services: + +```sh +ansible-playbook -i inventory/hosts setup.yml --tags=start +``` + +Proceed to [Maintaining your setup in the future](#2-maintaining-your-setup-in-the-future) and [Finalize the installation](#3-finalize-the-installation) + + +## 2. Maintaining your setup in the future + +Feel free to **re-run the setup command any time** you think something is off with the server configuration. Ansible will take your configuration and update your server to match. + +Note that if you remove components from `vars.yml`, or if we switch some component from being installed by default to not being installed by default anymore, you'd need to run the setup command with `--tags=setup-all` instead of `--tags=install-all`. See [Playbook tags introduction](#playbook-tags-introduction) + + +## 3. Finalize the installation + +Now that services are running, you need to **finalize the installation process** (required for federation to work!) by [Configuring Service Discovery via .well-known](configuring-well-known.md). + + +## 4. Things to do next + +After you have started the services and **finalized the installation process** (required for federation to work!) by [Configuring Service Discovery via .well-known](configuring-well-known.md), you can: + +- [check if services work](maintenance-checking-services.md) +- or [create your first Matrix user account](registering-users.md) +- or [set up additional services](configuring-playbook.md#other-configuration-options) (bridges to other chat networks, bots, etc.) +- or learn how to [upgrade services when new versions are released](maintenance-upgrading-services.md) +- or learn how to [maintain your server](faq.md#maintenance) +- or join some Matrix rooms: + * via the *Explore rooms* feature in Element or some other client, or by discovering them using this [matrix-static list](https://view.matrix.org). Note: joining large rooms may overload small servers. + * or come say Hi in our support room - [#matrix-docker-ansible-deploy:devture.com](https://matrix.to/#/#matrix-docker-ansible-deploy:devture.com). You might learn something or get to help someone else new to Matrix hosting. +- or help make this playbook better by contributing (code, documentation, or [coffee/beer](https://liberapay.com/s.pantaleev/donate)) diff --git a/docs/maintenance-and-troubleshooting.md b/docs/maintenance-and-troubleshooting.md new file mode 100644 index 0000000..ae90fba --- /dev/null +++ b/docs/maintenance-and-troubleshooting.md @@ -0,0 +1,49 @@ +# Maintenance and Troubleshooting + +## How to see the current status of your services + +You can check the status of your services by using `systemctl status`. Example: +``` +sudo systemctl status matrix-nginx-proxy + +● matrix-nginx-proxy.service - Matrix nginx proxy server + Loaded: loaded (/etc/systemd/system/matrix-nginx-proxy.service; enabled; vendor preset: enabled) + Active: active (running) since Wed 2018-11-14 19:38:35 UTC; 49min ago +``` + +You can see the logs by using journalctl. Example: +``` +sudo journalctl -fu matrix-synapse +``` + + +## Increasing Synapse logging + +Because the [Synapse](https://github.com/matrix-org/synapse) Matrix server is originally very chatty when it comes to logging, we intentionally reduce its [logging level](https://docs.python.org/3/library/logging.html#logging-levels) from `INFO` to `WARNING`. + +If you'd like to debug an issue or [report a Synapse bug](https://github.com/matrix-org/synapse/issues/new/choose) to the developers, it'd be better if you temporarily increasing the logging level to `INFO`. + +Example configuration (`inventory/host_vars/matrix.DOMAIN/vars.yml`): + +```yaml +matrix_synapse_log_level: "INFO" +matrix_synapse_storage_sql_log_level: "INFO" +matrix_synapse_root_log_level: "INFO" +``` + +Re-run the playbook after making these configuration changes. + +## Remove unused Docker data + +You can free some disk space from Docker, see [docker system prune](https://docs.docker.com/engine/reference/commandline/system_prune/) for more information. +```bash +ansible-playbook -i inventory/hosts setup.yml --tags=run-docker-prune +``` + +## Postgres + +See the dedicated [PostgreSQL Maintenance](maintenance-postgres.md) documentation page. + +## Ma1sd + +See the dedicated [Adjusting ma1sd Identity Server configuration](configuring-playbook-ma1sd.md) documentation page. diff --git a/docs/maintenance-checking-services.md b/docs/maintenance-checking-services.md new file mode 100644 index 0000000..151a577 --- /dev/null +++ b/docs/maintenance-checking-services.md @@ -0,0 +1,13 @@ +# Checking if services work + +This playbook can perform a check to ensure that you've configured things correctly and that services are running. + +To perform the check, run: + +```bash +ansible-playbook -i inventory/hosts setup.yml --tags=self-check +``` + +If it's all green, everything is probably running correctly. + +Besides this self-check, you can also check your server using the [Federation Tester](https://federationtester.matrix.org/). diff --git a/docs/maintenance-migrating.md b/docs/maintenance-migrating.md new file mode 100644 index 0000000..fd59369 --- /dev/null +++ b/docs/maintenance-migrating.md @@ -0,0 +1,14 @@ +> **Note**: This migration guide is applicable if you migrate from one server to another server having the same CPU architecture (e.g. both servers being `amd64`). +> +> If you're trying to migrate between different architectures (e.g. `amd64` --> `arm64`), simply copying the complete `/matrix` directory is not possible as it would move the raw PostgreSQL data between different architectures. In this specific case, you can use the guide below as a reference, but you would also need to dump the database on your current server and import it properly on the new server. See our [Backing up PostgreSQL](maintenance-postgres.md#backing-up-postgresql) docs for help with PostgreSQL backup/restore. + +# Migrating to new server + +1. Prepare by lowering DNS TTL for your domains (`matrix.DOMAIN`, etc.), so that DNS record changes (step 4 below) would happen faster, leading to less downtime +2. Stop all services on the old server and make sure they won't be starting again. Execute this on the old server: `systemctl disable --now matrix*` +3. Copy directory `/matrix` from the old server to the new server. Make sure to preserve ownership and permissions (use `cp -p` or `rsync -ar`)! +4. Make sure your DNS records are adjusted to point to the new server's IP address +5. Remove old server from the `inventory/hosts` file and add new server. +6. Run `ansible-playbook -i inventory/hosts setup.yml --tags=setup-system-user`. This will create the `matrix` user and group on the new server +7. Because the `matrix` user and group are created dynamically on each server, the user/group id may differ between the old and new server. We suggest that you adjust ownership of `/matrix` files manually by running this on the new server: `chown -R matrix:matrix /matrix`. +8. Run `ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start` to finish the installation and start all services diff --git a/docs/maintenance-postgres.md b/docs/maintenance-postgres.md new file mode 100644 index 0000000..f2ca907 --- /dev/null +++ b/docs/maintenance-postgres.md @@ -0,0 +1,161 @@ +# PostgreSQL maintenance + +This document shows you how to perform various maintenance tasks related to the Postgres database server used by Matrix. + +Table of contents: + +- [Getting a database terminal](#getting-a-database-terminal), for when you wish to execute SQL queries + +- [Vacuuming PostgreSQL](#vacuuming-postgresql), for when you wish to run a Postgres [VACUUM](https://www.postgresql.org/docs/current/sql-vacuum.html) (optimizing disk space) + +- [Backing up PostgreSQL](#backing-up-postgresql), for when you wish to make a backup + +- [Upgrading PostgreSQL](#upgrading-postgresql), for upgrading to new major versions of PostgreSQL. Such **manual upgrades are sometimes required**. + +- [Tuning PostgreSQL](#tuning-postgresql) to make it run faster + +## Getting a database terminal + +You can use the `/matrix/postgres/bin/cli` tool to get interactive terminal access ([psql](https://www.postgresql.org/docs/11/app-psql.html)) to the PostgreSQL server. + +If you are using an [external Postgres server](configuring-playbook-external-postgres.md), the above tool will not be available. + +By default, this tool puts you in the `matrix` database, which contains nothing. + +To see the available databases, run `\list` (or just `\l`). + +To change to another database (for example `synapse`), run `\connect synapse` (or just `\c synapse`). + +You can then proceed to write queries. Example: `SELECT COUNT(*) FROM users;` + +**Be careful**. Modifying the database directly (especially as services are running) is dangerous and may lead to irreversible database corruption. +When in doubt, consider [making a backup](#backing-up-postgresql). + + +## Vacuuming PostgreSQL + +Deleting lots data from Postgres does not make it release disk space, until you perform a `VACUUM` operation. + +To perform a `FULL` Postgres [VACUUM](https://www.postgresql.org/docs/current/sql-vacuum.html), run the playbook with `--tags=run-postgres-vacuum`. + +Example: + +```bash +ansible-playbook -i inventory/hosts setup.yml --tags=run-postgres-vacuum,start +``` + +**Note**: this will automatically stop Synapse temporarily and restart it later. You'll also need plenty of available disk space in your Postgres data directory (usually `/matrix/postgres/data`). + + +## Backing up PostgreSQL + +To automatically make Postgres database backups on a fixed schedule, see [Setting up postgres backup](configuring-playbook-postgres-backup.md). + +To make a one off back up of the current PostgreSQL database, make sure it's running and then execute a command like this on the server: + +```bash +/usr/bin/docker exec \ +--env-file=/matrix/postgres/env-postgres-psql \ +matrix-postgres \ +/usr/local/bin/pg_dumpall -h matrix-postgres \ +| gzip -c \ +> /matrix/postgres.sql.gz +``` + +If you are using an [external Postgres server](configuring-playbook-external-postgres.md), the above command will not work, because neither the credentials file (`/matrix/postgres/env-postgres-psql`), nor the `matrix-postgres` container is available. + +Restoring a backup made this way can be done by [importing it](importing-postgres.md). + + +## Upgrading PostgreSQL + +Unless you are using an [external Postgres server](configuring-playbook-external-postgres.md), this playbook initially installs Postgres for you. + +Once installed, the playbook attempts to preserve the Postgres version it starts with. +This is because newer Postgres versions cannot start with data generated by older Postgres versions. + +Upgrades must be performed manually. + +This playbook can upgrade your existing Postgres setup with the following command: + + ansible-playbook -i inventory/hosts setup.yml --tags=upgrade-postgres + +**Warning: If you're using Borg Backup keep in mind that there is no official Postgres 15 support yet.** + +**The old Postgres data directory is backed up** automatically, by renaming it to `/matrix/postgres/data-auto-upgrade-backup`. +To rename to a different path, pass some extra flags to the command above, like this: `--extra-vars="postgres_auto_upgrade_backup_data_path=/another/disk/matrix-postgres-before-upgrade"` + +The auto-upgrade-backup directory stays around forever, until you **manually decide to delete it**. + +As part of the upgrade, the database is dumped to `/tmp`, an upgraded and empty Postgres server is started, and then the dump is restored into the new server. +To use a different directory for the dump, pass some extra flags to the command above, like this: `--extra-vars="postgres_dump_dir=/directory/to/dump/here"` + +To save disk space in `/tmp`, the dump file is gzipped on the fly at the expense of CPU usage. +If you have plenty of space in `/tmp` and would rather avoid gzipping, you can explicitly pass a dump filename which doesn't end in `.gz`. +Example: `--extra-vars="postgres_dump_name=matrix-postgres-dump.sql"` + +**All databases, roles, etc. on the Postgres server are migrated**. + + +## Tuning PostgreSQL + +PostgreSQL can be tuned to make it run faster. This is done by passing extra arguments to Postgres with the `devture_postgres_process_extra_arguments` variable. You should use a website like https://pgtune.leopard.in.ua/ or information from https://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server to determine what Postgres settings you should change. + +**Note**: the configuration generator at https://pgtune.leopard.in.ua/ adds spaces around the `=` sign, which is invalid. You'll need to remove it manually (`max_connections = 300` -> `max_connections=300`) + +### Here are some examples: + +These are not recommended values and they may not work well for you. This is just to give you an idea of some of the options that can be set. If you are an experienced PostgreSQL admin feel free to update this documentation with better examples. + +Here is an example config for a small 2 core server with 4GB of RAM and SSD storage: +``` +devture_postgres_process_extra_arguments: [ + "-c shared_buffers=128MB", + "-c effective_cache_size=2304MB", + "-c effective_io_concurrency=100", + "-c random_page_cost=2.0", + "-c min_wal_size=500MB", +] +``` + +Here is an example config for a 4 core server with 8GB of RAM on a Virtual Private Server (VPS); the paramters have been configured using https://pgtune.leopard.in.ua with the following setup: PostgreSQL version 12, OS Type: Linux, DB Type: Mixed type of application, Data Storage: SSD storage: +``` +devture_postgres_process_extra_arguments: [ + "-c max_connections=100", + "-c shared_buffers=2GB", + "-c effective_cache_size=6GB", + "-c maintenance_work_mem=512MB", + "-c checkpoint_completion_target=0.9", + "-c wal_buffers=16MB", + "-c default_statistics_target=100", + "-c random_page_cost=1.1", + "-c effective_io_concurrency=200", + "-c work_mem=5242kB", + "-c min_wal_size=1GB", + "-c max_wal_size=4GB", + "-c max_worker_processes=4", + "-c max_parallel_workers_per_gather=2", + "-c max_parallel_workers=4", + "-c max_parallel_maintenance_workers=2", +] +``` + +Here is an example config for a large 6 core server with 24GB of RAM: +``` +devture_postgres_process_extra_arguments: [ + "-c max_connections=40", + "-c shared_buffers=1536MB", + "-c checkpoint_completion_target=0.7", + "-c wal_buffers=16MB", + "-c default_statistics_target=100", + "-c random_page_cost=1.1", + "-c effective_io_concurrency=100", + "-c work_mem=2621kB", + "-c min_wal_size=1GB", + "-c max_wal_size=4GB", + "-c max_worker_processes=6", + "-c max_parallel_workers_per_gather=3", + "-c max_parallel_workers=6", + "-c max_parallel_maintenance_workers=3", +] +``` diff --git a/docs/maintenance-upgrading-services.md b/docs/maintenance-upgrading-services.md new file mode 100644 index 0000000..d1c707f --- /dev/null +++ b/docs/maintenance-upgrading-services.md @@ -0,0 +1,17 @@ +# Upgrading the Matrix services + +This playbook not only installs the various Matrix services for you, but can also upgrade them as new versions are made available. + +If you want to be notified when new versions of Synapse are released, you should join the Synapse Homeowners room: [#homeowners:matrix.org](https://matrix.to/#/#homeowners:matrix.org). + +To upgrade services: + +- update your playbook directory (`git pull`), so you'd obtain everything new we've done + +- take a look at [the changelog](../CHANGELOG.md) to see if there have been any backward-incompatible changes that you need to take care of + +- download the upstream Ansible roles used by the playbook by running `make roles` + +- re-run the [playbook setup](installing.md) and restart all serivces: `ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,ensure-matrix-users-created,start` + +**Note**: major version upgrades to the internal PostgreSQL database are not done automatically. To upgrade it, refer to the [upgrading PostgreSQL guide](maintenance-postgres.md#upgrading-postgresql). diff --git a/docs/obtaining-access-tokens.md b/docs/obtaining-access-tokens.md new file mode 100644 index 0000000..7db2ef1 --- /dev/null +++ b/docs/obtaining-access-tokens.md @@ -0,0 +1,49 @@ +# Obtaining an Access Token + +When setting up some optional features like bots and bridges you will need to provide an access token for some user. This document provides documentation on how to obtain such an access token. + +**Access tokens are sensitive information. Do not include them in any bug reports, messages, or logs. Do not share the access token with anyone.** + +## Prerequisites + +The user for whom you want to obtain an access token needs to already exist. You can use this playbook to [register a new user](registering-users.md), if you have not already. + +Below, we describe 2 ways to generate an access token for a user - using [Element](#obtain-an-access-token-via-element) or [curl](#obtain-an-access-token-via-curl). For both ways you need the user's password. + +## Obtain an access token via Element + +1. In a private browsing session (incognito window), open Element. +1. Log in with the user's credentials. +1. In the settings page, choose "Help & About", scroll down to the bottom and expand the `Access Token` section (see screenshot below). +1. Copy the access token to your configuration. +1. Close the private browsing session. **Do not log out**. Logging out will invalidate the token, making it not work. + +![Obtaining an access token with Element](assets/obtain_admin_access_token_element.png) + + +## Obtain an access token via curl + +You can use the following command to get an access token for your user directly from the [Matrix Client-Server API](https://www.matrix.org/docs/guides/client-server-api#login): + +``` +curl -XPOST -d '{ + "identifier": { "type": "m.id.user", "user": "USERNAME" }, + "password": "PASSWORD", + "type": "m.login.password", + "device_id": "YOURDEVICEID" +}' 'https://matrix.YOURDOMAIN/_matrix/client/r0/login' +``` +Change `USERNAME`, `PASSWORD`, and `YOURDOMAIN` accordingly. + +`YOURDEVICEID` is optional and can be used to more easily identify the session later. When omitted (mind the commas in the JSON payload if you'll be omitting it), a random device ID will be generated. + +Your response will look like this (prettified): + +``` +{ + "user_id":"@USERNAME:YOURDOMAIN", + "access_token":">>>YOUR_ACCESS_TOKEN_IS_HERE<<<", + "home_server":"YOURDOMAIN", + "device_id":"YOURDEVICEID" +} +``` diff --git a/docs/prerequisites.md b/docs/prerequisites.md new file mode 100644 index 0000000..c0a9064 --- /dev/null +++ b/docs/prerequisites.md @@ -0,0 +1,43 @@ +# Prerequisites + +To install Matrix services using this Ansible playbook, you need: + +- (Recommended) An **x86** server ([What kind of server specs do I need?](faq.md#what-kind-of-server-specs-do-i-need)) running one of these operating systems: + - **CentOS** (7 only for now; [8 is not yet supported](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/300)) + - **Debian** (10/Buster or newer) + - **Ubuntu** (18.04 or newer, although [20.04 may be problematic](ansible.md#supported-ansible-versions)) + - **Archlinux** + +Generally, newer is better. We only strive to support released stable versions of distributions, not betas or pre-releases. This playbook can take over your whole server or co-exist with other services that you have there. + +This playbook somewhat supports running on non-`amd64` architectures like ARM. See [Alternative Architectures](alternative-architectures.md). + +If your distro runs within an [LXC container](https://linuxcontainers.org/), you may hit [this issue](https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/703). It can be worked around, if absolutely necessary, but we suggest that you avoid running from within an LXC container. + +- `root` access to your server (or a user capable of elevating to `root` via `sudo`). + +- [Python](https://www.python.org/) being installed on the server. Most distributions install Python by default, but some don't (e.g. Ubuntu 18.04) and require manual installation (something like `apt-get install python3`). On some distros, Ansible may incorrectly [detect the Python version](https://docs.ansible.com/ansible/latest/reference_appendices/interpreter_discovery.html) (2 vs 3) and you may need to explicitly specify the interpreter path in `inventory/hosts` during installation (e.g. `ansible_python_interpreter=/usr/bin/python3`) + +- The [Ansible](http://ansible.com/) program being installed on your own computer. It's used to run this playbook and configures your server for you. Take a look at [our guide about Ansible](ansible.md) for more information, as well as [version requirements](ansible.md#supported-ansible-versions) and alternative ways to run Ansible. + +- [`git`](https://git-scm.com/) is the recommended way to download the playbook to your computer. `git` may also be required on the server if you will be [self-building](self-building.md) components. + +- [`make`](https://www.gnu.org/software/make/) for running `make roles`, etc. (see [`Makefile`](../Makefile)), although you can also run these commands manually (without `make`) + +- An HTTPS-capable web server at the base domain name (``) which is capable of serving static files. Unless you decide to [Serve the base domain from the Matrix server](configuring-playbook-base-domain-serving.md) or alternatively, to use DNS SRV records for [Server Delegation](howto-server-delegation.md). + +- Properly configured DNS records for `` (details in [Configuring DNS](configuring-dns.md)). + +- Some TCP/UDP ports open. This playbook (actually [Docker itself](https://docs.docker.com/network/iptables/)) configures the server's internal firewall for you. In most cases, you don't need to do anything special. But **if your server is running behind another firewall**, you'd need to open these ports: + + - `80/tcp`: HTTP webserver + - `443/tcp`: HTTPS webserver + - `3478/tcp`: TURN over TCP (used by Coturn) + - `3478/udp`: TURN over UDP (used by Coturn) + - `5349/tcp`: TURN over TCP (used by Coturn) + - `5349/udp`: TURN over UDP (used by Coturn) + - `8448/tcp`: Matrix Federation API HTTPS webserver. In some cases, this **may necessary even with federation disabled**. Integration Servers (like Dimension) and Identity Servers (like ma1sd) may need to access `openid` APIs on the federation port. + - the range `49152-49172/udp`: TURN over UDP + - potentially some other ports, depending on the additional (non-default) services that you enable in the **configuring the playbook** step (later on). Consult each service's documentation page in `docs/` for that. + +When ready to proceed, continue with [Configuring DNS](configuring-dns.md). diff --git a/docs/registering-users.md b/docs/registering-users.md new file mode 100644 index 0000000..321346b --- /dev/null +++ b/docs/registering-users.md @@ -0,0 +1,81 @@ +# Registering users + +This documentation page tells you how to create user account on your Matrix server. + +Table of contents: + +- [Registering users](#registering-users) + - [Registering users manually](#registering-users-manually) + - [Managing users via a Web UI](#managing-users-via-a-web-ui) + - [Letting certain users register on your private server](#letting-certain-users-register-on-your-private-server) + - [Enabling public user registration](#enabling-public-user-registration) + - [Adding/Removing Administrator privileges to an existing Synapse user](#addingremoving-administrator-privileges-to-an-existing-synapse-user) + + +## Registering users manually + +You can do it via this Ansible playbook (make sure to edit the `` and `` part below): + +``` +ansible-playbook -i inventory/hosts setup.yml --extra-vars='username= password= admin=' --tags=register-user +``` + +**or** using the command-line after **SSH**-ing to your server (requires that [all services have been started](#starting-the-services)): + +``` +/matrix/synapse/bin/register-user +``` + +**Note**: `` is just a plain username (like `john`), not your full `@:` identifier. + +**You can then log in with that user** via the Element service that this playbook has created for you at a URL like this: `https://element./`. + +----- + +If you've just installed Matrix, **to finalize the installation process**, it's best if you proceed to [Configuring service discovery via .well-known](configuring-well-known.md) + + +## Managing users via a Web UI + +To manage users more easily (via a web user-interace), you can install [Synapse Admin](configuring-playbook-synapse-admin.md). + + +## Letting certain users register on your private server + +If you'd rather **keep your server private** (public registration closed, as is the default), and **let certain people create accounts by themselves** (instead of creating user accounts manually like this), consider installing and making use of [matrix-registration](configuring-playbook-matrix-registration.md). + + +## Enabling public user registration + +To **open up user registration publicly** (usually **not recommended**), consider using the following configuration: + +```yaml +matrix_synapse_enable_registration: true +``` + +and running the [installation](installing.md) procedure once again. + +If you're opening up registrations publicly like this, you might also wish to [configure CAPTCHA protection](configuring-captcha.md). + + +## Adding/Removing Administrator privileges to an existing Synapse user + +To change the admin privileges for a user, you need to run an SQL query like this against the `synapse` database: + +```sql +UPDATE users SET admin=ADMIN_VALUE WHERE name = '@USER:DOMAIN' +``` + +where: + +- `ADMIN_VALUE` being either `0` (regular user) or `1` (admin) +- `USER` and `DOMAIN` pointing to a valid user on your server + +If you're using the integrated Postgres server and not an [external Postgres server](configuring-playbook-external-postgres.md), you can launch a Postgres into the `synapse` database by: + +- running `/matrix/postgres/bin/cli` - to launch [`psql`](https://www.postgresql.org/docs/current/app-psql.html) +- running `\c synapse` - to change to the `synapse` database + +You can then proceed to run the query above. + +**Note**: directly modifying the raw data of Synapse (or any other software) could cause the software to break. You've been warned! diff --git a/docs/self-building.md b/docs/self-building.md new file mode 100644 index 0000000..ad29fc2 --- /dev/null +++ b/docs/self-building.md @@ -0,0 +1,45 @@ +# Self-building + +**Caution: self-building does not have to be used on its own. See the [Alternative Architectures](alternative-architectures.md) page.** + +The playbook supports self-building of various components, which don't have a container image for your architecture (see the [container images we use](container-images.md)). For `amd64`, self-building is not required. + +For other architectures (e.g. `arm32`, `arm64`), ready-made container images are used when available. If there's no ready-made image for a specific component and said component supports self-building, an image will be built on the host. Building images like this takes more time and resources (some build tools need to get installed by the playbook to assist building). + +To make use of self-building, you don't need to do anything. If a component has an image for the specified architecture, the playbook will use it directly. If not, it will build the image on the server itself. + +Note that **not all components support self-building yet**. + +Possibly outdated list of roles where self-building the Docker image is currently possible: +- `matrix-synapse` +- `matrix-synapse-admin` +- `matrix-client-element` +- `matrix-client-hydrogen` +- `matrix-client-cinny` +- `matrix-registration` +- `matrix-coturn` +- `matrix-corporal` +- `matrix-dimension` +- `matrix-ma1sd` +- `matrix-mailer` +- `matrix-bridge-hookshot` +- `matrix-bridge-appservice-irc` +- `matrix-bridge-appservice-slack` +- `matrix-bridge-appservice-webhooks` +- `matrix-bridge-beeper-linkedin` +- `matrix-bridge-mautrix-facebook` +- `matrix-bridge-mautrix-hangouts` +- `matrix-bridge-mautrix-googlechat` +- `matrix-bridge-mautrix-telegram` +- `matrix-bridge-mautrix-signal` +- `matrix-bridge-mautrix-whatsapp` +- `matrix-bridge-mx-puppet-steam` +- `matrix-bot-mjolnir` +- `matrix-bot-honoroit` +- `matrix-bot-matrix-reminder-bot` +- `matrix-bot-maubot` +- `matrix-email2matrix` + +Adding self-building support to other roles is welcome. Feel free to contribute! + +If you'd like **to force self-building** even if an image is available for your architecture, look into the `matrix_*_self_build` variables provided by individual roles. diff --git a/docs/uninstalling.md b/docs/uninstalling.md new file mode 100644 index 0000000..73a414e --- /dev/null +++ b/docs/uninstalling.md @@ -0,0 +1,36 @@ +# Uninstalling + +**Warnings**: + +- If your server federates with others, make sure to **leave any federated rooms before nuking your Matrix server's data**. Otherwise, the next time you set up a Matrix server for this domain (regardless of the installation method you use), you'll encounter trouble federating. + +- If you have some trouble with your installation, you can just [re-run the playbook](installing.md) and it will try to set things up again. **Uninstalling and then installing anew rarely solves anything**. + + +----------------- + + +## Uninstalling using a script + +Installing places a `/matrix/bin/remove-all` script on the server. + +You can run it to to have it uninstall things for you automatically (see below). **Use with caution!** + + +## Uninstalling manually + +If you prefer to uninstall manually, run these commands (most are meant to be executed on the Matrix server itself): + +- ensure all Matrix services are stopped: `ansible-playbook -i inventory/hosts setup.yml --tags=stop` (if you can't get Ansible working to run this command, you can run `systemctl stop 'matrix*'` manually on the server) + +- delete the Matrix-related systemd `.service` and `.timer` files (`rm -f /etc/systemd/system/matrix*.{service,timer}`) and reload systemd (`systemctl daemon-reload`) + +- delete some cached Docker images (`docker system prune -a`) or just delete them all (`docker rmi $(docker images -aq)`) + +- delete the Docker networks: `docker network rm matrix matrix-coturn` (might have been deleted already if you ran the `docker system prune` command) + +- uninstall Docker itself, if necessary + +- delete the `/matrix` directory (`rm -rf /matrix`) + + diff --git a/docs/updating-users-passwords.md b/docs/updating-users-passwords.md new file mode 100644 index 0000000..98663c6 --- /dev/null +++ b/docs/updating-users-passwords.md @@ -0,0 +1,45 @@ +# Updating users passwords + +## Option 1 (if you are using the integrated Postgres database): + +You can reset a user's password via the Ansible playbook (make sure to edit the `` and `` part below): + +``` +ansible-playbook -i inventory/hosts setup.yml --extra-vars='username= password=' --tags=update-user-password +``` + +**Note**: `` is just a plain username (like `john`), not your full `@:` identifier. + +**You can then log in with that user** via the Element service that this playbook has created for you at a URL like this: `https://element./`. + + +## Option 2 (if you are using an external Postgres server): + +You can manually generate the password hash by using the command-line after **SSH**-ing to your server (requires that [all services have been started](installing.md#starting-the-services)): + +``` +docker exec -it matrix-synapse /usr/local/bin/hash_password -c /data/homeserver.yaml +``` + +and then connecting to the postgres server and executing: + +``` +UPDATE users SET password_hash = '' WHERE name = '@someone:server.com' +``` + +where `` is the hash returned by the docker command above. + + +## Option 3: + +Use the Synapse User Admin API as described here: https://github.com/matrix-org/synapse/blob/master/docs/admin_api/user_admin_api.rst#reset-password + +This requires an [access token](obtaining-access-tokens.md) from a server admin account. *This method will also log the user out of all of their clients while the other options do not.* + +If you didn't make your account a server admin when you created it, you can learn how to switch it now by reading about it in [Adding/Removing Administrator privileges to an existing Synapse user](registering-users.md#addingremoving-administrator-privileges-to-an-existing-synapse-user). + +### Example: +To set @user:domain.com's password to `correct_horse_battery_staple` you could use this curl command: +``` +curl -XPOST -d '{ "new_password": "correct_horse_battery_staple" }' "https://matrix./_matrix/client/r0/admin/reset_password/@user:domain.com?access_token=MDA...this_is_my_access_token +``` diff --git a/examples/all b/examples/all new file mode 100644 index 0000000..d83d046 --- /dev/null +++ b/examples/all @@ -0,0 +1,108 @@ +--- + +######################################################################## +# # +# Playbook # +# # +######################################################################## + +# Controls whether to install Docker or not +# Also see `devture_docker_sdk_for_python_installation_enabled`. +matrix_playbook_docker_installation_enabled: true + + +matrix_domain: YOUR_BARE_DOMAIN_NAME_HERE + + + + +######################################################################## +# # +# Default # +# # +######################################################################## + +#borg_add +matrix_user_username: "matrix" +matrix_user_groupname: "matrix" + +# By default, the playbook creates the user (`matrix_user_username`) +# and group (`matrix_user_groupname`) with a random id. +# To use a specific user/group id, override these variables. +matrix_user_uid: ~ +matrix_user_gid: ~ +matrix_base_data_path: "/matrix" +matrix_base_data_path_mode: "750" + +run_setup: true + +###################################################################### +# +# SSL_configuration +# +###################################################################### + +matrix_ssl_retrieval_method: manually-managed + +###################################################################### +# +# docker_custom +# +###################################################################### + +# if you use internet through IPv6 only, please use this registery : registry.ipv6.docker.com +container_registry_mirror: +container_registry_debug: + +###################################################################### +# +# Keycloak +# +###################################################################### + +keycloak_enabled: true + + +keycloak_service_name: "keycloak" + +keycloak_admin_password: + +fqn_keycloak: "{{ keycloak_service_name }}.{{ matrix_domain }}" + +keycloak_realm_name : +keycloak_client_id: +vault_synapse_keycloak: +matrix_wildcard_cerifiate_enabled: true + + +###################################################################### +# +# Gitlab +# +###################################################################### + +gitlab_enabled: false + +drbd_enabled: false + +gitlab_service_name: "gitlab" + + +fqn_gitlab: "{{ gitlab_service_name }}.{{ matrix_domain }}" + +gitlab_http_service_port: "80" + + +hacluster_password: + +nfs_directory: /mnt/gitlab_data/ + +nginx_custom_file_path: /etc/nginx/conf.d/nginx_custom.conf + +###################################################################### +# +# backup_borg +# +###################################################################### + +matrix_backup_borg_enabled: true \ No newline at end of file diff --git a/examples/apache/README.md b/examples/apache/README.md new file mode 100644 index 0000000..92d7d93 --- /dev/null +++ b/examples/apache/README.md @@ -0,0 +1,17 @@ +# Apache reverse-proxy + +This directory contains sample files that show you how to do reverse-proxying using Apache. + +This is for when you wish to have your own Apache webserver sitting in front of Matrix services installed by this playbook. +See the [Using your own webserver, instead of this playbook's nginx proxy](../../docs/configuring-playbook-own-webserver.md) documentation page. + +To use your own Apache reverse-proxy, you first need to disable the integrated nginx server. +You do that with the following custom configuration (`inventory/host_vars/matrix./vars.yml`): + +```yaml +matrix_nginx_proxy_enabled: false +``` + +You can then use the configuration files from this directory as an example for how to configure your Apache server. + +**NOTE**: this is just an example and may not be entirely accurate. It may also not cover other use cases (enabling various services or bridges requires additional reverse-proxying configuration). diff --git a/examples/apache/matrix-client-element.conf b/examples/apache/matrix-client-element.conf new file mode 100644 index 0000000..f2b347f --- /dev/null +++ b/examples/apache/matrix-client-element.conf @@ -0,0 +1,41 @@ +# This is a sample file demonstrating how to set up reverse-proxy for element.DOMAIN. +# If you're not using Element (`matrix_client_element_enabled: false`), you won't need this. + + + ServerName element.DOMAIN + + ProxyVia On + + # Map /.well-known/acme-challenge to the certbot server + # If you manage SSL certificates by yourself, this will differ. + + ProxyPreserveHost On + ProxyPass http://127.0.0.1:2402/.well-known/acme-challenge + + + Redirect permanent / https://element.DOMAIN/ + + + + ServerName element.DOMAIN + + SSLEngine On + + # If you manage SSL certificates by yourself, these paths will differ. + SSLCertificateFile /matrix/ssl/config/live/element.DOMAIN/fullchain.pem + SSLCertificateKeyFile /matrix/ssl/config/live/element.DOMAIN/privkey.pem + + SSLProxyEngine on + SSLProxyProtocol +TLSv1.2 +TLSv1.3 + SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH + + ProxyPreserveHost On + ProxyRequests Off + ProxyVia On + + ProxyPass / http://127.0.0.1:8765/ + ProxyPassReverse / http://127.0.0.1:8765/ + + ErrorLog ${APACHE_LOG_DIR}/element.DOMAIN-error.log + CustomLog ${APACHE_LOG_DIR}/element.DOMAIN-access.log combined + diff --git a/examples/apache/matrix-dimension.conf b/examples/apache/matrix-dimension.conf new file mode 100644 index 0000000..f334690 --- /dev/null +++ b/examples/apache/matrix-dimension.conf @@ -0,0 +1,41 @@ +# This is a sample file demonstrating how to set up reverse-proxy for dimension.DOMAIN. +# If you're not using Dimension (`matrix_dimension_enabled: false`, which is also the default), you won't need this. + + + ServerName dimension.DOMAIN + + ProxyVia On + + # Map /.well-known/acme-challenge to the certbot server + # If you manage SSL certificates by yourself, this will differ. + + ProxyPreserveHost On + ProxyPass http://127.0.0.1:2402/.well-known/acme-challenge + + + Redirect permanent / https://dimension.DOMAIN/ + + + + ServerName dimension.DOMAIN + + SSLEngine On + + # If you manage SSL certificates by yourself, these paths will differ. + SSLCertificateFile /matrix/ssl/config/live/dimension.DOMAIN/fullchain.pem + SSLCertificateKeyFile /matrix/ssl/config/live/dimension.DOMAIN/privkey.pem + + SSLProxyEngine on + SSLProxyProtocol +TLSv1.2 +TLSv1.3 + SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH + + ProxyPreserveHost On + ProxyRequests Off + ProxyVia On + + ProxyPass / http://127.0.0.1:8184/ + ProxyPassReverse / http://127.0.0.1:8184/ + + ErrorLog ${APACHE_LOG_DIR}/dimension.DOMAIN-error.log + CustomLog ${APACHE_LOG_DIR}/dimension.DOMAIN-access.log combined + diff --git a/examples/apache/matrix-synapse.conf b/examples/apache/matrix-synapse.conf new file mode 100644 index 0000000..2c7b3dd --- /dev/null +++ b/examples/apache/matrix-synapse.conf @@ -0,0 +1,134 @@ +# This is a sample file demonstrating how to set up reverse-proxy for matrix.DOMAIN + + + ServerName matrix.DOMAIN + + ProxyVia On + + # Map /.well-known/acme-challenge to the certbot server + # If you manage SSL certificates by yourself, this will differ. + + ProxyPreserveHost On + ProxyPass http://127.0.0.1:2402/.well-known/acme-challenge + + + Redirect permanent / https://matrix.DOMAIN/ + + +# Client-Server API + + ServerName matrix.DOMAIN + + SSLEngine On + + # If you manage SSL certificates by yourself, these paths will differ. + SSLCertificateFile /matrix/ssl/config/live/matrix.DOMAIN/fullchain.pem + SSLCertificateKeyFile /matrix/ssl/config/live/matrix.DOMAIN/privkey.pem + + SSLProxyEngine on + SSLProxyProtocol +TLSv1.2 +TLSv1.3 + SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH + + ProxyPreserveHost On + ProxyRequests Off + ProxyVia On + RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME} + + # Keep some URIs free for different proxy/location + ProxyPassMatch ^/.well-known/matrix/client ! + ProxyPassMatch ^/.well-known/matrix/server ! + ProxyPassMatch ^/_matrix/identity ! + ProxyPassMatch ^/_matrix/client/r0/user_directory/search ! + + # Proxy all remaining traffic to Synapse + AllowEncodedSlashes NoDecode + ProxyPass /_matrix http://127.0.0.1:8008/_matrix retry=0 nocanon + ProxyPassReverse /_matrix http://127.0.0.1:8008/_matrix + ProxyPass /_synapse/client http://127.0.0.1:8008/_synapse/client retry=0 nocanon + ProxyPassReverse /_synapse/client http://127.0.0.1:8008/_synapse/client + + # Proxy Admin API (necessary for Synapse-Admin) + # ProxyPass /_synapse/admin http://127.0.0.1:8008/_synapse/admin retry=0 nocanon + # ProxyPassReverse /_synapse/admin http://127.0.0.1:8008/_synapse/admin + + # Proxy Synapse-Admin + # ProxyPass /synapse-admin http://127.0.0.1:8766 retry=0 nocanon + # ProxyPassReverse /synapse-admin http://127.0.0.1:8766 + + # Map /.well-known/matrix/client for client discovery + Alias /.well-known/matrix/client /matrix/static-files/.well-known/matrix/client + + Require all granted + + + Header always set Content-Type "application/json" + Header always set Access-Control-Allow-Origin "*" + + # Map /.well-known/matrix/server for server discovery + Alias /.well-known/matrix/server /matrix/static-files/.well-known/matrix/server + + Require all granted + + + Header always set Content-Type "application/json" + + + AllowOverride All + # Apache 2.4: + Require all granted + # Or for Apache 2.2: + #order allow,deny + + + # Map /_matrix/identity to the identity server + + ProxyPass http://127.0.0.1:8090/_matrix/identity nocanon + + + # Map /_matrix/client/r0/user_directory/search to the identity server + + ProxyPass http://127.0.0.1:8090/_matrix/client/r0/user_directory/search nocanon + + + ErrorLog ${APACHE_LOG_DIR}/matrix.DOMAIN-error.log + CustomLog ${APACHE_LOG_DIR}/matrix.DOMAIN-access.log combined + + +# Server-Server (federation) API +# Use this apache reverse proxy template to enable matrix server-to-server federation traffic +# Be sure that network traffic on port 8448 is possible +# +# You can check your federation config at https://federationtester.matrix.org/ +# Enter there your base DOMAIN address, NOT your matrix.DOMAIN address, ex. https://DOMAIN +# +# In this example we use all services on the same machine (127.0.0.1) but you can do this with different machines. +# If you do so be sure to reach the destinated IPADRESS and the correspondending port. Check this with netstat, nmap or your favourite tool. +Listen 8448 + + ServerName matrix.DOMAIN + + SSLEngine On + + # If you manage SSL certificates by yourself, these paths will differ. + SSLCertificateFile /matrix/ssl/config/live/matrix.DOMAIN/fullchain.pem + SSLCertificateKeyFile /matrix/ssl/config/live/matrix.DOMAIN/privkey.pem + + SSLProxyEngine on + SSLProxyProtocol +TLSv1.2 +TLSv1.3 + SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH + + ProxyPreserveHost On + ProxyRequests Off + ProxyVia On + RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME} + + # Proxy all remaining traffic to the Synapse port + # Beware: In this example the local traffic goes to the local synapse server at 127.0.0.1 + # Of course you can use another IPADRESS in case of using other synapse servers in your network + AllowEncodedSlashes NoDecode + ProxyPass /_matrix http://127.0.0.1:8048/_matrix retry=0 nocanon + ProxyPassReverse /_matrix http://127.0.0.1:8048/_matrix + + ErrorLog ${APACHE_LOG_DIR}/matrix.DOMAIN-error.log + CustomLog ${APACHE_LOG_DIR}/matrix.DOMAIN-access.log combined + diff --git a/examples/caddy/matrix-client-element b/examples/caddy/matrix-client-element new file mode 100644 index 0000000..2dc6ba3 --- /dev/null +++ b/examples/caddy/matrix-client-element @@ -0,0 +1,8 @@ +https://element.DOMAIN { + # These might differ if you are supplying your own certificates + tls /matrix/ssl/config/live/element.DOMAIN/fullchain.pem /matrix/ssl/config/live/element.DOMAIN/privkey.pem + + proxy / http://127.0.0.1:8765 { + transparent + } +} diff --git a/examples/caddy/matrix-dimension b/examples/caddy/matrix-dimension new file mode 100644 index 0000000..74d08e5 --- /dev/null +++ b/examples/caddy/matrix-dimension @@ -0,0 +1,9 @@ +https://dimension.DOMAIN { + # These might differ if you are supplying your own certificates + # If you wish to use Caddy's built-in Let's Encrypt support, you can also supply an email address here + tls /matrix/ssl/config/live/dimension.DOMAIN/fullchain.pem /matrix/ssl/config/live/dimension.DOMAIN/privkey.pem + + proxy / http://127.0.0.1:8184/ { + transparent + } +} diff --git a/examples/caddy/matrix-synapse b/examples/caddy/matrix-synapse new file mode 100644 index 0000000..46c48ab --- /dev/null +++ b/examples/caddy/matrix-synapse @@ -0,0 +1,31 @@ +https://matrix.DOMAIN { + # If you use your own certificates, your path may differ + # If you wish to use Caddy's built-in Let's Encrypt support, you can also supply an email address here + tls /matrix/ssl/config/live/matrix.DOMAIN/fullchain.pem /matrix/ssl/config/live/matrix.DOMAIN/privkey.pem + + root /matrix/static-files + + header / { + Access-Control-Allow-Origin * + Strict-Transport-Security "mag=age=31536000;" + X-Frame-Options "DENY" + X-XSS-Protection "1; mode=block" + } + + # Identity server traffic + proxy /_matrix/identity matrix-ma1sd:8090 { + transparent + } + proxy /_matrix/client/r0/user_directory/search matrix-ma1sd:8090 { + transparent + } + + # Synapse Client<>Server API + proxy /_matrix matrix-synapse-reverse-proxy-companion:8008 { + transparent + except /_matrix/identity/ /_matrix/client/r0/user_directory/search + } + proxy /_synapse/client matrix-synapse-reverse-proxy-companion:8008 { + transparent + } +} diff --git a/examples/caddy/matrix-util b/examples/caddy/matrix-util new file mode 100644 index 0000000..191f775 --- /dev/null +++ b/examples/caddy/matrix-util @@ -0,0 +1,7 @@ +:80 { + # Redirect ACME-Challenge traffic to port 2402 + proxy /.well-known/acme-challenge http://127.0.0.1:2402 + + # Redirect all other traffic to HTTPS + redir / https://{host}{uri} 301 +} diff --git a/examples/caddy2/Caddyfile b/examples/caddy2/Caddyfile new file mode 100644 index 0000000..43005ca --- /dev/null +++ b/examples/caddy2/Caddyfile @@ -0,0 +1,269 @@ +(cors) { + @cors_preflight method OPTIONS + + handle @cors_preflight { + header Access-Control-Allow-Origin "{args.0}" + header Access-Control-Allow-Methods "HEAD, GET, POST, PUT, PATCH, DELETE" + header Access-Control-Allow-Headers "Content-Type, Authorization" + header Access-Control-Max-Age "3600" + } +} + + +matrix.DOMAIN.tld { + + # creates letsencrypt certificate + # tls your@email.com + + @identity { + path /_matrix/identity/* + } + + @noidentity { + not path /_matrix/identity/* + } + + @search { + path /_matrix/client/r0/user_directory/search/* + } + + @nosearch { + not path /_matrix/client/r0/user_directory/search/* + } + + @static { + path /matrix/static-files/* + } + + @nostatic { + not path /matrix/static-files/* + } + + @wellknown { + path /.well-known/matrix/* + } + + header { + # Enable HTTP Strict Transport Security (HSTS) to force clients to always connect via HTTPS + Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" + # Enable cross-site filter (XSS) and tell browser to block detected attacks + X-XSS-Protection "1; mode=block" + # Prevent some browsers from MIME-sniffing a response away from the declared Content-Type + X-Content-Type-Options "nosniff" + # Disallow the site to be rendered within a frame (clickjacking protection) + X-Frame-Options "DENY" + # X-Robots-Tag + X-Robots-Tag "noindex, noarchive, nofollow" + } + + # Cache + header @static { + # Cache + Cache-Control "public, max-age=31536000" + defer + } + + # identity + handle @identity { + reverse_proxy localhost:8090 { + header_up X-Forwarded-Port {http.request.port} + header_up X-Forwarded-Proto {http.request.scheme} + header_up X-Forwarded-TlsProto {tls_protocol} + header_up X-Forwarded-TlsCipher {tls_cipher} + header_up X-Forwarded-HttpsProto {proto} + } + } + + # search + handle @search { + reverse_proxy localhost:8090 { + header_up X-Forwarded-Port {http.request.port} + header_up X-Forwarded-Proto {http.request.scheme} + header_up X-Forwarded-TlsProto {tls_protocol} + header_up X-Forwarded-TlsCipher {tls_cipher} + header_up X-Forwarded-HttpsProto {proto} + } + } + + handle @wellknown { + encode zstd gzip + root * /matrix/static-files + header Cache-Control max-age=14400 + header Content-Type application/json + header Access-Control-Allow-Origin * + file_server + } + + # If you have other well-knowns already handled by your base domain, you can replace the above block by this one, along with the replacement suggested in the base domain + #handle @wellknown { + # # .well-known is handled by base domain + # reverse_proxy https://DOMAIN.tld { + # header_up Host {http.reverse_proxy.upstream.hostport} + #} + + handle { + encode zstd gzip + + reverse_proxy localhost:8008 { + header_up X-Forwarded-Port {http.request.port} + header_up X-Forwarded-Proto {http.request.scheme} + header_up X-Forwarded-TlsProto {tls_protocol} + header_up X-Forwarded-TlsCipher {tls_cipher} + header_up X-Forwarded-HttpsProto {proto} + } + } +} + +matrix.DOMAIN.tld:8448 { + handle { + encode zstd gzip + + reverse_proxy 127.0.0.1:8048 { + header_up X-Forwarded-Port {http.request.port} + header_up X-Forwarded-Proto {http.request.scheme} + header_up X-Forwarded-TlsProto {tls_protocol} + header_up X-Forwarded-TlsCipher {tls_cipher} + header_up X-Forwarded-HttpsProto {proto} + } + } +} + +element.DOMAIN.tld { + + # creates letsencrypt certificate + # tls your@email.com + + import cors https://*.DOMAIN.tld + + header { + # Enable HTTP Strict Transport Security (HSTS) to force clients to always connect via HTTPS + Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" + # Enable cross-site filter (XSS) and tell browser to block detected attacks + X-XSS-Protection "1; mode=block" + # Prevent some browsers from MIME-sniffing a response away from the declared Content-Type + X-Content-Type-Options "nosniff" + # Disallow the site to be rendered within a frame (clickjacking protection) + X-Frame-Options "DENY" + # If using integrations that add frames to Element, such as Dimension and its integrations running on the same domain, it can be a good idea to limit sources allowed to be rendered + # Content-Security-Policy frame-src https://*.DOMAIN.tld + # X-Robots-Tag + X-Robots-Tag "noindex, noarchive, nofollow" + } + + handle { + encode zstd gzip + + reverse_proxy localhost:8765 { + header_up X-Forwarded-Port {http.request.port} + header_up X-Forwarded-Proto {http.request.scheme} + header_up X-Forwarded-TlsProto {tls_protocol} + header_up X-Forwarded-TlsCipher {tls_cipher} + header_up X-Forwarded-HttpsProto {proto} + } +} + +#dimension.DOMAIN.tld { +# +# # creates letsencrypt certificate +# # tls your@email.com +# +# import cors https://*.DOMAIN.tld +# +# header { +# # Enable HTTP Strict Transport Security (HSTS) to force clients to always connect via HTTPS +# Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" +# # Enable cross-site filter (XSS) and tell browser to block detected attacks +# X-XSS-Protection "1; mode=block" +# # Prevent some browsers from MIME-sniffing a response away from the declared Content-Type +# X-Content-Type-Options "nosniff" +# # Only allow same base domain to render this website in a frame; Can be removed if the client (Element for example) is hosted on another domain (clickjacking protection) +# Content-Security-Policy frame-ancestors https://*.DOMAIN.tld +# # X-Robots-Tag +# X-Robots-Tag "noindex, noarchive, nofollow" +# } +# +# handle { +# encode zstd gzip +# +# reverse_proxy localhost:8184 { +# header_up X-Forwarded-Port {http.request.port} +# header_up X-Forwarded-Proto {http.request.scheme} +# header_up X-Forwarded-TlsProto {tls_protocol} +# header_up X-Forwarded-TlsCipher {tls_cipher} +# header_up X-Forwarded-HttpsProto {proto} +# } +# } +#} + + +#jitsi.DOMAIN.tld { +# +# creates letsencrypt certificate +# tls your@email.com +# +# import cors https://*.DOMAIN.tld +# +# header { +# # Enable HTTP Strict Transport Security (HSTS) to force clients to always connect via HTTPS +# Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" +# +# # Enable cross-site filter (XSS) and tell browser to block detected attacks +# X-XSS-Protection "1; mode=block" +# +# # Prevent some browsers from MIME-sniffing a response away from the declared Content-Type +# X-Content-Type-Options "nosniff" + +# # Only allow same base domain to render this website in a frame; Can be removed if the client (Element for example) is hosted on another domain +# Content-Security-Policy frame-ancestors https://*.DOMAIN.tld +# +# # Disable some features +# Feature-Policy "accelerometer 'none';ambient-light-sensor 'none'; autoplay 'none';camera 'none';encrypted-media 'none';focus-without-user-activation 'none'; geolocation 'none';gyroscope #'none';magnetometer 'none';microphone 'none';midi 'none';payment 'none';picture-in-picture 'none'; speaker 'none';sync-xhr 'none';usb 'none';vr 'none'" +# +# # Referer +# Referrer-Policy "no-referrer" +# +# # X-Robots-Tag +# X-Robots-Tag "none" +# +# # Remove Server header +# -Server +# } +# +# handle { +# encode zstd gzip +# +# reverse_proxy 127.0.0.1:13080 { +# header_up X-Forwarded-Port {http.request.port} +# header_up X-Forwarded-Proto {http.request.scheme} +# header_up X-Forwarded-TlsProto {tls_protocol} +# header_up X-Forwarded-TlsCipher {tls_cipher} +# header_up X-Forwarded-HttpsProto {proto} +# } +# } +#} +#DOMAIN.com { +# Uncomment this if you are following "(Option 3): Setting up reverse-proxying of the well-known files from the base domain's server to the Matrix server" of https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/docs/configuring-well-known.md#option-3-setting-up-reverse-proxying-of-the-well-known-files-from-the-base-domains-server-to-the-matrix-server +# @wellknown { +# path /.well-known/matrix/* +# } +# +# handle @wellknown { +# reverse_proxy https://matrix.DOMAIN.com { +# header_up Host {http.reverse_proxy.upstream.hostport} +# } +# } +# # If you have other well-knowns already handled by your base domain, you can replace the above block by this one, along with the replacement suggested in the matrix subdomain +# # handle /.well-known/* { +# # encode zstd gzip +# # header Cache-Control max-age=14400 +# # header Content-Type application/json +# # header Access-Control-Allow-Origin * +# #} +# +# # Configration for the base domain goes here +# # handle { +# # header -Server +# # encode zstd gzip +# # reverse_proxy localhost:4020 +# # } +#} diff --git a/examples/caddy2/README.md b/examples/caddy2/README.md new file mode 100644 index 0000000..fe8d576 --- /dev/null +++ b/examples/caddy2/README.md @@ -0,0 +1,12 @@ +# Caddyfile + +This directory contains sample files that show you how to do reverse-proxying using Caddy2. + +## Config + +| Variable | Function | +| ------------------ | -------- | +| tls your@email.com | Specify an email address for your [ACME account](https://caddyserver.com/docs/caddyfile/directives/tls) (but if only one email is used for all sites, we recommend the email [global option](https://caddyserver.com/docs/caddyfile/options) instead) | +| tls | To enable [tls](https://caddyserver.com/docs/caddyfile/directives/tls) support uncomment the lines for tls | +| Dimension | To enable Dimension support uncomment the lines for Dimension and set your data | +| Jitsi | To enable Jitsi support uncomment the lines for Jitsi and set your data | diff --git a/examples/haproxy/Dockerfile b/examples/haproxy/Dockerfile new file mode 100644 index 0000000..8c7db98 --- /dev/null +++ b/examples/haproxy/Dockerfile @@ -0,0 +1,12 @@ +# Pull nginx base image +FROM nginx:latest + +# Expost port 80 +EXPOSE 80 + +# Copy custom configuration file from the current directory +COPY nginx.conf /etc/nginx/nginx.conf + +# Start up nginx server +CMD ["nginx"] + diff --git a/examples/haproxy/README.md b/examples/haproxy/README.md new file mode 100644 index 0000000..c1d20b0 --- /dev/null +++ b/examples/haproxy/README.md @@ -0,0 +1,26 @@ +# HAproxy reverse-proxy + +This directory contains sample files that show you how to do reverse-proxying using HAproxy. + +This is for when you wish to have your own HAproxy instance sitting in front of Matrix services installed by this playbook. +See the [Using your own webserver, instead of this playbook's nginx proxy](../../docs/configuring-playbook-own-webserver.md) documentation page. + +To use your own HAproxy reverse-proxy, you first need to disable the integrated Nginx server. +You do that with the following custom configuration (`inventory/host_vars/matrix./vars.yml`): + +```yaml +matrix_nginx_proxy_enabled: false +``` + +You can then use the configuration files from this directory as an example for how to configure your HAproxy reverse proxy. + +**NOTE**: this is just an example and may not be entirely accurate. It may also not cover other use cases or performance needs. + +### Configuration + +HAproxy, unlike Apache, Nginx and others, does not provide you with a webserver to serve static files (i.e., `/.well-known/` directory). For this reason, in this folder you can find an example on how to use HAproxy together with a simple Nginx container whose only task is to serve those files. + +* Build the Docker image. `docker build -t local/nginx .` +* Start the container. `docker-compose up -d`. Note that if you want to run Nginx on a different port, you will have to change the port both in the `docker-compose.yml` and in `haproxy.cfg`. +* If you don't want to use a wildcard certificate, you will need to modify the corresponding line in the HTTPS frontent and add the paths of all the specific certificates (as for the commented example in `haproxy.cfg`). +* Start HAproxy with the proposed configuration. diff --git a/examples/haproxy/docker-compose.yml b/examples/haproxy/docker-compose.yml new file mode 100644 index 0000000..b5c9aab --- /dev/null +++ b/examples/haproxy/docker-compose.yml @@ -0,0 +1,9 @@ +--- +version: '3' +services: + nginx: + image: local/nginx + ports: + - 40888:80 + volumes: + - /matrix/static-files:/var/www/:ro diff --git a/examples/haproxy/haproxy.cfg b/examples/haproxy/haproxy.cfg new file mode 100644 index 0000000..c7fbf96 --- /dev/null +++ b/examples/haproxy/haproxy.cfg @@ -0,0 +1,97 @@ +global + log /dev/log local0 + log /dev/log local1 notice + chroot /var/lib/haproxy + stats socket /run/haproxy/admin.sock mode 660 level admin + stats timeout 30s + user haproxy + group haproxy + daemon + # Default SSL material locations + ca-base /etc/ssl/certs + crt-base /etc/ssl/private + # Default ciphers to use on SSL-enabled listening sockets. + # For more information, see ciphers(1SSL). This list is from: + # https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ + ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS + ssl-default-bind-options no-sslv3 + +defaults + log global + mode http + option httplog + option dontlognull + option forwardfor + option redispatch + timeout connect 5000 + timeout client 50000 + timeout server 50000 + errorfile 400 /etc/haproxy/errors/400.http + errorfile 403 /etc/haproxy/errors/403.http + errorfile 408 /etc/haproxy/errors/408.http + errorfile 500 /etc/haproxy/errors/500.http + errorfile 502 /etc/haproxy/errors/502.http + errorfile 503 /etc/haproxy/errors/503.http + errorfile 504 /etc/haproxy/errors/504.http + +frontend https-frontend + bind *:80 + # HAproxy wants the full chain and the private key in one file. For Letsencrypt manually generated certs (e.g., wildcard certs) you can use + # cat /etc/letsencrypt/live/example.com/fullchain.pem /etc/letsencrypt/live/example.com/privkey.pem > /etc/haproxy/certs/star-example.com.pem + bind *:443 ssl crt /etc/haproxy/certs/star-example.com.pem + #bind *:443 ssl crt /etc/haproxy/certs/element.example.com.pem /etc/haproxy/certs/matrix.example.com.pem + reqadd X-Forwarded-Proto:\ https + option httplog + option http-server-close + # + # Matrix + # + # matrix.example.com + acl matrix_domain hdr_dom(host) -i matrix.example.com + acl static_files path -i -m beg /.well-known/matrix + use_backend nginx-static if static_files + # /_matrix/identity and /_matrix/client/r0/user_directory/search + acl matrix_identity path -i -m beg /_matrix/identity + acl matrix_search path -i -m beg /_matrix/client/r0/user_directory/search + # Send to :8090 + use_backend matrix-supporting if matrix_identity or matrix_search + # /_matrix and /_synapse/admin + acl matrix_path path -i -m beg /_matrix + acl synapse_admin path -i -m beg /_synapse/admin + # Send to :8008 + use_backend matrix-main if matrix_path or synapse_admin + # element.example.com + acl element_domain hdr_dom(host) -i element.example.com + # Send to 8765 + use_backend element if element_domain + # If nothing else match, just send to default matrix backend + use_backend matrix-main if matrix_domain + #default_backend matrix-main + +frontend matrix-federation + bind *:8448 ssl crt /etc/haproxy/certs/star-example.com.pem + reqadd X-Forwarded-Proto:\ https + option httplog + option http-server-close + default_backend synapse + +backend matrix-supporting + server matrix-supporting 127.0.0.1:8090 check + +backend matrix-main + server matrix-main 127.0.0.1:8008 check + +backend synapse + server synapse 127.0.0.1:8048 check + +backend nginx-static + capture request header origin len 128 + http-response add-header Access-Control-Allow-Origin * + rspadd Access-Control-Allow-Methods:\ GET,\ HEAD,\ OPTIONS,\ POST,\ PUT if { capture.req.hdr(0) -m found } + rspadd Access-Control-Allow-Credentials:\ true if { capture.req.hdr(0) -m found } + rspadd Access-Control-Allow-Headers:\ Origin,\ Accept,\ X-Requested-With,\ Content-Type,\ Access-Control-Request-Method,\ Access-Control-Request-Headers,\ Authorization if { capture.req.hdr(0) -m found } + server nginx 127.0.0.1:40888 check + +backend element + server element 127.0.0.1:8765 check + diff --git a/examples/haproxy/nginx.conf b/examples/haproxy/nginx.conf new file mode 100644 index 0000000..912e17c --- /dev/null +++ b/examples/haproxy/nginx.conf @@ -0,0 +1,15 @@ +worker_processes auto; +daemon off; + +events { + worker_connections 1024; +} + +http { + server_tokens off; + server { + listen 80; + index index.html; + root /var/www; + } +} diff --git a/examples/host.yml b/examples/host.yml new file mode 100644 index 0000000..e9ba281 --- /dev/null +++ b/examples/host.yml @@ -0,0 +1,11 @@ +--- + +# This is a host file for usage with the `ansible-all-hosts.sh` script, +# which runs Ansible against a bunch of hosts, each with its own `sudo` password. +matrix_servers: + hosts: + matrix.: + ansible_host: + ansible_ssh_user: + become: true + become_user: root diff --git a/examples/hosts b/examples/hosts new file mode 100644 index 0000000..6d4b3e9 --- /dev/null +++ b/examples/hosts @@ -0,0 +1,35 @@ +# We explicitly ask for your server's external IP address, because the same value is used for configuring Coturn. +# If you'd rather use a local IP here, make sure to set up `matrix_coturn_turn_external_ip_address`. +# +# To connect using a non-root user (and elevate to root with sudo later), +# replace `ansible_ssh_user=root` with something like this: `ansible_ssh_user=username become=true become_user=root` +# +# For improved Ansible performance, SSH pipelining is enabled by default in `ansible.cfg`. +# If this causes SSH connection troubles, disable it by adding `ansible_ssh_pipelining=False` +# to the host line below or by adding `ansible_ssh_pipelining: False` to your variables file. +# +# If you're running this Ansible playbook on the same server as the one you're installing to, +# consider adding an additional `ansible_connection=local` argument to the host line below. +# +# Ansible may fail to discover which Python interpreter to use on the host for some distros (like Ubuntu 20.04). +# You may sometimes need to explicitly add the argument `ansible_python_interpreter=/usr/bin/python3` +# to the host line below. + +[matrix_servers] +matrix. ansible_host= ansible_ssh_user=root + + +[keycloak_servers] +keycloak. ansible_host= ansible_ssh_user=ubuntu service_ip_address= + + +[gitlab_servers] +gitlab. ansible_host= ansible_ssh_user=ubuntu service_ip_address= +gitlab-2. ansible_host= ansible_ssh_user=ubuntu service_ip_address= +gitlab-3. ansible_host= ansible_ssh_user=ubuntu service_ip_address= + +[drbd_primary] +gitlab-storage-p. ansible_host= ansible_ssh_user=ubuntu drbd_ip_address= drbd_storage_path= drbd_port= + +[drbd_secondary] +gitlab-storage-s. ansible_host= ansible_ssh_user=ubuntu drbd_ip_address= drbd_storage_path= drbd_port= \ No newline at end of file diff --git a/examples/vars_keycloak.yml b/examples/vars_keycloak.yml new file mode 100644 index 0000000..498b21a --- /dev/null +++ b/examples/vars_keycloak.yml @@ -0,0 +1,37 @@ +--- + + +keycloak_keysstore_file_password: +# This is something which is provided to Let's Encrypt when retrieving SSL certificates for domains. +# +# In case SSL renewal fails at some point, you'll also get an email notification there. +# +# If you decide to use another method for managing SSL certificates (different than the default Let's Encrypt), +# you won't be required to define this variable (see `docs/configuring-playbook-ssl-certificates.md`). +# +# Example value: someone@example.com +matrix_ssl_lets_encrypt_support_email: + +# A Postgres password to use for the superuser Postgres user (called `matrix` by default). +# +# The playbook creates additional Postgres users and databases (one for each enabled service) +# using this superuser account. +postgres_connection_password: + + +keycloak_admin_password : + + + +keycloak_admin_password : + + +keycloak_postgresql_database: keycloak +keycloak_postgresql_database_hostname: 'keycloak_postgres' +keycloak_postgresql_database_username: "keycloak" +keycloak_postgresql_database_password: + + +matrix_docker_network: keycloak-network + + diff --git a/examples/vars_matrix.yml b/examples/vars_matrix.yml new file mode 100644 index 0000000..d092cac --- /dev/null +++ b/examples/vars_matrix.yml @@ -0,0 +1,38 @@ +--- +# The bare domain name which represents your Matrix identity. +# Matrix user ids for your server will be of the form (`@user:`). +# +# Note: this playbook does not touch the server referenced here. +# Installation happens on another server ("matrix."). +# +# If you've deployed using the wrong domain, you'll have to run the Uninstalling step, +# because you can't change the Domain after deployment. +# +# Example value: example.com + + +# The Matrix homeserver software to install. +# See: +# - `roles/matrix/matrix-base/defaults/main.yml` for valid options +# - the `docs/configuring-playbook-IMPLEMENTATION_NAME.md` documentation page, if one is available for your implementation choice +matrix_homeserver_implementation: synapse + +# A secret used as a base, for generating various other secrets. +# You can put any string here, but generating a strong one is preferred (e.g. `pwgen -s 64 1`). +matrix_homeserver_generic_secret_key: '' + +# This is something which is provided to Let's Encrypt when retrieving SSL certificates for domains. +# +# In case SSL renewal fails at some point, you'll also get an email notification there. +# +# If you decide to use another method for managing SSL certificates (different than the default Let's Encrypt), +# you won't be required to define this variable (see `docs/configuring-playbook-ssl-certificates.md`). +# +# Example value: someone@example.com +matrix_ssl_lets_encrypt_support_email: '' + +# A Postgres password to use for the superuser Postgres user (called `matrix` by default). +# +# The playbook creates additional Postgres users and databases (one for each enabled service) +# using this superuser account. +devture_postgres_connection_password: '' diff --git a/group_vars/matrix_servers b/group_vars/matrix_servers new file mode 100644 index 0000000..cbed860 --- /dev/null +++ b/group_vars/matrix_servers @@ -0,0 +1,3180 @@ +--- + +# This variables file wires together the various components (roles) used by the playbook. +# +# Roles used by playbook are pretty minimal and kept independent of one another as much as possible. +# To deliver a turnkey fully-featured Matrix server, this playbook needs +# to connect them all together. It does so by overriding role variables. +# +# You can also override ANY variable (seen here or in any given role), +# by re-defining it in your own configuration file (`inventory/host_vars/matrix.`). + +######################################################################## +# # +# Playbook # +# # +######################################################################## + +# Controls whether to install Docker or not +# Also see `devture_docker_sdk_for_python_installation_enabled`. +matrix_playbook_docker_installation_enabled: true + +######################################################################## +# # +# /Playbook # +# # +######################################################################## + +######################################################################## +# # +# base # +# # +######################################################################## + +matrix_homeserver_container_extra_arguments_auto: | + {{ + (['--mount type=bind,src=' + matrix_appservice_discord_config_path + '/registration.yaml,dst=/matrix-appservice-discord-registration.yaml,ro'] if matrix_appservice_discord_enabled else []) + + + (['--mount type=bind,src=' + matrix_appservice_irc_config_path + '/registration.yaml,dst=/matrix-appservice-irc-registration.yaml,ro'] if matrix_appservice_irc_enabled else []) + + + (['--mount type=bind,src=' + matrix_appservice_kakaotalk_config_path + '/registration.yaml,dst=/matrix-appservice-kakaotalk-registration.yaml,ro'] if matrix_appservice_kakaotalk_enabled else []) + + + (['--mount type=bind,src=' + matrix_appservice_slack_config_path + '/slack-registration.yaml,dst=/matrix-appservice-slack-registration.yaml,ro'] if matrix_appservice_slack_enabled else []) + + + (['--mount type=bind,src=' + matrix_appservice_webhooks_config_path + '/webhooks-registration.yaml,dst=/matrix-appservice-webhooks-registration.yaml,ro'] if matrix_appservice_webhooks_enabled else []) + + + (['--mount type=bind,src=' + matrix_beeper_linkedin_config_path + '/registration.yaml,dst=/matrix-beeper-linkedin-registration.yaml,ro'] if matrix_beeper_linkedin_enabled else []) + + + (['--mount type=bind,src=' + matrix_go_skype_bridge_config_path + '/registration.yaml,dst=/matrix-go-skype-bridge-registration.yaml,ro'] if matrix_go_skype_bridge_enabled else []) + + + (['--mount type=bind,src=' + matrix_heisenbridge_base_path + '/registration.yaml,dst=/heisenbridge-registration.yaml,ro'] if matrix_heisenbridge_enabled else []) + + + (['--mount type=bind,src=' + matrix_hookshot_base_path + '/registration.yml,dst=/hookshot-registration.yml,ro'] if matrix_hookshot_enabled else []) + + + (['--mount type=bind,src=' + matrix_mautrix_discord_config_path + '/registration.yaml,dst=/matrix-mautrix-discord-registration.yaml,ro'] if matrix_mautrix_discord_enabled else []) + + + (['--mount type=bind,src=' + matrix_mautrix_facebook_config_path + '/registration.yaml,dst=/matrix-mautrix-facebook-registration.yaml,ro'] if matrix_mautrix_facebook_enabled else []) + + + (['--mount type=bind,src=' + matrix_mautrix_googlechat_config_path + '/registration.yaml,dst=/matrix-mautrix-googlechat-registration.yaml,ro'] if matrix_mautrix_googlechat_enabled else []) + + + (['--mount type=bind,src=' + matrix_mautrix_hangouts_config_path + '/registration.yaml,dst=/matrix-mautrix-hangouts-registration.yaml,ro'] if matrix_mautrix_hangouts_enabled else []) + + + (['--mount type=bind,src=' + matrix_mautrix_instagram_config_path + '/registration.yaml,dst=/matrix-mautrix-instagram-registration.yaml,ro'] if matrix_mautrix_instagram_enabled else []) + + + (['--mount type=bind,src=' + matrix_mautrix_signal_config_path + '/registration.yaml,dst=/matrix-mautrix-signal-registration.yaml,ro'] if matrix_mautrix_signal_enabled else []) + + + (['--mount type=bind,src=' + matrix_mautrix_telegram_config_path + '/registration.yaml,dst=/matrix-mautrix-telegram-registration.yaml,ro'] if matrix_mautrix_telegram_enabled else []) + + + (['--mount type=bind,src=' + matrix_mautrix_twitter_config_path + '/registration.yaml,dst=/matrix-mautrix-twitter-registration.yaml,ro'] if matrix_mautrix_twitter_enabled else []) + + + (['--mount type=bind,src=' + matrix_mautrix_whatsapp_config_path + '/registration.yaml,dst=/matrix-mautrix-whatsapp-registration.yaml,ro'] if matrix_mautrix_whatsapp_enabled else []) + + + (['--mount type=bind,src=' + matrix_mx_puppet_discord_config_path + '/registration.yaml,dst=/matrix-mx-puppet-discord-registration.yaml,ro'] if matrix_mx_puppet_discord_enabled else []) + + + (['--mount type=bind,src=' + matrix_mx_puppet_groupme_config_path + '/registration.yaml,dst=/matrix-mx-puppet-groupme-registration.yaml,ro'] if matrix_mx_puppet_groupme_enabled else []) + + + (['--mount type=bind,src=' + matrix_mx_puppet_instagram_config_path + '/registration.yaml,dst=/matrix-mx-puppet-instagram-registration.yaml,ro'] if matrix_mx_puppet_instagram_enabled else []) + + + (['--mount type=bind,src=' + matrix_mx_puppet_slack_config_path + '/registration.yaml,dst=/matrix-mx-puppet-slack-registration.yaml,ro'] if matrix_mx_puppet_slack_enabled else []) + + + (['--mount type=bind,src=' + matrix_mx_puppet_steam_config_path + '/registration.yaml,dst=/matrix-mx-puppet-steam-registration.yaml,ro'] if matrix_mx_puppet_steam_enabled else []) + + + (['--mount type=bind,src=' + matrix_mx_puppet_twitter_config_path + '/registration.yaml,dst=/matrix-mx-puppet-twitter-registration.yaml,ro'] if matrix_mx_puppet_twitter_enabled else []) + + + (['--mount type=bind,src=' + matrix_sms_bridge_config_path + '/registration.yaml,dst=/matrix-sms-bridge-registration.yaml,ro'] if matrix_sms_bridge_enabled else []) + + + (['--mount type=bind,src=' + matrix_cactus_comments_app_service_config_file + ',dst=/matrix-cactus-comments.yaml,ro'] if matrix_cactus_comments_enabled else []) + }} + +matrix_homeserver_app_service_config_files_auto: | + {{ + (['/matrix-appservice-discord-registration.yaml'] if matrix_appservice_discord_enabled else []) + + + (['/matrix-appservice-irc-registration.yaml'] if matrix_appservice_irc_enabled else []) + + + (['/matrix-appservice-kakaotalk-registration.yaml'] if matrix_appservice_kakaotalk_enabled else []) + + + (['/matrix-appservice-slack-registration.yaml'] if matrix_appservice_slack_enabled else []) + + + (['/matrix-appservice-webhooks-registration.yaml'] if matrix_appservice_webhooks_enabled else []) + + + (['/matrix-beeper-linkedin-registration.yaml'] if matrix_beeper_linkedin_enabled else []) + + + (['/matrix-go-skype-bridge-registration.yaml'] if matrix_go_skype_bridge_enabled else []) + + + (['/heisenbridge-registration.yaml'] if matrix_heisenbridge_enabled else []) + + + (['/hookshot-registration.yml'] if matrix_hookshot_enabled else []) + + + (['/matrix-mautrix-discord-registration.yaml'] if matrix_mautrix_discord_enabled else []) + + + (['/matrix-mautrix-facebook-registration.yaml'] if matrix_mautrix_facebook_enabled else []) + + + (['/matrix-mautrix-googlechat-registration.yaml'] if matrix_mautrix_googlechat_enabled else []) + + + (['/matrix-mautrix-hangouts-registration.yaml'] if matrix_mautrix_hangouts_enabled else []) + + + (['/matrix-mautrix-instagram-registration.yaml'] if matrix_mautrix_instagram_enabled else []) + + + (['/matrix-mautrix-signal-registration.yaml'] if matrix_mautrix_signal_enabled else []) + + + (['/matrix-mautrix-telegram-registration.yaml'] if matrix_mautrix_telegram_enabled else []) + + + (['/matrix-mautrix-twitter-registration.yaml'] if matrix_mautrix_twitter_enabled else []) + + + (['/matrix-mautrix-whatsapp-registration.yaml'] if matrix_mautrix_whatsapp_enabled else []) + + + (['/matrix-mx-puppet-discord-registration.yaml'] if matrix_mx_puppet_discord_enabled else []) + + + (['/matrix-mx-puppet-groupme-registration.yaml'] if matrix_mx_puppet_groupme_enabled else []) + + + (['/matrix-mx-puppet-instagram-registration.yaml'] if matrix_mx_puppet_instagram_enabled else []) + + + (['/matrix-mx-puppet-slack-registration.yaml'] if matrix_mx_puppet_slack_enabled else []) + + + (['/matrix-mx-puppet-steam-registration.yaml'] if matrix_mx_puppet_steam_enabled else []) + + + (['/matrix-mx-puppet-twitter-registration.yaml'] if matrix_mx_puppet_twitter_enabled else []) + + + (['/matrix-sms-bridge-registration.yaml'] if matrix_sms_bridge_enabled else []) + + + (['/matrix-cactus-comments.yaml'] if matrix_cactus_comments_enabled else []) + }} + +######################################################################## +# # +# /base # +# # +######################################################################## + + +######################################################################## +# # +# com.devture.ansible.role.systemd_service_manager # +# # +######################################################################## + +# This list is not exhaustive and final. +# Synapse workers are still injected into the list at runtime. +# Additional JVB workers (playbooks/jitsi_jvb.yml -- roles/matrix/matrix-jitsi/tasks/init_additional_jvb.yml) override this variable at runtime as well. +# +# Priority levels are like this: +# - core services (the homeserver) get a level of ~1000 +# - services that core services depend on (database, Redis, ntfy, etc.) get a lower level - between 500 and 1000 +# - reverse-proxying services get level 3000 +# - Matrix utility services (bridges, bots) get a level of 2000/2200, so that: +# - they can start before the reverse-proxy +# - so that, when the reverse-proxy is up (Matrix is up), all bots and bridges can be interacted with +# - monitoring services (Prometheus, Grafana, ..) get a level of 4000 - they can start later than all-of-Matrix +# - services which aren't time-sensitive (various crons and timers) get a level of 5000 - they can start later than all-of-Matrix +devture_systemd_service_manager_services_list_auto: | + {{ + ([{'name': 'matrix-backup-borg.timer', 'priority': 5000, 'groups': ['matrix', 'backup', 'borg']}] if matrix_backup_borg_enabled else []) + + + ([{'name': 'matrix-bot-buscarron.service', 'priority': 2200, 'groups': ['matrix', 'bots', 'buscarron']}] if matrix_bot_buscarron_enabled else []) + + + ([{'name': 'matrix-bot-go-neb.service', 'priority': 2200, 'groups': ['matrix', 'bots', 'go-neb']}] if matrix_bot_go_neb_enabled else []) + + + ([{'name': 'matrix-bot-honoroit.service', 'priority': 2200, 'groups': ['matrix', 'bots', 'honoroit']}] if matrix_bot_honoroit_enabled else []) + + + ([{'name': 'matrix-bot-matrix-registration-bot.service', 'priority': 2200, 'groups': ['matrix', 'bots', 'registration-bot']}] if matrix_bot_matrix_registration_bot_enabled else []) + + + ([{'name': 'matrix-bot-matrix-reminder-bot.service', 'priority': 2200, 'groups': ['matrix', 'bots', 'reminder-bot']}] if matrix_bot_matrix_reminder_bot_enabled else []) + + + ([{'name': 'matrix-bot-maubot.service', 'priority': 2200, 'groups': ['matrix', 'bots', 'maubot']}] if matrix_bot_maubot_enabled else []) + + + ([{'name': 'matrix-bot-mjolnir.service', 'priority': 2200, 'groups': ['matrix', 'bots', 'mjolnir']}] if matrix_bot_mjolnir_enabled else []) + + + ([{'name': 'matrix-bot-postmoogle.service', 'priority': 2200, 'groups': ['matrix', 'bots', 'postmoogle']}] if matrix_bot_postmoogle_enabled else []) + + + ([{'name': 'matrix-appservice-discord.service', 'priority': 2000, 'groups': ['matrix', 'bridges', 'appservice-discord']}] if matrix_appservice_discord_enabled else []) + + + ([{'name': 'matrix-appservice-irc.service', 'priority': 2000, 'groups': ['matrix', 'bridges', 'appservice-irc']}] if matrix_appservice_irc_enabled else []) + + + ([{'name': 'matrix-appservice-kakaotalk.service', 'priority': 2000, 'groups': ['matrix', 'bridges', 'appservice-kakaotalk']}] if matrix_appservice_kakaotalk_enabled else []) + + + ([{'name': 'matrix-appservice-kakaotalk-node.service', 'priority': 1900, 'groups': ['matrix', 'bridges', 'appservice-kakaotalk', 'appservice-kakaotalk-node']}] if matrix_appservice_kakaotalk_enabled else []) + + + ([{'name': 'matrix-appservice-slack.service', 'priority': 2000, 'groups': ['matrix', 'bridges', 'appservice-slack']}] if matrix_appservice_slack_enabled else []) + + + ([{'name': 'matrix-appservice-webhooks.service', 'priority': 2000, 'groups': ['matrix', 'bridges', 'appservice-webhooks']}] if matrix_appservice_webhooks_enabled else []) + + + ([{'name': 'matrix-beeper-linkedin.service', 'priority': 2000, 'groups': ['matrix', 'bridges', 'beeper-linkedin']}] if matrix_beeper_linkedin_enabled else []) + + + ([{'name': 'matrix-go-skype-bridge.service', 'priority': 2000, 'groups': ['matrix', 'bridges', 'go-skype']}] if matrix_go_skype_bridge_enabled else []) + + + ([{'name': 'matrix-heisenbridge.service', 'priority': 2000, 'groups': ['matrix', 'bridges', 'heisenbridge']}] if matrix_heisenbridge_enabled else []) + + + ([{'name': 'matrix-hookshot.service', 'priority': 2000, 'groups': ['matrix', 'bridges', 'hookshot']}] if matrix_hookshot_enabled else []) + + + ([{'name': 'matrix-mautrix-discord.service', 'priority': 2000, 'groups': ['matrix', 'bridges', 'mautrix-discord']}] if matrix_mautrix_discord_enabled else []) + + + ([{'name': 'matrix-mautrix-facebook.service', 'priority': 2000, 'groups': ['matrix', 'bridges', 'mautrix-facebook']}] if matrix_mautrix_facebook_enabled else []) + + + ([{'name': 'matrix-mautrix-googlechat.service', 'priority': 2000, 'groups': ['matrix', 'bridges', 'mautrix-googlechat']}] if matrix_mautrix_googlechat_enabled else []) + + + ([{'name': 'matrix-mautrix-hangouts.service', 'priority': 2000, 'groups': ['matrix', 'bridges', 'mautrix-hangouts']}] if matrix_mautrix_hangouts_enabled else []) + + + ([{'name': 'matrix-mautrix-instagram.service', 'priority': 2000, 'groups': ['matrix', 'bridges', 'mautrix-instagram']}] if matrix_mautrix_instagram_enabled else []) + + + ([{'name': 'matrix-mautrix-signal.service', 'priority': 2000, 'groups': ['matrix', 'bridges', 'mautrix-signal']}] if matrix_mautrix_signal_enabled else []) + + + ([{'name': 'matrix-mautrix-signal-daemon.service', 'priority': 1900, 'groups': ['matrix', 'bridges', 'mautrix-signal', 'mautrix-signal-daemon']}] if matrix_mautrix_signal_enabled else []) + + + ([{'name': 'matrix-mautrix-telegram.service', 'priority': 2000, 'groups': ['matrix', 'bridges', 'mautrix-telegram']}] if matrix_mautrix_telegram_enabled else []) + + + ([{'name': 'matrix-mautrix-twitter.service', 'priority': 2000, 'groups': ['matrix', 'bridges', 'mautrix-twitter']}] if matrix_mautrix_twitter_enabled else []) + + + ([{'name': 'matrix-mautrix-whatsapp.service', 'priority': 2000, 'groups': ['matrix', 'bridges', 'mautrix-whatsapp']}] if matrix_mautrix_whatsapp_enabled else []) + + + ([{'name': 'matrix-mx-puppet-discord.service', 'priority': 2000, 'groups': ['matrix', 'bridges', 'mx-puppet-discord']}] if matrix_mx_puppet_discord_enabled else []) + + + ([{'name': 'matrix-mx-puppet-groupme.service', 'priority': 2000, 'groups': ['matrix', 'bridges', 'mx-puppet-groupme']}] if matrix_mx_puppet_groupme_enabled else []) + + + ([{'name': 'matrix-mx-puppet-instagram.service', 'priority': 2000, 'groups': ['matrix', 'bridges', 'mx-puppet-instagram']}] if matrix_mx_puppet_instagram_enabled else []) + + + ([{'name': 'matrix-mx-puppet-slack.service', 'priority': 2000, 'groups': ['matrix', 'bridges', 'mx-puppet-slack']}] if matrix_mx_puppet_slack_enabled else []) + + + ([{'name': 'matrix-mx-puppet-steam.service', 'priority': 2000, 'groups': ['matrix', 'bridges', 'mx-puppet-steam']}] if matrix_mx_puppet_steam_enabled else []) + + + ([{'name': 'matrix-mx-puppet-twitter.service', 'priority': 2000, 'groups': ['matrix', 'bridges', 'mx-puppet-twitter']}] if matrix_mx_puppet_twitter_enabled else []) + + + ([{'name': 'matrix-sms-bridge.service', 'priority': 2000, 'groups': ['matrix', 'bridges', 'sms']}] if matrix_sms_bridge_enabled else []) + + + ([{'name': 'matrix-cactus-comments.service', 'priority': 2000, 'groups': ['matrix', 'cactus-comments']}] if matrix_cactus_comments_enabled else []) + + + ([{'name': 'matrix-client-cinny.service', 'priority': 2000, 'groups': ['matrix', 'clients', 'cinny']}] if matrix_client_cinny_enabled else []) + + + ([{'name': 'matrix-client-element.service', 'priority': 2000, 'groups': ['matrix', 'clients', 'element']}] if matrix_client_element_enabled else []) + + + ([{'name': 'matrix-client-hydrogen.service', 'priority': 2000, 'groups': ['matrix', 'clients', 'hydrogen']}] if matrix_client_hydrogen_enabled else []) + + + ([{'name': ('matrix-' + matrix_homeserver_implementation + '.service'), 'priority': 1000, 'groups': ['matrix', 'homeservers', matrix_homeserver_implementation]}] if matrix_homeserver_enabled else []) + + + ([{'name': 'matrix-corporal.service', 'priority': 1500, 'groups': ['matrix', 'corporal']}] if matrix_corporal_enabled else []) + + + ([{'name': 'matrix-coturn.service', 'priority': 4000, 'groups': ['matrix', 'coturn']}] if matrix_coturn_enabled else []) + + + ([{'name': 'matrix-coturn-reload.timer', 'priority': 5000, 'groups': ['matrix', 'coturn']}] if (matrix_coturn_enabled and matrix_coturn_tls_enabled) else []) + + + ([{'name': 'matrix-dimension.service', 'priority': 2500, 'groups': ['matrix', 'integration-managers', 'dimension']}] if matrix_dimension_enabled else []) + + + ([{'name': 'matrix-dynamic-dns.service', 'priority': 5000, 'groups': ['matrix', 'dynamic-dns']}] if matrix_dynamic_dns_enabled else []) + + + ([{'name': 'matrix-email2matrix.service', 'priority': 2000, 'groups': ['matrix', 'bridges', 'email2matrix']}] if matrix_email2matrix_enabled else []) + + + ([{'name': 'matrix-etherpad.service', 'priority': 4000, 'groups': ['matrix', 'etherpad']}] if matrix_etherpad_enabled else []) + + + ([{'name': 'matrix-grafana.service', 'priority': 4000, 'groups': ['matrix', 'monitoring', 'grafana']}] if matrix_grafana_enabled else []) + + + ([{'name': 'matrix-jitsi-web.service', 'priority': 4200, 'groups': ['matrix', 'jitsi', 'jitsi-web']}] if matrix_jitsi_enabled else []) + + + ([{'name': 'matrix-jitsi-prosody.service', 'priority': 4000, 'groups': ['matrix', 'jitsi', 'jitsi-prosody']}] if matrix_jitsi_enabled else []) + + + ([{'name': 'matrix-jitsi-jicofo.service', 'priority': 4100, 'groups': ['matrix', 'jitsi', 'jitsi-jicofo']}] if matrix_jitsi_enabled else []) + + + ([{'name': 'matrix-jitsi-jvb.service', 'priority': 4100, 'groups': ['matrix', 'jitsi', 'jitsi-jvb']}] if matrix_jitsi_enabled else []) + + + ([{'name': 'matrix-ldap-registration-proxy.service', 'priority': 2000, 'groups': ['matrix', 'ldap-registration-proxy']}] if matrix_ldap_registration_proxy_enabled else []) + + + ([{'name': 'matrix-ma1sd.service', 'priority': 2000, 'groups': ['matrix', 'ma1sd']}] if matrix_ma1sd_enabled else []) + + + ([{'name': 'matrix-mailer.service', 'priority': 2000, 'groups': ['matrix', 'mailer']}] if matrix_mailer_enabled else []) + + + ([{'name': 'matrix-nginx-proxy.service', 'priority': 3000, 'groups': ['matrix', 'nginx', 'reverse-proxies']}] if matrix_nginx_proxy_enabled else []) + + + (matrix_ssl_renewal_systemd_units_list | selectattr('applicable') | selectattr('enableable')) + + + ([{'name': 'matrix-ntfy.service', 'priority': 800, 'groups': ['matrix', 'ntfy']}] if matrix_ntfy_enabled else []) + + + ([{'name': (devture_postgres_identifier + '.service'), 'priority': 500, 'groups': ['matrix', 'postgres']}] if devture_postgres_enabled else []) + + + ([{'name': (devture_postgres_backup_identifier + '.service'), 'priority': 5000, 'groups': ['matrix', 'backup', 'postgres-backup']}] if devture_postgres_backup_enabled else []) + + + ([{'name': 'matrix-prometheus.service', 'priority': 4000, 'groups': ['matrix', 'monitoring', 'prometheus', 'prometheus-core']}] if matrix_prometheus_enabled else []) + + + ([{'name': 'matrix-prometheus-node-exporter.service', 'priority': 3900, 'groups': ['matrix', 'monitoring', 'prometheus', 'prometheus-node-exporters']}] if matrix_prometheus_node_exporter_enabled else []) + + + ([{'name': 'matrix-prometheus-postgres-exporter.service', 'priority': 3900, 'groups': ['matrix', 'monitoring', 'prometheus', 'prometheus-node-exporters']}] if matrix_prometheus_postgres_exporter_enabled else []) + + + ([{'name': 'matrix-prometheus-nginxlog-exporter.service', 'priority': 3900, 'groups': ['matrix', 'monitoring', 'prometheus', 'prometheus-node-exporters']}] if matrix_prometheus_nginxlog_exporter_enabled else []) + + + ([{'name': 'matrix-redis', 'priority': 750, 'groups': ['matrix', 'redis']}] if matrix_redis_enabled else []) + + + ([{'name': 'matrix-registration.service', 'priority': 4000, 'groups': ['matrix', 'registration']}] if matrix_registration_enabled else []) + + + ([{'name': 'matrix-sygnal.service', 'priority': 800, 'groups': ['matrix', 'sygnal']}] if matrix_sygnal_enabled else []) + + + ([{'name': 'matrix-goofys.service', 'priority': 800, 'groups': ['matrix', 'goofys']}] if matrix_s3_media_store_enabled else []) + + + ([{'name': 'matrix-synapse-s3-storage-provider-migrate.timer', 'priority': 5000, 'groups': ['matrix']}] if matrix_synapse_ext_synapse_s3_storage_provider_enabled else []) + + + ([{'name': 'matrix-synapse-admin.service', 'priority': 4000, 'groups': ['matrix', 'synapse-admin']}] if matrix_synapse_admin_enabled else []) + + + ([{'name': 'matrix-synapse-reverse-proxy-companion.service', 'priority': 1500, 'groups': ['matrix', 'homeservers', 'synapse', 'reverse-proxies']}] if matrix_synapse_reverse_proxy_companion_enabled else []) + }} + +######################################################################## +# # +# /com.devture.ansible.role.systemd_service_manager # +# # +######################################################################## + + +######################################################################## +# # +# com.devture.ansible.role.timesync # +# # +######################################################################## + +# To completely disable installing systemd-timesyncd/ntpd, use `devture_timesync_installation_enabled: false`. + +######################################################################## +# # +# /com.devture.ansible.role.timesync # +# # +######################################################################## + + + +###################################################################### +# +# com.devture.ansible.role.playbook_state_preserver +# +###################################################################### + +# To completely disable this feature, use `devture_playbook_state_preserver_enabled: false`. + +devture_playbook_state_preserver_uid: "{{ matrix_user_uid }}" +devture_playbook_state_preserver_gid: "{{ matrix_user_gid }}" + +devture_playbook_state_preserver_vars_preservation_dst: "{{ matrix_base_data_path }}/vars.yml" + +devture_playbook_state_preserver_commit_hash_preservation_dst: "{{ matrix_base_data_path }}/git_hash.yml" + +###################################################################### +# +# /com.devture.ansible.role.playbook_state_preserver +# +###################################################################### + + + +###################################################################### +# +# matrix-base +# +###################################################################### + +matrix_identity_server_url: "{{ ('https://' + matrix_server_fqn_matrix) if matrix_ma1sd_enabled else None }}" + +matrix_homeserver_container_url: |- + {{ + 'http://matrix-nginx-proxy:12080' if matrix_nginx_proxy_enabled else { + 'synapse': ('http://matrix-synapse-reverse-proxy-companion:8008' if matrix_synapse_reverse_proxy_companion_enabled else 'http://matrix-synapse:'+ matrix_synapse_container_client_api_port|string), + 'dendrite': ('http://matrix-dendrite:' + matrix_dendrite_http_bind_port|string), + 'conduit': ('http://matrix-conduit:' + matrix_conduit_port_number|string), + }[matrix_homeserver_implementation] + }} + +matrix_homeserver_container_federation_url: |- + {{ + 'http://matrix-nginx-proxy:12088' if matrix_nginx_proxy_enabled else { + 'synapse': ('http://matrix-synapse-reverse-proxy-companion:8048' if matrix_synapse_reverse_proxy_companion_enabled else 'http://matrix-synapse:'+ matrix_synapse_container_federation_api_plain_port|string), + 'dendrite': ('http://matrix-dendrite:' + matrix_dendrite_http_bind_port|string), + 'conduit': ('http://matrix-conduit:' + matrix_conduit_port_number|string), + }[matrix_homeserver_implementation] + }} + +matrix_integration_manager_rest_url: "{{ matrix_dimension_integrations_rest_url if matrix_dimension_enabled else None }}" +matrix_integration_manager_ui_url: "{{ matrix_dimension_integrations_ui_url if matrix_dimension_enabled else None }}" + +###################################################################### +# +# /matrix-base +# +###################################################################### + + +###################################################################### +# +# matrix-bridge-appservice-discord +# +###################################################################### + +# We don't enable bridges by default. +matrix_appservice_discord_enabled: false + +# Normally, matrix-nginx-proxy is enabled and nginx can reach matrix-appservice-discord over the container network. +# If matrix-nginx-proxy is not enabled, or you otherwise have a need for it, you can expose +# matrix-appservice-discord's client-server port to the local host. +matrix_appservice_discord_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:9005' }}" + +# If the homeserver disables presence, it's likely better (less wasteful) to also disable presence on the bridge side. +matrix_appservice_discord_bridge_disablePresence: "{{ not matrix_synapse_presence_enabled }}" + +matrix_appservice_discord_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +matrix_appservice_discord_appservice_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'discord.as.token', rounds=655555) | to_uuid }}" + +matrix_appservice_discord_homeserver_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'discord.hs.token', rounds=655555) | to_uuid }}" + +# We only make this use Postgres if our own Postgres server is enabled. +# It's only then (for now) that we can automatically create the necessary database and user for this service. +matrix_appservice_discord_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'sqlite' }}" +matrix_appservice_discord_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_appservice_discord_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'as.discord.db', rounds=655555) | to_uuid }}" + +###################################################################### +# +# /matrix-bridge-appservice-discord +# +###################################################################### + + +###################################################################### +# +# matrix-appservice-webhooks +# +###################################################################### + +# We don't enable bridges by default. +matrix_appservice_webhooks_enabled: false + +matrix_appservice_webhooks_container_image_self_build: "{{ matrix_architecture != 'amd64' }}" + +# Normally, matrix-nginx-proxy is enabled and nginx can reach matrix-appservice-webhooks over the container network. +# If matrix-nginx-proxy is not enabled, or you otherwise have a need for it, you can expose +# matrix-appservice-webhooks' client-server port to the local host. +matrix_appservice_webhooks_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else ('127.0.0.1:' ~ matrix_appservice_webhooks_matrix_port) }}" + +matrix_appservice_webhooks_appservice_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'webhook.as.token', rounds=655555) | to_uuid }}" + +matrix_appservice_webhooks_homeserver_url: "{{ matrix_homeserver_container_url }}" +matrix_appservice_webhooks_homeserver_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'webhook.hs.token', rounds=655555) | to_uuid }}" + +matrix_appservice_webhooks_id_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'webhook.id.token', rounds=655555) | to_uuid }}" + +matrix_appservice_webhooks_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +###################################################################### +# +# /matrix-appservice-webhooks +# +###################################################################### + + +###################################################################### +# +# matrix-appservice-slack +# +###################################################################### + +# We don't enable bridges by default. +matrix_appservice_slack_enabled: false + +matrix_appservice_slack_container_image_self_build: "{{ matrix_architecture not in ['amd64', 'arm64'] }}" + +# Normally, matrix-nginx-proxy is enabled and nginx can reach matrix-appservice-slack over the container network. +# If matrix-nginx-proxy is not enabled, or you otherwise have a need for it, you can expose +# matrix-appservice-slack's client-server port to the local host. +matrix_appservice_slack_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else ('127.0.0.1:' ~ matrix_appservice_slack_slack_port) }}" + +matrix_appservice_slack_appservice_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'slack.as.token', rounds=655555) | to_uuid }}" + +matrix_appservice_slack_homeserver_url: "{{ matrix_homeserver_container_url }}" +matrix_appservice_slack_homeserver_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'slack.hs.token', rounds=655555) | to_uuid }}" + +matrix_appservice_slack_id_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'slack.id.token', rounds=655555) | to_uuid }}" + +matrix_appservice_slack_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +# Postgres is the default, except if not using internal Postgres server +matrix_appservice_slack_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'nedb' }}" +matrix_appservice_slack_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_appservice_slack_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'as.slack.db', rounds=655555) | to_uuid }}" + +###################################################################### +# +# /matrix-bridge-appservice-slack +# +###################################################################### + +###################################################################### +# +# matrix-bridge-appservice-irc +# +###################################################################### + +# We don't enable bridges by default. +matrix_appservice_irc_enabled: false + +matrix_appservice_irc_container_image_self_build: "{{ matrix_architecture != 'amd64' }}" + +# Normally, matrix-nginx-proxy is enabled and nginx can reach matrix-appservice-irc over the container network. +# If matrix-nginx-proxy is not enabled, or you otherwise have a need for it, you can expose +# matrix-appservice-irc's client-server port to the local host. +matrix_appservice_irc_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:9999' }}" + +# The IRC bridge docs say that if homeserver presence is disabled, it's better to also disable +# IRC bridge presence, for performance reasons. +matrix_appservice_irc_homeserver_enablePresence: "{{ matrix_synapse_presence_enabled }}" + +matrix_appservice_irc_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +matrix_appservice_irc_appservice_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'irc.as.token', rounds=655555) | to_uuid }}" + +matrix_appservice_irc_homeserver_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'irc.hs.token', rounds=655555) | to_uuid }}" + +matrix_appservice_irc_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'nedb' }}" +matrix_appservice_irc_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_appservice_irc_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'as.irc.db', rounds=655555) | to_uuid }}" + + +###################################################################### +# +# /matrix-bridge-appservice-irc +# +###################################################################### + +###################################################################### +# +# matrix-bridge-appservice-kakaotalk +# +###################################################################### + +# We don't enable bridges by default. +matrix_appservice_kakaotalk_enabled: false + +matrix_appservice_kakaotalk_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-appservice-kakaotalk-node.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + }} + +matrix_appservice_kakaotalk_appservice_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'as.kakao.hs', rounds=655555) | to_uuid }}" + +matrix_appservice_kakaotalk_homeserver_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'as.kakao.hs', rounds=655555) | to_uuid }}" + +matrix_appservice_kakaotalk_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" + +matrix_appservice_kakaotalk_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'sqlite' }}" +matrix_appservice_kakaotalk_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_appservice_kakaotalk_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'as.kakao.db', rounds=655555) | to_uuid }}" + +###################################################################### +# +# /matrix-bridge-appservice-kakaotalk +# +###################################################################### + + +###################################################################### +# +# matrix-bridge-beeper-linkedin +# +###################################################################### + +# We don't enable bridges by default. +matrix_beeper_linkedin_enabled: false + +matrix_beeper_linkedin_container_image_self_build: "{{ matrix_architecture not in ['amd64'] }}" + +matrix_beeper_linkedin_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +matrix_beeper_linkedin_appservice_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'linked.as.token', rounds=655555) | to_uuid }}" + +matrix_beeper_linkedin_homeserver_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'linked.hs.token', rounds=655555) | to_uuid }}" + +matrix_beeper_linkedin_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" + +matrix_beeper_linkedin_bridge_presence: "{{ matrix_synapse_presence_enabled if matrix_synapse_enabled else true }}" + +matrix_beeper_linkedin_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_beeper_linkedin_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'maulinkedin.db', rounds=655555) | to_uuid }}" + +###################################################################### +# +# /matrix-bridge-beeper-linkedin +# +###################################################################### + +###################################################################### +# +# matrix-bridge-go-skype-bridge +# +###################################################################### + +# We don't enable bridges by default. +matrix_go_skype_bridge_enabled: false + +matrix_go_skype_bridge_container_image_self_build: "{{ matrix_architecture not in ['amd64', 'arm64'] }}" + +matrix_go_skype_bridge_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +matrix_go_skype_bridge_appservice_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'skype.as.token', rounds=655555) | to_uuid }}" + +matrix_go_skype_bridge_homeserver_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'skype.hs.token', rounds=655555) | to_uuid }}" + +matrix_go_skype_bridge_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" + +# Postgres is the default, except if not using internal Postgres server +matrix_go_skype_bridge_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'sqlite' }}" +matrix_go_skype_bridge_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_go_skype_bridge_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'goskype.db', rounds=655555) | to_uuid }}" + +###################################################################### +# +# /matrix-bridge-go-skype-bridge +# +###################################################################### + + +###################################################################### +# +# matrix-bridge-mautrix-discord +# +###################################################################### + +# We don't enable bridges by default. +matrix_mautrix_discord_enabled: false + +matrix_mautrix_discord_container_image_self_build: "{{ matrix_architecture not in ['arm64', 'amd64'] }}" + +matrix_mautrix_discord_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +matrix_mautrix_discord_appservice_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'maudisc.as.tok', rounds=655555) | to_uuid }}" + +matrix_mautrix_discord_homeserver_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'maudisc.hs.tok', rounds=655555) | to_uuid }}" + +matrix_mautrix_discord_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" + +# Postgres is the default, except if not using internal Postgres server +matrix_mautrix_discord_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'sqlite' }}" +matrix_mautrix_discord_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_mautrix_discord_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'maudiscord.db', rounds=655555) | to_uuid }}" + +# Enabling bridge.restricted_rooms for this bridge does not work well with Conduit, so we disable it by default. +# This will be fixed in the upcoming `0.5.0` release of conduit. +matrix_mautrix_discord_bridge_restricted_rooms: "{{ false if matrix_homeserver_implementation == 'conduit' else true }}" + +###################################################################### +# +# /matrix-bridge-mautrix-discord +# +###################################################################### + + +###################################################################### +# +# matrix-bridge-mautrix-facebook +# +###################################################################### + +# We don't enable bridges by default. +matrix_mautrix_facebook_enabled: false + +matrix_mautrix_facebook_container_image_self_build: "{{ matrix_architecture not in ['amd64', 'arm64'] }}" + +matrix_mautrix_facebook_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +matrix_mautrix_facebook_appservice_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'fb.as.token', rounds=655555) | to_uuid }}" + +matrix_mautrix_facebook_homeserver_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'fb.hs.token', rounds=655555) | to_uuid }}" + +matrix_mautrix_facebook_public_endpoint: "/{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'facebook', rounds=655555) | to_uuid }}" + +matrix_mautrix_facebook_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:9008' }}" + +matrix_mautrix_facebook_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" + +matrix_mautrix_facebook_bridge_presence: "{{ matrix_synapse_presence_enabled if matrix_synapse_enabled else true }}" + +# We'd like to force-set people with external Postgres to SQLite, so the bridge role can complain +# and point them to a migration path. +matrix_mautrix_facebook_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'sqlite' }}" +matrix_mautrix_facebook_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_mautrix_facebook_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mau.fb.db', rounds=655555) | to_uuid }}" + +###################################################################### +# +# /matrix-bridge-mautrix-facebook +# +###################################################################### + + +###################################################################### +# +# matrix-bridge-mautrix-googlechat +# +###################################################################### + +# We don't enable bridges by default. +matrix_mautrix_googlechat_enabled: false + +matrix_mautrix_googlechat_container_image_self_build: "{{ matrix_architecture not in ['amd64', 'arm64'] }}" + +matrix_mautrix_googlechat_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +matrix_mautrix_googlechat_appservice_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'gc.as.token', rounds=655555) | to_uuid }}" + +matrix_mautrix_googlechat_homeserver_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'gc.hs.token', rounds=655555) | to_uuid }}" + +matrix_mautrix_googlechat_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:9007' }}" + +matrix_mautrix_googlechat_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" + +# Postgres is the default, except if not using internal Postgres server +matrix_mautrix_googlechat_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'sqlite' }}" +matrix_mautrix_googlechat_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_mautrix_googlechat_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mau.gc.db', rounds=655555) | to_uuid }}" + +###################################################################### +# +# /matrix-bridge-mautrix-googlechat +# +###################################################################### + + +###################################################################### +# +# matrix-bridge-mautrix-hangouts +# +###################################################################### + +# We don't enable bridges by default. +matrix_mautrix_hangouts_enabled: false + +matrix_mautrix_hangouts_container_image_self_build: "{{ matrix_architecture not in ['amd64', 'arm64'] }}" + +matrix_mautrix_hangouts_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +matrix_mautrix_hangouts_appservice_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'ho.as.token', rounds=655555) | to_uuid }}" + +matrix_mautrix_hangouts_homeserver_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'ho.hs.token', rounds=655555) | to_uuid }}" + +matrix_mautrix_hangouts_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:9007' }}" + +matrix_mautrix_hangouts_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" + +# Postgres is the default, except if not using internal Postgres server +matrix_mautrix_hangouts_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'sqlite' }}" +matrix_mautrix_hangouts_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_mautrix_hangouts_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mau.hangouts.db', rounds=655555) | to_uuid }}" + +###################################################################### +# +# /matrix-bridge-mautrix-hangouts +# +###################################################################### + + +###################################################################### +# +# matrix-bridge-mautrix-instagram +# +###################################################################### + +# We don't enable bridges by default. +matrix_mautrix_instagram_enabled: false + +matrix_mautrix_instagram_container_image_self_build: "{{ matrix_architecture not in ['amd64', 'arm64'] }}" + +matrix_mautrix_instagram_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +matrix_mautrix_instagram_appservice_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'ig.as.token', rounds=655555) | to_uuid }}" + +matrix_mautrix_instagram_homeserver_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'ig.hs.token', rounds=655555) | to_uuid }}" + +matrix_mautrix_instagram_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" + +matrix_mautrix_instagram_bridge_presence: "{{ matrix_synapse_presence_enabled if matrix_synapse_enabled else true }}" + +# We'd like to force-set people with external Postgres to SQLite, so the bridge role can complain +# and point them to a migration path. +matrix_mautrix_instagram_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'sqlite' }}" +matrix_mautrix_instagram_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_mautrix_instagram_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mau.ig.db', rounds=655555) | to_uuid }}" + +###################################################################### +# +# /matrix-bridge-mautrix-instagram +# +###################################################################### + + +###################################################################### +# +# matrix-bridge-mautrix-signal +# +###################################################################### + +# We don't enable bridges by default. +matrix_mautrix_signal_enabled: false + +matrix_mautrix_signal_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + + + ['matrix-mautrix-signal-daemon.service'] + }} + +matrix_mautrix_signal_homeserver_domain: '{{ matrix_domain }}' + +matrix_mautrix_signal_homeserver_address: "{{ matrix_homeserver_container_url }}" + +matrix_mautrix_signal_homeserver_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'si.hs.token', rounds=655555) | to_uuid }}" + +matrix_mautrix_signal_appservice_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'si.as.token', rounds=655555) | to_uuid }}" + +matrix_mautrix_signal_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" + +matrix_mautrix_signal_database_engine: 'postgres' +matrix_mautrix_signal_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_mautrix_signal_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mau.signal.db', rounds=655555) | to_uuid }}" + +matrix_mautrix_signal_container_image_self_build: "{{ matrix_architecture not in ['amd64', 'arm64'] }}" +matrix_mautrix_signal_daemon_container_image_self_build: "{{ matrix_architecture not in ['amd64', 'arm64'] }}" + +###################################################################### +# +# /matrix-bridge-mautrix-signal +# +###################################################################### + +###################################################################### +# +# matrix-bridge-mautrix-telegram +# +###################################################################### + +# We don't enable bridges by default. +matrix_mautrix_telegram_enabled: false + +# Images are multi-arch (amd64 and arm64, but not arm32). +matrix_mautrix_telegram_container_image_self_build: "{{ matrix_architecture not in ['arm64', 'amd64'] }}" +matrix_telegram_lottieconverter_container_image_self_build: "{{ matrix_architecture not in ['arm64', 'amd64'] }}" +matrix_telegram_lottieconverter_container_image_self_build_mask_arch: "{{ matrix_architecture != 'amd64' }}" + +matrix_mautrix_telegram_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +matrix_mautrix_telegram_appservice_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'telegr.as.token', rounds=655555) | to_uuid }}" + +matrix_mautrix_telegram_homeserver_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'telegr.hs.token', rounds=655555) | to_uuid }}" + +matrix_mautrix_telegram_public_endpoint: "/{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'telegram', rounds=655555) | to_uuid }}" + +matrix_mautrix_telegram_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:9006' }}" + +matrix_mautrix_telegram_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" + +# Postgres is the default, except if not using internal Postgres server +matrix_mautrix_telegram_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'sqlite' }}" +matrix_mautrix_telegram_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_mautrix_telegram_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mau.telegram.db', rounds=655555) | to_uuid }}" + +###################################################################### +# +# /matrix-bridge-mautrix-telegram +# +###################################################################### + +###################################################################### +# +# matrix-bridge-mautrix-twitter +# +###################################################################### + +# We don't enable bridges by default. +matrix_mautrix_twitter_enabled: false + +matrix_mautrix_twitter_container_image_self_build: "{{ matrix_architecture not in ['amd64', 'arm64'] }}" + +matrix_mautrix_twitter_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +matrix_mautrix_twitter_appservice_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'twt.as.token', rounds=655555) | to_uuid }}" + +matrix_mautrix_twitter_homeserver_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'twt.hs.token', rounds=655555) | to_uuid }}" + +matrix_mautrix_twitter_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" + +matrix_mautrix_twitter_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_mautrix_twitter_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mau.twt.db', rounds=655555) | to_uuid if devture_postgres_enabled else '' }}" + +###################################################################### +# +# /matrix-bridge-mautrix-twitter +# +###################################################################### + +###################################################################### +# +# matrix-bridge-mautrix-whatsapp +# +###################################################################### + +# We don't enable bridges by default. +matrix_mautrix_whatsapp_enabled: false + +matrix_mautrix_whatsapp_container_image_self_build: "{{ matrix_architecture not in ['arm64', 'amd64'] }}" + +matrix_mautrix_whatsapp_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +matrix_mautrix_whatsapp_appservice_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'whats.as.token', rounds=655555) | to_uuid }}" + +matrix_mautrix_whatsapp_homeserver_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'whats.hs.token', rounds=655555) | to_uuid }}" + +matrix_mautrix_whatsapp_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" + +# Postgres is the default, except if not using internal Postgres server +matrix_mautrix_whatsapp_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'sqlite' }}" +matrix_mautrix_whatsapp_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_mautrix_whatsapp_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mauwhatsapp.db', rounds=655555) | to_uuid }}" + +###################################################################### +# +# /matrix-bridge-mautrix-whatsapp +# +###################################################################### + +###################################################################### +# +# matrix-sms-bridge +# +###################################################################### + +# We don't enable bridges by default. +matrix_sms_bridge_enabled: false + +matrix_sms_bridge_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +matrix_sms_bridge_appservice_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'sms.as.token', rounds=655555) | to_uuid }}" + +matrix_sms_bridge_homeserver_port: "{{ matrix_synapse_container_client_api_port }}" +matrix_sms_bridge_homeserver_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'sms.hs.token', rounds=655555) | to_uuid }}" + +###################################################################### +# +# /matrix-sms-bridge +# +###################################################################### + +###################################################################### +# +# matrix-bridge-heisenbridge +# +###################################################################### + +# We don't enable bridges by default. +matrix_heisenbridge_enabled: false + +matrix_heisenbridge_appservice_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'heisen.as.tok', rounds=655555) | to_uuid }}" + +matrix_heisenbridge_homeserver_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'heisen.hs.tok', rounds=655555) | to_uuid }}" + +matrix_heisenbridge_systemd_wanted_services_list: | + {{ + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +###################################################################### +# +# /matrix-bridge-heisenbridge +# +###################################################################### + +###################################################################### +# +# matrix-bridge-hookshot +# +###################################################################### + +# We don't enable bridges by default. +matrix_hookshot_enabled: false + +matrix_hookshot_container_image_self_build: "{{ matrix_architecture not in ['arm64', 'amd64'] }}" + +matrix_hookshot_appservice_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'hookshot.as.tok', rounds=655555) | to_uuid }}" + +matrix_hookshot_homeserver_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'hookshot.hs.tok', rounds=655555) | to_uuid }}" + +matrix_hookshot_systemd_wanted_services_list: | + {{ + (['matrix-' + matrix_homeserver_implementation + '.service']) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +matrix_hookshot_container_http_host_bind_ports_defaultmapping: + - "127.0.0.1:{{ matrix_hookshot_appservice_port }}:{{ matrix_hookshot_appservice_port }}" + - "127.0.0.1:{{ matrix_hookshot_metrics_port }}:{{ matrix_hookshot_metrics_port }}" + - "127.0.0.1:{{ matrix_hookshot_webhook_port }}:{{ matrix_hookshot_webhook_port }}" + - "127.0.0.1:{{ matrix_hookshot_provisioning_port }}:{{ matrix_hookshot_provisioning_port }}" + +matrix_hookshot_container_http_host_bind_ports: "{{ [] if matrix_nginx_proxy_enabled else matrix_hookshot_container_http_host_bind_ports_defaultmapping }}" + +matrix_hookshot_provisioning_enabled: "{{ matrix_hookshot_provisioning_secret and matrix_dimension_enabled }}" + +# We only enable metrics (locally, in the container network) for the bridge if Prometheus is enabled. +# +# People using an external Prometheus server will need to toggle all of these to be able to consume metrics remotely: +# - `matrix_hookshot_metrics_enabled` +# - `matrix_hookshot_metrics_proxying_enabled` +# - `matrix_nginx_proxy_proxy_matrix_metrics_enabled` +matrix_hookshot_metrics_enabled: "{{ matrix_prometheus_enabled }}" + +matrix_hookshot_urlprefix_port_enabled: "{{ matrix_nginx_proxy_container_https_host_bind_port == 443 if matrix_nginx_proxy_https_enabled else matrix_nginx_proxy_container_https_host_bind_port == 80 }}" +matrix_hookshot_urlprefix_port: ":{{ matrix_nginx_proxy_container_https_host_bind_port if matrix_nginx_proxy_https_enabled else matrix_nginx_proxy_container_http_host_bind_port }}" +matrix_hookshot_urlprefix: "http{{ 's' if matrix_nginx_proxy_https_enabled else '' }}://{{ matrix_server_fqn_matrix }}{{ matrix_hookshot_urlprefix_port if matrix_hookshot_urlprefix_port_enabled else '' }}" + +###################################################################### +# +# /matrix-bridge-hookshot +# +###################################################################### + + +###################################################################### +# +# matrix-bridge-mx-puppet-slack +# +###################################################################### + +# We don't enable bridges by default. +matrix_mx_puppet_slack_enabled: false + +matrix_mx_puppet_slack_container_image_self_build: "{{ matrix_architecture != 'amd64' }}" + +matrix_mx_puppet_slack_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +matrix_mx_puppet_slack_appservice_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mxslk.as.tok', rounds=655555) | to_uuid }}" + +matrix_mx_puppet_slack_homeserver_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mxslk.hs.tok', rounds=655555) | to_uuid }}" + +matrix_mx_puppet_slack_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" + +# Postgres is the default, except if not using internal Postgres server +matrix_mx_puppet_slack_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'sqlite' }}" +matrix_mx_puppet_slack_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_mx_puppet_slack_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mxpup.slack.db', rounds=655555) | to_uuid }}" + +###################################################################### +# +# /matrix-bridge-mx-puppet-slack +# +###################################################################### + +###################################################################### +# +# matrix-bridge-mx-puppet-twitter +# +###################################################################### + +# We don't enable bridges by default. +matrix_mx_puppet_twitter_enabled: false + +matrix_mx_puppet_twitter_container_image_self_build: "{{ matrix_architecture != 'amd64' }}" + +matrix_mx_puppet_twitter_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +matrix_mx_puppet_twitter_appservice_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mxtwt.as.tok', rounds=655555) | to_uuid }}" + +matrix_mx_puppet_twitter_homeserver_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mxtwt.hs.tok', rounds=655555) | to_uuid }}" + +matrix_mx_puppet_twitter_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" + +matrix_mx_puppet_twitter_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else ('127.0.0.1:' ~ matrix_mx_puppet_twitter_appservice_port) }}" + +# Postgres is the default, except if not using internal Postgres server +matrix_mx_puppet_twitter_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'sqlite' }}" +matrix_mx_puppet_twitter_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_mx_puppet_twitter_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mxpup.twitter.db', rounds=655555) | to_uuid }}" + +###################################################################### +# +# /matrix-bridge-mx-puppet-twitter +# +###################################################################### + + +###################################################################### +# +# matrix-bridge-mx-puppet-instagram +# +###################################################################### + +# We don't enable bridges by default. +matrix_mx_puppet_instagram_enabled: false + +matrix_mx_puppet_instagram_container_image_self_build: "{{ matrix_architecture != 'amd64' }}" + +matrix_mx_puppet_instagram_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +matrix_mx_puppet_instagram_appservice_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mxig.as.tok', rounds=655555) | to_uuid }}" + +matrix_mx_puppet_instagram_homeserver_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mxig.hs.tok', rounds=655555) | to_uuid }}" + +matrix_mx_puppet_instagram_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" + +# Postgres is the default, except if not using internal Postgres server +matrix_mx_puppet_instagram_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'sqlite' }}" +matrix_mx_puppet_instagram_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_mx_puppet_instagram_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mxpup.ig.db', rounds=655555) | to_uuid }}" + +###################################################################### +# +# /matrix-bridge-mx-puppet-instagram +# +###################################################################### + +###################################################################### +# +# matrix-bridge-mx-puppet-discord +# +###################################################################### + +# We don't enable bridges by default. +matrix_mx_puppet_discord_enabled: false + +matrix_mx_puppet_discord_container_image_self_build: "{{ matrix_architecture != 'amd64' }}" + +matrix_mx_puppet_discord_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +matrix_mx_puppet_discord_appservice_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mxdsc.as.tok', rounds=655555) | to_uuid }}" + +matrix_mx_puppet_discord_homeserver_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mxdsc.hs.tok', rounds=655555) | to_uuid }}" + +matrix_mx_puppet_discord_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" + +# Postgres is the default, except if not using internal Postgres server +matrix_mx_puppet_discord_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'sqlite' }}" +matrix_mx_puppet_discord_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_mx_puppet_discord_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mxpup.dsc.db', rounds=655555) | to_uuid }}" + +###################################################################### +# +# /matrix-bridge-mx-puppet-discord +# +###################################################################### + +###################################################################### +# +# matrix-bridge-mx-puppet-steam +# +###################################################################### + +# We don't enable bridges by default. +matrix_mx_puppet_steam_enabled: false + +matrix_mx_puppet_steam_container_image_self_build: "{{ matrix_architecture not in ['arm64', 'amd64'] }}" + +matrix_mx_puppet_steam_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +matrix_mx_puppet_steam_appservice_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mxste.as.tok', rounds=655555) | to_uuid }}" + +matrix_mx_puppet_steam_homeserver_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mxste.hs.tok', rounds=655555) | to_uuid }}" + +matrix_mx_puppet_steam_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" + +# Postgres is the default, except if not using internal Postgres server +matrix_mx_puppet_steam_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'sqlite' }}" +matrix_mx_puppet_steam_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_mx_puppet_steam_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mxpup.steam.db', rounds=655555) | to_uuid }}" + +###################################################################### +# +# /matrix-bridge-mx-puppet-steam +# +###################################################################### + +###################################################################### +# +# matrix-bridge-mx-puppet-groupme +# +###################################################################### + +# We don't enable bridges by default. +matrix_mx_puppet_groupme_enabled: false + +matrix_mx_puppet_groupme_container_image_self_build: "{{ matrix_architecture != 'amd64' }}" + +matrix_mx_puppet_groupme_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +matrix_mx_puppet_groupme_appservice_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mxgro.as.tok', rounds=655555) | to_uuid }}" + +matrix_mx_puppet_groupme_homeserver_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mxgro.hs.tok', rounds=655555) | to_uuid }}" + +matrix_mx_puppet_groupme_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}" + +# Postgres is the default, except if not using internal Postgres server +matrix_mx_puppet_groupme_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'sqlite' }}" +matrix_mx_puppet_groupme_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_mx_puppet_groupme_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mxpup.groupme.db', rounds=655555) | to_uuid }}" + +###################################################################### +# +# /matrix-bridge-mx-puppet-groupme +# +###################################################################### + +###################################################################### +# +# matrix-bot-matrix-reminder-bot +# +###################################################################### + +# We don't enable bots by default. +matrix_bot_matrix_reminder_bot_enabled: false + +matrix_bot_matrix_reminder_bot_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +# Postgres is the default, except if not using internal Postgres server +matrix_bot_matrix_reminder_bot_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'sqlite' }}" +matrix_bot_matrix_reminder_bot_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_bot_matrix_reminder_bot_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'reminder.bot.db', rounds=655555) | to_uuid }}" +matrix_bot_matrix_reminder_bot_container_image_self_build: "{{ matrix_architecture != 'amd64' }}" + +###################################################################### +# +# /matrix-bot-matrix-reminder-bot +# +###################################################################### + + +###################################################################### +# +# matrix-bot-matrix-registration-bot +# +###################################################################### + +# We don't enable bots by default. +matrix_bot_matrix_registration_bot_enabled: false + +matrix_bot_matrix_registration_bot_container_image_self_build: "{{ matrix_architecture not in ['amd64'] }}" + +matrix_bot_matrix_registration_bot_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + + +###################################################################### +# +# /matrix-bot-matrix-registration-bot +# +###################################################################### + +###################################################################### +# +# matrix-bot-maubot +# +###################################################################### + +# We don't enable bots by default. +matrix_bot_maubot_enabled: false + +matrix_bot_maubot_container_image_self_build: "{{ matrix_architecture not in ['amd64'] }}" + +matrix_bot_maubot_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +matrix_bot_maubot_registration_shared_secret: |- + {{ + { + 'synapse': matrix_synapse_registration_shared_secret, + 'dendrite': matrix_dendrite_client_api_registration_shared_secret, + }[matrix_homeserver_implementation] + }} + +matrix_bot_maubot_management_interface_http_bind_port: "{{ '' if matrix_nginx_proxy_enabled else ('127.0.0.1:' + matrix_bot_maubot_management_interface_port | string) }}" + +# Postgres is the default, except if not using internal Postgres server +matrix_bot_maubot_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'sqlite' }}" +matrix_bot_maubot_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_bot_maubot_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mxpup.dsc.db', rounds=655555) | to_uuid }}" + +###################################################################### +# +# /matrix-bot-maubot +# +###################################################################### + + +###################################################################### +# +# matrix-bot-honoroit +# +###################################################################### + +# We don't enable bots by default. +matrix_bot_honoroit_enabled: false + +matrix_bot_honoroit_systemd_required_services_list: | + {{ + ['docker.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-synapse.service'] if matrix_synapse_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +# Postgres is the default, except if not using internal Postgres server +matrix_bot_honoroit_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'sqlite' }}" +matrix_bot_honoroit_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_bot_honoroit_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'honoroit.bot.db', rounds=655555) | to_uuid }}" +matrix_bot_honoroit_container_image_self_build: "{{ matrix_architecture not in ['amd64', 'arm64'] }}" + +###################################################################### +# +# /matrix-bot-honoroit +# +###################################################################### + +###################################################################### +# +# matrix-bot-buscarron +# +###################################################################### + +# We don't enable bots by default. +matrix_bot_buscarron_enabled: false + +matrix_bot_buscarron_container_image_self_build: "{{ matrix_architecture not in ['amd64', 'arm64'] }}" + +matrix_bot_buscarron_systemd_required_services_list: | + {{ + ['docker.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-synapse.service'] if matrix_synapse_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +# Postgres is the default, except if not using internal Postgres server +matrix_bot_buscarron_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'sqlite' }}" +matrix_bot_buscarron_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_bot_buscarron_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'buscarron.bot.db', rounds=655555) | to_uuid }}" + +###################################################################### +# +# /matrix-bot-buscarron +# +###################################################################### + +###################################################################### +# +# matrix-bot-postmoogle +# +###################################################################### + +# We don't enable bots by default. +matrix_bot_postmoogle_enabled: false + +matrix_bot_postmoogle_container_image_self_build: "{{ matrix_architecture not in ['amd64', 'arm64'] }}" + +matrix_bot_postmoogle_ssl_path: "{{ matrix_ssl_config_dir_path }}" +matrix_bot_postmoogle_tls_cert: "{% for domain in matrix_bot_postmoogle_domains %}/ssl/live/{{ domain }}/fullchain.pem {% endfor %}" +matrix_bot_postmoogle_tls_key: "{% for domain in matrix_bot_postmoogle_domains %}/ssl/live/{{ domain }}/privkey.pem {% endfor %}" + +matrix_bot_postmoogle_systemd_required_services_list: | + {{ + ['docker.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-synapse.service'] if matrix_synapse_enabled else []) + }} + +# Postgres is the default, except if not using internal Postgres server +matrix_bot_postmoogle_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'sqlite' }}" +matrix_bot_postmoogle_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_bot_postmoogle_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'postmoogle.db', rounds=655555) | to_uuid }}" + +###################################################################### +# +# /matrix-bot-postmoogle +# +###################################################################### + + +###################################################################### +# +# matrix-bot-go-neb +# +###################################################################### + +# We don't enable bots by default. +matrix_bot_go_neb_enabled: false + +matrix_bot_go_neb_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +matrix_bot_go_neb_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:4050' }}" + +###################################################################### +# +# /matrix-bot-go-neb +# +###################################################################### + + +###################################################################### +# +# matrix-bot-mjolnir +# +###################################################################### + +# We don't enable bots by default. +matrix_bot_mjolnir_enabled: false + +matrix_bot_mjolnir_container_image_self_build: "{{ matrix_architecture != 'amd64' }}" + +matrix_bot_mjolnir_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +###################################################################### +# +# /matrix-bot-mjolnir +# +###################################################################### + +###################################################################### +# +# matrix-backup-borg +# +###################################################################### + +matrix_backup_borg_enabled: false + +matrix_backup_borg_container_image_self_build: "{{ matrix_architecture not in ['amd64', 'arm32', 'arm64'] }}" + +matrix_backup_borg_postgresql_enabled: "{{ devture_postgres_enabled }}" +matrix_backup_borg_postgresql_databases_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_backup_borg_postgresql_databases_username: "{{ devture_postgres_connection_username if devture_postgres_enabled else '' }}" +matrix_backup_borg_postgresql_databases_password: "{{ devture_postgres_connection_password if devture_postgres_enabled else '' }}" +matrix_backup_borg_postgresql_databases_port: "{{ devture_postgres_connection_port if devture_postgres_enabled else 5432 }}" +matrix_backup_borg_postgresql_databases: "{{ devture_postgres_managed_databases | map(attribute='name') if devture_postgres_enabled else [] }}" + +matrix_backup_borg_location_source_directories: + - "{{ matrix_base_data_path }}" + +matrix_backup_borg_location_exclude_patterns: | + {{ + ([matrix_synapse_media_store_path + '/local_thumbnails', matrix_synapse_media_store_path + '/remote_thumbnail', matrix_synapse_media_store_path + '/url_cache', matrix_synapse_media_store_path + '/url_cache_thumbnails'] if matrix_homeserver_implementation == 'synapse' else []) + + + ([devture_postgres_data_path] if devture_postgres_enabled else []) + }} + +matrix_backup_borg_systemd_required_services_list: | + {{ + ['docker.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + }} + +###################################################################### +# +# /matrix-backup-borg +# +###################################################################### +###################################################################### +# +# matrix-cactus-comments +# +###################################################################### + +matrix_cactus_comments_enabled: false + +# Derive secret values from homeserver secret +matrix_cactus_comments_as_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'cactus.as.token', rounds=655555) | to_uuid }}" +matrix_cactus_comments_hs_token: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'cactus.hs.token', rounds=655555) | to_uuid }}" + +matrix_cactus_comments_container_image_self_build: "{{ matrix_architecture not in ['amd64', 'arm32', 'arm64'] }}" +matrix_cactus_comments_systemd_required_services_list: | + {{ + (['docker.service']) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + + + (['matrix-' + matrix_homeserver_implementation + '.service']) + }} + +matrix_cactus_comments_client_nginx_path: "{{ '/cactus-comments/' if matrix_nginx_proxy_enabled else matrix_cactus_comments_client_path + '/' }}" + +###################################################################### +# +# /matrix-cactus-comments +# +###################################################################### + +###################################################################### +# +# matrix-corporal +# +###################################################################### + +matrix_corporal_enabled: false + +matrix_corporal_container_image_self_build: "{{ matrix_architecture not in ['amd64', 'arm32', 'arm64'] }}" + +# Normally, matrix-nginx-proxy is enabled and nginx can reach matrix-corporal over the container network. +# If matrix-nginx-proxy is not enabled, or you otherwise have a need for it, you can expose +# matrix-corporal's web-server ports to the local host. +matrix_corporal_container_http_gateway_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:41080' }}" +matrix_corporal_container_http_api_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:41081' }}" + +matrix_corporal_systemd_required_services_list: | + {{ + (['docker.service']) + + + (['matrix-' + matrix_homeserver_implementation + '.service']) + }} + +matrix_corporal_matrix_homeserver_api_endpoint: "{{ matrix_homeserver_container_url }}" + +matrix_corporal_matrix_auth_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret }}" + +# This is only useful if there's REST auth provider to make use of it. +matrix_corporal_http_gateway_internal_rest_auth_enabled: "{{ matrix_synapse_ext_password_provider_rest_auth_enabled }}" + +matrix_corporal_matrix_registration_shared_secret: "{{ matrix_synapse_registration_shared_secret }}" + +###################################################################### +# +# /matrix-corporal +# +###################################################################### + +###################################################################### +# +# matrix-coturn +# +###################################################################### + +matrix_coturn_enabled: true + +matrix_coturn_container_image_self_build: "{{ matrix_architecture not in ['amd64', 'arm32', 'arm64'] }}" + +matrix_coturn_turn_external_ip_address: "{{ ansible_host }}" + +matrix_coturn_turn_static_auth_secret: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'coturn.sas', rounds=655555) | to_uuid }}" + +matrix_coturn_tls_enabled: "{{ matrix_ssl_retrieval_method != 'none' }}" +matrix_coturn_tls_cert_path: "{{ matrix_ssl_config_dir_path }}/live/{{ matrix_server_fqn_matrix }}/fullchain.pem" +matrix_coturn_tls_key_path: "{{ matrix_ssl_config_dir_path }}/live/{{ matrix_server_fqn_matrix }}/privkey.pem" +matrix_coturn_container_additional_volumes: | + {{ + ([] if matrix_ssl_retrieval_method == 'none' else [ + { + 'src': matrix_ssl_config_dir_path, + 'dst': matrix_ssl_config_dir_path, + 'options': 'ro', + } + ]) + }} + +###################################################################### +# +# /matrix-coturn +# +###################################################################### + +###################################################################### +# +# matrix-dimension +# +###################################################################### + +matrix_dimension_enabled: false + +matrix_dimension_container_image_self_build: "{{ matrix_architecture != 'amd64' }}" + +# Normally, matrix-nginx-proxy is enabled and nginx can reach Dimension over the container network. +# If matrix-nginx-proxy is not enabled, or you otherwise have a need for it, you can expose +# the Dimension HTTP port to the local host. +matrix_dimension_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:8184' }}" + +matrix_dimension_homeserver_federationUrl: "{{ matrix_homeserver_container_federation_url }}" + +matrix_dimension_systemd_required_services_list: | + {{ + ['docker.service'] + + + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else []) + }} + +# Postgres is the default, except if not using internal Postgres server +matrix_dimension_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'sqlite' }}" +matrix_dimension_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_dimension_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'dimension.db', rounds=655555) | to_uuid }}" + +###################################################################### +# +# /matrix-dimension +# +###################################################################### + +###################################################################### +# +# matrix-etherpad +# +###################################################################### + +matrix_etherpad_enabled: false + +matrix_etherpad_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:9001' }}" + +matrix_etherpad_base_url: "{{ 'https://' + matrix_server_fqn_dimension + matrix_etherpad_public_endpoint if matrix_etherpad_mode == 'dimension' else 'https://' + matrix_server_fqn_etherpad + '/' }}" + +matrix_etherpad_systemd_required_services_list: | + {{ + ['docker.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + }} + +matrix_etherpad_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_etherpad_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'etherpad.db', rounds=655555) | to_uuid }}" + +###################################################################### +# +# /matrix-etherpad +# +###################################################################### + +###################################################################### +# +# matrix-dynamic-dns +# +###################################################################### + +matrix_dynamic_dns_enabled: false + +###################################################################### +# +# /matrix-dynamic-dns +# +###################################################################### + +###################################################################### +# +# matrix-email2matrix +# +###################################################################### + +matrix_email2matrix_enabled: false + +matrix_email2matrix_container_image_self_build: "{{ matrix_architecture not in ['amd64', 'arm32', 'arm64'] }}" + +###################################################################### +# +# /matrix-email2matrix +# +###################################################################### + +###################################################################### +# +# matrix-jitsi +# +###################################################################### + +matrix_jitsi_enabled: false + +# Normally, matrix-nginx-proxy is enabled and nginx can reach jitsi/web over the container network. +# If matrix-nginx-proxy is not enabled, or you otherwise have a need for it, you can expose +# the Jitsi HTTP port to the local host. +matrix_jitsi_web_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:13080' }}" + +matrix_jitsi_jvb_container_colibri_ws_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:13090' }}" + +matrix_jitsi_prosody_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:5280' }}" + +matrix_jitsi_jibri_xmpp_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'jibri', rounds=655555) | to_uuid }}" +matrix_jitsi_jicofo_auth_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'jicofo', rounds=655555) | to_uuid }}" +matrix_jitsi_jvb_auth_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'jvb', rounds=655555) | to_uuid }}" + +matrix_jitsi_web_stun_servers: | + {{ + [ + 'stun:' + matrix_server_fqn_matrix + ':5349', + 'stun:' + matrix_server_fqn_matrix + ':3478', + ] + if matrix_coturn_enabled + else [ 'stun:meet-jit-si-turnrelay.jitsi.net:443'] + }} + +# If the self-hosted Etherpad instance is available, it will also show up in Jitsi conferences, +# unless explicitly disabled by setting `matrix_jitsi_etherpad_enabled` to false. +# Falls back to the scalar.vector.im etherpad in case someone sets `matrix_jitsi_etherpad_enabled` to true, +# while also setting `matrix_etherpad_enabled` to false. +matrix_jitsi_etherpad_enabled: "{{ matrix_etherpad_enabled }}" +matrix_jitsi_etherpad_base: "{{ matrix_etherpad_base_url if matrix_etherpad_enabled else 'https://scalar.vector.im/etherpad' }}" + +###################################################################### +# +# /matrix-jitsi +# +###################################################################### +###################################################################### +# +# matrix-ldap-registration-proxy +# +###################################################################### + +# This is only for users with a specific LDAP setup +matrix_ldap_registration_proxy_enabled: false + +###################################################################### +# +# /matrix-ldap-registration-proxy +# +###################################################################### + +###################################################################### +# +# matrix-mailer +# +###################################################################### + +# By default, this playbook sets up an exim mailer server (running in a container). +# This is so that Synapse can send email reminders for unread messages. +# Other services (like ma1sd), also use the mailer. +matrix_mailer_enabled: true + +matrix_mailer_container_image_self_build: "{{ matrix_architecture not in ['amd64', 'arm32', 'arm64'] }}" + +###################################################################### +# +# /matrix-mailer +# +###################################################################### + +###################################################################### +# +# matrix-ma1sd +# +###################################################################### + +# We no longer install the ma1sd identity server by default. +# +# The main reason we used to install ma1sd by default in the past was to +# prevent Element from talking to the `matrix.org` / `vector.im` identity servers, +# by forcing it to talk to our own self-hosted (but otherwise useless) identity server instead, +# thus preventing contact list leaks. +# +# Since Element no longer defaults to using a public identity server if another one is not provided, +# we can stop installing ma1sd. +matrix_ma1sd_enabled: false + +matrix_ma1sd_container_image_self_build: "{{ matrix_architecture != 'amd64' }}" + +# Normally, matrix-nginx-proxy is enabled and nginx can reach ma1sd over the container network. +# If matrix-nginx-proxy is not enabled, or you otherwise have a need for it, you can expose +# ma1sd's web-server port. +matrix_ma1sd_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:' + matrix_ma1sd_container_port | string }}" + + +# We enable Synapse integration via its Postgres database by default. +# When using another Identity store, you might wish to disable this and define +# your own configuration in `matrix_ma1sd_configuration_extension_yaml`. +matrix_ma1sd_synapsesql_enabled: true +matrix_ma1sd_synapsesql_type: postgresql +matrix_ma1sd_synapsesql_connection: //{{ matrix_synapse_database_host }}/{{ matrix_synapse_database_database }}?user={{ matrix_synapse_database_user | urlencode() }}&password={{ matrix_synapse_database_password | urlencode() }} + +matrix_ma1sd_dns_overwrite_enabled: true +matrix_ma1sd_dns_overwrite_homeserver_client_name: "{{ matrix_server_fqn_matrix }}" +# The `matrix_ma1sd_dns_overwrite_homeserver_client_value` value when matrix_nginx_proxy_enabled is false covers the general case, +# but may be inaccurate if matrix-corporal is enabled. +matrix_ma1sd_dns_overwrite_homeserver_client_value: "{{ ('http://' + matrix_nginx_proxy_proxy_matrix_client_api_addr_with_container) if matrix_nginx_proxy_enabled else matrix_homeserver_container_url }}" + +# By default, we send mail through the `matrix-mailer` service. +matrix_ma1sd_threepid_medium_email_identity_from: "{{ matrix_mailer_sender_address }}" +matrix_ma1sd_threepid_medium_email_connectors_smtp_host: "matrix-mailer" +matrix_ma1sd_threepid_medium_email_connectors_smtp_port: 8025 +matrix_ma1sd_threepid_medium_email_connectors_smtp_tls: 0 + +matrix_ma1sd_self_check_validate_certificates: "{{ false if matrix_ssl_retrieval_method == 'self-signed' else true }}" + +matrix_ma1sd_systemd_required_services_list: | + {{ + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + }} + +matrix_ma1sd_systemd_wanted_services_list: | + {{ + (['matrix-corporal.service'] if matrix_corporal_enabled else ['matrix-' + matrix_homeserver_implementation + '.service']) + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-mailer.service'] if matrix_mailer_enabled else []) + }} + +# Postgres is the default, except if not using internal Postgres server +matrix_ma1sd_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'sqlite' }}" +matrix_ma1sd_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_ma1sd_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'ma1sd.db', rounds=655555) | to_uuid }}" + +###################################################################### +# +# /matrix-ma1sd +# +###################################################################### + + +###################################################################### +# +# matrix-nginx-proxy +# +###################################################################### + +# By default, this playbook sets up a reverse-proxy nginx proxy server on TCP ports 80, 443 and 8448. +# This is fine if you're dedicating the whole server to Matrix. +# If that's not the case, you may wish to disable this and take care of proxying yourself. +matrix_nginx_proxy_enabled: true + +matrix_nginx_proxy_proxy_matrix_client_api_addr_with_container: "{{ 'matrix-corporal:41080' if matrix_corporal_enabled else 'matrix-nginx-proxy:12080' }}" +matrix_nginx_proxy_proxy_matrix_client_api_addr_sans_container: "{{ '127.0.0.1:41080' if matrix_corporal_enabled else '127.0.0.1:12080' }}" +matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb: |- + {{ + { + 'synapse': matrix_synapse_max_upload_size_mb, + 'dendrite': (matrix_dendrite_max_file_size_bytes / 1024 / 1024) | round, + 'conduit': (matrix_conduit_max_request_size / 1024 / 1024) | round, + }[matrix_homeserver_implementation]|int + }} + +matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_synapse_admin_api_enabled: "{{ matrix_synapse_admin_enabled or matrix_bot_matrix_registration_bot_enabled }}" + +matrix_nginx_proxy_proxy_matrix_client_redirect_root_uri_to_domain: "{{ matrix_server_fqn_element if matrix_client_element_enabled else '' }}" + +matrix_nginx_proxy_proxy_matrix_enabled: true +matrix_nginx_proxy_proxy_element_enabled: "{{ matrix_client_element_enabled }}" +matrix_nginx_proxy_proxy_hydrogen_enabled: "{{ matrix_client_hydrogen_enabled }}" +matrix_nginx_proxy_proxy_cinny_enabled: "{{ matrix_client_cinny_enabled }}" +matrix_nginx_proxy_proxy_buscarron_enabled: "{{ matrix_bot_buscarron_enabled }}" +matrix_nginx_proxy_proxy_dimension_enabled: "{{ matrix_dimension_enabled }}" +matrix_nginx_proxy_proxy_etherpad_enabled: "{{ matrix_etherpad_enabled and matrix_etherpad_mode == 'standalone' }}" +matrix_nginx_proxy_proxy_bot_go_neb_enabled: "{{ matrix_bot_go_neb_enabled }}" +matrix_nginx_proxy_proxy_jitsi_enabled: "{{ matrix_jitsi_enabled }}" +matrix_nginx_proxy_proxy_grafana_enabled: "{{ matrix_grafana_enabled }}" +matrix_nginx_proxy_proxy_sygnal_enabled: "{{ matrix_sygnal_enabled }}" +matrix_nginx_proxy_proxy_ntfy_enabled: "{{ matrix_ntfy_enabled }}" + +matrix_nginx_proxy_proxy_keycloak_enabled: "{{keycloak_enabled}}" +matrix_nginx_proxy_proxy_gitlab_enabled: "{{gitlab_enabled}}" + +matrix_nginx_proxy_proxy_matrix_corporal_api_enabled: "{{ matrix_corporal_enabled and matrix_corporal_http_api_enabled }}" +matrix_nginx_proxy_proxy_matrix_corporal_api_addr_with_container: "matrix-corporal:41081" +matrix_nginx_proxy_proxy_matrix_corporal_api_addr_sans_container: "127.0.0.1:41081" + +matrix_nginx_proxy_proxy_matrix_identity_api_enabled: "{{ matrix_ma1sd_enabled }}" +matrix_nginx_proxy_proxy_matrix_identity_api_addr_with_container: "matrix-ma1sd:{{ matrix_ma1sd_container_port }}" +matrix_nginx_proxy_proxy_matrix_identity_api_addr_sans_container: "127.0.0.1:{{ matrix_ma1sd_container_port }}" + +# By default, we do TLS termination for the Matrix Federation API (port 8448) at matrix-nginx-proxy. +# Unless this is handled there OR Synapse's federation listener port is disabled, we'll reverse-proxy. +matrix_nginx_proxy_proxy_matrix_federation_api_enabled: |- + {{ + { + 'synapse': (matrix_synapse_federation_port_enabled and not matrix_synapse_tls_federation_listener_enabled), + 'dendrite': matrix_dendrite_federation_enabled, + 'conduit': matrix_conduit_allow_federation, + }[matrix_homeserver_implementation]|bool + }} + +matrix_nginx_proxy_proxy_matrix_federation_api_addr_with_container: "matrix-nginx-proxy:12088" +matrix_nginx_proxy_proxy_matrix_federation_api_addr_sans_container: "127.0.0.1:12088" + +matrix_nginx_proxy_proxy_synapse_enabled: "{{ matrix_synapse_enabled }}" +matrix_nginx_proxy_proxy_synapse_client_api_addr_with_container: "{{ 'matrix-synapse-reverse-proxy-companion:8008' if matrix_synapse_reverse_proxy_companion_enabled else 'matrix-synapse:8008' }}" +matrix_nginx_proxy_proxy_synapse_client_api_addr_sans_container: "127.0.0.1:8008" +matrix_nginx_proxy_proxy_synapse_federation_api_addr_with_container: "{{ 'matrix-synapse-reverse-proxy-companion:8048' if matrix_synapse_reverse_proxy_companion_enabled else 'matrix-synapse:8048' }}" +matrix_nginx_proxy_proxy_synapse_federation_api_addr_sans_container: "127.0.0.1:8048" + +matrix_nginx_proxy_proxy_dendrite_enabled: "{{ matrix_dendrite_enabled }}" +matrix_nginx_proxy_proxy_dendrite_client_api_addr_with_container: "matrix-dendrite:{{ matrix_dendrite_http_bind_port | string }}" +matrix_nginx_proxy_proxy_dendrite_client_api_addr_sans_container: "127.0.0.1:{{ matrix_dendrite_http_bind_port | string }}" +matrix_nginx_proxy_proxy_dendrite_federation_api_addr_with_container: "matrix-dendrite:{{ matrix_dendrite_http_bind_port | string }}" +matrix_nginx_proxy_proxy_dendrite_federation_api_addr_sans_container: "127.0.0.1:{{ matrix_dendrite_http_bind_port | string }}" + +matrix_nginx_proxy_proxy_conduit_enabled: "{{ matrix_conduit_enabled }}" +matrix_nginx_proxy_proxy_conduit_client_api_addr_with_container: "matrix-conduit:{{ matrix_conduit_port_number|string }}" +matrix_nginx_proxy_proxy_conduit_client_api_addr_sans_container: "127.0.0.1:{{ matrix_conduit_port_number|string }}" +matrix_nginx_proxy_proxy_conduit_federation_api_addr_with_container: "matrix-conduit:{{ matrix_conduit_port_number|string }}" +matrix_nginx_proxy_proxy_conduit_federation_api_addr_sans_container: "127.0.0.1:{{ matrix_conduit_port_number|string }}" + +# When matrix-nginx-proxy is disabled, the actual port number that the vhost uses may begin to matter. +matrix_nginx_proxy_proxy_matrix_federation_port: "{{ matrix_federation_public_port }}" + +matrix_nginx_proxy_container_federation_host_bind_port: "{{ matrix_federation_public_port }}" + +matrix_nginx_proxy_proxy_matrix_user_directory_search_enabled: "{{ matrix_ma1sd_enabled }}" +matrix_nginx_proxy_proxy_matrix_user_directory_search_addr_with_container: "{{ matrix_nginx_proxy_proxy_matrix_identity_api_addr_with_container }}" +matrix_nginx_proxy_proxy_matrix_user_directory_search_addr_sans_container: "{{ matrix_nginx_proxy_proxy_matrix_identity_api_addr_sans_container }}" + +matrix_nginx_proxy_self_check_validate_certificates: "{{ false if matrix_ssl_retrieval_method == 'self-signed' else true }}" + +# OCSP stapling does not make sense when self-signed certificates are used. +# See https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1073 +# and https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/1074 +matrix_nginx_proxy_ocsp_stapling_enabled: "{{ matrix_ssl_retrieval_method == 'lets-encrypt' }}" + +matrix_nginx_proxy_systemd_wanted_services_list: | + {{ + ['matrix-' + matrix_homeserver_implementation + '.service'] + + + (matrix_synapse_webserving_workers_systemd_services_list if matrix_homeserver_implementation == 'synapse' and matrix_synapse_workers_enabled else []) + + + (['matrix-synapse-reverse-proxy-companion.service'] if matrix_synapse_reverse_proxy_companion_enabled else []) + + + (['matrix-corporal.service'] if matrix_corporal_enabled else []) + + + (['matrix-ma1sd.service'] if matrix_ma1sd_enabled else []) + + + (['matrix-client-cinny.service'] if matrix_client_cinny_enabled else []) + + + (['matrix-bot-buscarron.service'] if matrix_bot_buscarron_enabled else []) + + + (['matrix-client-element.service'] if matrix_client_element_enabled else []) + + + (['matrix-client-hydrogen.service'] if matrix_client_hydrogen_enabled else []) + + + (['matrix-grafana.service'] if matrix_grafana_enabled else []) + + + (['matrix-dimension.service'] if matrix_dimension_enabled else []) + + + (['matrix-sygnal.service'] if matrix_sygnal_enabled else []) + + + (['matrix-ntfy.service'] if matrix_ntfy_enabled else []) + + + (['matrix-jitsi.service'] if matrix_jitsi_enabled else []) + + + (['matrix-bot-go-neb.service'] if matrix_bot_go_neb_enabled else []) + + + (['matrix-etherpad.service'] if matrix_etherpad_enabled else []) + + + (['matrix-hookshot.service'] if matrix_hookshot_enabled else []) + }} + +matrix_ssl_domains_to_obtain_certificates_for: | + {{ + ([matrix_server_fqn_matrix]) + + + ([matrix_server_fqn_element] if matrix_client_element_enabled else []) + + + ([matrix_nginx_proxy_proxy_riot_compat_redirect_hostname] if matrix_nginx_proxy_proxy_riot_compat_redirect_enabled else []) + + + ([matrix_server_fqn_hydrogen] if matrix_client_hydrogen_enabled else []) + + + ([matrix_server_fqn_cinny] if matrix_client_cinny_enabled else []) + + + ([matrix_server_fqn_buscarron] if matrix_bot_buscarron_enabled else []) + + + ([matrix_server_fqn_dimension] if matrix_dimension_enabled else []) + + + ([matrix_server_fqn_etherpad] if (matrix_etherpad_enabled and matrix_etherpad_mode == 'standalone') else []) + + + ([matrix_server_fqn_bot_go_neb] if matrix_bot_go_neb_enabled else []) + + + ([matrix_server_fqn_jitsi] if matrix_jitsi_enabled else []) + + + ([matrix_server_fqn_grafana] if matrix_grafana_enabled else []) + + + ([matrix_server_fqn_sygnal] if matrix_sygnal_enabled else []) + + + ([matrix_server_fqn_ntfy] if matrix_ntfy_enabled else []) + + + ([matrix_bot_postmoogle_domain] if matrix_bot_postmoogle_enabled else []) + + + ([fqn_keycloak] if keycloak_enabled else []) + + + ([matrix_domain] if matrix_nginx_proxy_base_domain_serving_enabled else []) + + + matrix_ssl_additional_domains_to_obtain_certificates_for + }} + +matrix_ssl_architecture: "{{ + { + 'amd64': 'amd64', + 'arm32': 'arm32v6', + 'arm64': 'arm64v8', + }[matrix_architecture] +}}" + +matrix_ssl_pre_obtaining_required_service_name: "{{ 'matrix-dynamic-dns' if matrix_dynamic_dns_enabled else '' }}" + +matrix_nginx_proxy_access_log_syslog_integration_enabled: "{{ matrix_prometheus_nginxlog_exporter_enabled }}" +matrix_nginx_proxy_access_log_syslog_integration_server_port: "{{ (matrix_prometheus_nginxlog_exporter_container_hostname | string +':'+ matrix_prometheus_nginxlog_exporter_container_syslog_port | string) | default('') }}" + +###################################################################### +# +# /matrix-nginx-proxy +# +###################################################################### + + +######################################################################## +# # +# com.devture.ansible.role.postgres # +# # +######################################################################## + +# To completely disable installing Postgres, use `devture_postgres_enabled: false`. + +devture_postgres_identifier: matrix-postgres + +devture_postgres_architecture: "{{ matrix_architecture }}" + +devture_postgres_base_path: "{{ matrix_base_data_path }}/postgres" + +devture_postgres_container_network: "{{ matrix_docker_network }}" + +devture_postgres_uid: "{{ matrix_user_uid }}" +devture_postgres_gid: "{{ matrix_user_gid }}" + +devture_postgres_connection_username: matrix +devture_postgres_db_name: matrix + +devture_postgres_systemd_services_to_stop_for_maintenance_list: | + {{ + ['matrix-' + matrix_homeserver_implementation + '.service'] + }} + +devture_postgres_managed_databases_auto: | + {{ + ([{ + 'name': matrix_synapse_database_database, + 'username': matrix_synapse_database_user, + 'password': matrix_synapse_database_password, + }] if (matrix_synapse_enabled and matrix_synapse_database_host == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_dendrite_federationapi_database, + 'username': matrix_dendrite_database_user, + 'password': matrix_dendrite_database_password, + },{ + 'name': matrix_dendrite_keyserver_database, + 'username': matrix_dendrite_database_user, + 'password': matrix_dendrite_database_password, + },{ + 'name': matrix_dendrite_mediaapi_database, + 'username': matrix_dendrite_database_user, + 'password': matrix_dendrite_database_password, + },{ + 'name': matrix_dendrite_room_database, + 'username': matrix_dendrite_database_user, + 'password': matrix_dendrite_database_password, + },{ + 'name': matrix_dendrite_syncapi_database, + 'username': matrix_dendrite_database_user, + 'password': matrix_dendrite_database_password, + },{ + 'name': matrix_dendrite_userapi_database, + 'username': matrix_dendrite_database_user, + 'password': matrix_dendrite_database_password, + },{ + 'name': matrix_dendrite_pushserver_database, + 'username': matrix_dendrite_database_user, + 'password': matrix_dendrite_database_password, + },{ + 'name': matrix_dendrite_mscs_database, + 'username': matrix_dendrite_database_user, + 'password': matrix_dendrite_database_password, + }] if (matrix_dendrite_enabled and matrix_dendrite_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_ma1sd_database_name, + 'username': matrix_ma1sd_database_username, + 'password': matrix_ma1sd_database_password, + }] if (matrix_ma1sd_enabled and matrix_ma1sd_database_engine == 'postgres' and matrix_ma1sd_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_bot_matrix_reminder_bot_database_name, + 'username': matrix_bot_matrix_reminder_bot_database_username, + 'password': matrix_bot_matrix_reminder_bot_database_password, + }] if (matrix_bot_matrix_reminder_bot_enabled and matrix_bot_matrix_reminder_bot_database_engine == 'postgres' and matrix_bot_matrix_reminder_bot_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_bot_honoroit_database_name, + 'username': matrix_bot_honoroit_database_username, + 'password': matrix_bot_honoroit_database_password, + }] if (matrix_bot_honoroit_enabled and matrix_bot_honoroit_database_engine == 'postgres' and matrix_bot_honoroit_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_bot_postmoogle_database_name, + 'username': matrix_bot_postmoogle_database_username, + 'password': matrix_bot_postmoogle_database_password, + }] if (matrix_bot_postmoogle_enabled and matrix_bot_postmoogle_database_engine == 'postgres' and matrix_bot_postmoogle_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_bot_maubot_database_name, + 'username': matrix_bot_maubot_database_username, + 'password': matrix_bot_maubot_database_password, + }] if (matrix_bot_maubot_enabled and matrix_bot_maubot_database_engine == 'postgres' and matrix_bot_maubot_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_bot_buscarron_database_name, + 'username': matrix_bot_buscarron_database_username, + 'password': matrix_bot_buscarron_database_password, + }] if (matrix_bot_buscarron_enabled and matrix_bot_buscarron_database_engine == 'postgres' and matrix_bot_buscarron_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_registration_database_name, + 'username': matrix_registration_database_username, + 'password': matrix_registration_database_password, + }] if (matrix_registration_enabled and matrix_registration_database_engine == 'postgres' and matrix_registration_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_appservice_discord_database_name, + 'username': matrix_appservice_discord_database_username, + 'password': matrix_appservice_discord_database_password, + }] if (matrix_appservice_discord_enabled and matrix_appservice_discord_database_engine == 'postgres' and matrix_appservice_discord_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_appservice_slack_database_name, + 'username': matrix_appservice_slack_database_username, + 'password': matrix_appservice_slack_database_password, + }] if (matrix_appservice_slack_enabled and matrix_appservice_slack_database_engine == 'postgres' and matrix_appservice_slack_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_appservice_irc_database_name, + 'username': matrix_appservice_irc_database_username, + 'password': matrix_appservice_irc_database_password, + }] if (matrix_appservice_irc_enabled and matrix_appservice_irc_database_engine == 'postgres' and matrix_appservice_irc_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_appservice_kakaotalk_database_name, + 'username': matrix_appservice_kakaotalk_database_username, + 'password': matrix_appservice_kakaotalk_database_password, + }] if (matrix_appservice_kakaotalk_enabled and matrix_appservice_kakaotalk_database_engine == 'postgres' and matrix_appservice_kakaotalk_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_beeper_linkedin_database_name, + 'username': matrix_beeper_linkedin_database_username, + 'password': matrix_beeper_linkedin_database_password, + }] if (matrix_beeper_linkedin_enabled and matrix_beeper_linkedin_database_engine == 'postgres' and matrix_beeper_linkedin_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_go_skype_bridge_database_name, + 'username': matrix_go_skype_bridge_database_username, + 'password': matrix_go_skype_bridge_database_password, + }] if (matrix_go_skype_bridge_enabled and matrix_go_skype_bridge_database_engine == 'postgres' and matrix_go_skype_bridge_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_mautrix_facebook_database_name, + 'username': matrix_mautrix_facebook_database_username, + 'password': matrix_mautrix_facebook_database_password, + }] if (matrix_mautrix_facebook_enabled and matrix_mautrix_facebook_database_engine == 'postgres' and matrix_mautrix_facebook_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_mautrix_hangouts_database_name, + 'username': matrix_mautrix_hangouts_database_username, + 'password': matrix_mautrix_hangouts_database_password, + }] if (matrix_mautrix_hangouts_enabled and matrix_mautrix_hangouts_database_engine == 'postgres' and matrix_mautrix_hangouts_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_mautrix_googlechat_database_name, + 'username': matrix_mautrix_googlechat_database_username, + 'password': matrix_mautrix_googlechat_database_password, + }] if (matrix_mautrix_googlechat_enabled and matrix_mautrix_googlechat_database_engine == 'postgres' and matrix_mautrix_googlechat_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_mautrix_instagram_database_name, + 'username': matrix_mautrix_instagram_database_username, + 'password': matrix_mautrix_instagram_database_password, + }] if (matrix_mautrix_instagram_enabled and matrix_mautrix_instagram_database_engine == 'postgres' and matrix_mautrix_instagram_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_mautrix_signal_database_name, + 'username': matrix_mautrix_signal_database_username, + 'password': matrix_mautrix_signal_database_password, + }] if (matrix_mautrix_signal_enabled and matrix_mautrix_signal_database_engine == 'postgres' and matrix_mautrix_signal_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_mautrix_telegram_database_name, + 'username': matrix_mautrix_telegram_database_username, + 'password': matrix_mautrix_telegram_database_password, + }] if (matrix_mautrix_telegram_enabled and matrix_mautrix_telegram_database_engine == 'postgres' and matrix_mautrix_telegram_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_mautrix_twitter_database_name, + 'username': matrix_mautrix_twitter_database_username, + 'password': matrix_mautrix_twitter_database_password, + }] if (matrix_mautrix_twitter_enabled and matrix_mautrix_twitter_database_engine == 'postgres' and matrix_mautrix_twitter_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_mautrix_whatsapp_database_name, + 'username': matrix_mautrix_whatsapp_database_username, + 'password': matrix_mautrix_whatsapp_database_password, + }] if (matrix_mautrix_whatsapp_enabled and matrix_mautrix_whatsapp_database_engine == 'postgres' and matrix_mautrix_whatsapp_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_mautrix_discord_database_name, + 'username': matrix_mautrix_discord_database_username, + 'password': matrix_mautrix_discord_database_password, + }] if (matrix_mautrix_discord_enabled and matrix_mautrix_discord_database_engine == 'postgres' and matrix_mautrix_discord_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_mx_puppet_slack_database_name, + 'username': matrix_mx_puppet_slack_database_username, + 'password': matrix_mx_puppet_slack_database_password, + }] if (matrix_mx_puppet_slack_enabled and matrix_mx_puppet_slack_database_engine == 'postgres' and matrix_mx_puppet_slack_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_mx_puppet_twitter_database_name, + 'username': matrix_mx_puppet_twitter_database_username, + 'password': matrix_mx_puppet_twitter_database_password, + }] if (matrix_mx_puppet_twitter_enabled and matrix_mx_puppet_twitter_database_engine == 'postgres' and matrix_mx_puppet_twitter_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_mx_puppet_instagram_database_name, + 'username': matrix_mx_puppet_instagram_database_username, + 'password': matrix_mx_puppet_instagram_database_password, + }] if (matrix_mx_puppet_instagram_enabled and matrix_mx_puppet_instagram_database_engine == 'postgres' and matrix_mx_puppet_instagram_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_mx_puppet_discord_database_name, + 'username': matrix_mx_puppet_discord_database_username, + 'password': matrix_mx_puppet_discord_database_password, + }] if (matrix_mx_puppet_discord_enabled and matrix_mx_puppet_discord_database_engine == 'postgres' and matrix_mx_puppet_discord_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_mx_puppet_steam_database_name, + 'username': matrix_mx_puppet_steam_database_username, + 'password': matrix_mx_puppet_steam_database_password, + }] if (matrix_mx_puppet_steam_enabled and matrix_mx_puppet_steam_database_engine == 'postgres' and matrix_mx_puppet_steam_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_mx_puppet_groupme_database_name, + 'username': matrix_mx_puppet_groupme_database_username, + 'password': matrix_mx_puppet_groupme_database_password, + }] if (matrix_mx_puppet_groupme_enabled and matrix_mx_puppet_groupme_database_engine == 'postgres' and matrix_mx_puppet_groupme_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_dimension_database_name, + 'username': matrix_dimension_database_username, + 'password': matrix_dimension_database_password, + }] if (matrix_dimension_enabled and matrix_dimension_database_engine == 'postgres' and matrix_dimension_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_etherpad_database_name, + 'username': matrix_etherpad_database_username, + 'password': matrix_etherpad_database_password, + }] if (matrix_etherpad_enabled and matrix_etherpad_database_engine == 'postgres' and matrix_etherpad_database_hostname == devture_postgres_connection_hostname) else []) + + + ([{ + 'name': matrix_prometheus_postgres_exporter_database_name, + 'username': matrix_prometheus_postgres_exporter_database_username, + 'password': matrix_prometheus_postgres_exporter_database_password, + }] if (matrix_prometheus_postgres_exporter_enabled and matrix_prometheus_postgres_exporter_database_hostname == devture_postgres_connection_hostname) else []) + + }} + +######################################################################## +# # +# /com.devture.ansible.role.postgres # +# # +######################################################################## + + +######################################################################## +# # +# com.devture.ansible.role.postgres_backup # +# # +######################################################################## + +devture_postgres_backup_enabled: false + +devture_postgres_backup_identifier: matrix-postgres-backup + +devture_postgres_backup_architecture: "{{ matrix_architecture }}" + +devture_postgres_backup_base_path: "{{ matrix_base_data_path }}/postgres-backup" + +devture_postgres_backup_systemd_required_services_list: | + {{ + (['docker.service']) + + + ([(devture_postgres_identifier + '.service')] if devture_postgres_enabled else []) + }} + +devture_postgres_backup_container_network: "{{ matrix_docker_network }}" + +devture_postgres_backup_uid: "{{ matrix_user_uid }}" +devture_postgres_backup_gid: "{{ matrix_user_gid }}" + +devture_postgres_backup_connection_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +devture_postgres_backup_connection_port: "{{ devture_postgres_connection_port if devture_postgres_enabled else 5432 }}" +devture_postgres_backup_connection_username: "{{ devture_postgres_connection_username if devture_postgres_enabled else '' }}" +devture_postgres_backup_connection_password: "{{ devture_postgres_connection_password if devture_postgres_enabled else '' }}" + +devture_postgres_backup_postgres_data_path: "{{ devture_postgres_data_path if devture_postgres_enabled else '' }}" + +devture_postgres_backup_databases: "{{ devture_postgres_managed_databases | map(attribute='name') if devture_postgres_enabled else [] }}" + +######################################################################## +# # +# /com.devture.ansible.role.postgres_backup # +# # +######################################################################## + + +###################################################################### +# +# matrix-sygnal +# +###################################################################### + +# Most people don't need their own push-server, because they also need their own app to utilize it from. +matrix_sygnal_enabled: false + +# If someone instals Prometheus via the playbook, they most likely wish to monitor Sygnal. +matrix_sygnal_metrics_prometheus_enabled: "{{ matrix_prometheus_enabled }}" + +matrix_sygnal_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:6000' }}" + +###################################################################### +# +# /matrix-sygnal +# +###################################################################### + +###################################################################### +# +# matrix-ntfy +# +###################################################################### + +matrix_ntfy_enabled: false + +matrix_ntfy_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:2586' }}" + +###################################################################### +# +# /matrix-ntfy +# +###################################################################### + +###################################################################### +# +# matrix-redis +# +###################################################################### + +matrix_redis_enabled: "{{ matrix_synapse_workers_enabled }}" + +###################################################################### +# +# /matrix-redis +# +###################################################################### + +###################################################################### +# +# matrix-client-element +# +###################################################################### + +# By default, this playbook installs the Element web UI on the `matrix_server_fqn_element` domain. +# If you wish to connect to your Matrix server by other means, you may wish to disable this. +matrix_client_element_enabled: true + +matrix_client_element_container_image_self_build: "{{ matrix_architecture not in ['arm64', 'amd64'] }}" + +# Normally, matrix-nginx-proxy is enabled and nginx can reach Element over the container network. +# If matrix-nginx-proxy is not enabled, or you otherwise have a need for it, you can expose +# the Element HTTP port to the local host. +matrix_client_element_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:8765' }}" + +matrix_client_element_default_hs_url: "{{ matrix_homeserver_url }}" +matrix_client_element_default_is_url: "{{ matrix_identity_server_url }}" + +# Use Dimension if enabled, otherwise fall back to Scalar +matrix_client_element_integrations_ui_url: "{{ matrix_dimension_integrations_ui_url if matrix_dimension_enabled else 'https://scalar.vector.im/' }}" +matrix_client_element_integrations_rest_url: "{{ matrix_dimension_integrations_rest_url if matrix_dimension_enabled else 'https://scalar.vector.im/api' }}" +matrix_client_element_integrations_widgets_urls: "{{ matrix_dimension_integrations_widgets_urls if matrix_dimension_enabled else ['https://scalar.vector.im/api'] }}" +matrix_client_element_integrations_jitsi_widget_url: "{{ matrix_dimension_integrations_jitsi_widget_url if matrix_dimension_enabled else 'https://scalar.vector.im/api/widgets/jitsi.html' }}" + +matrix_client_element_self_check_validate_certificates: "{{ false if matrix_ssl_retrieval_method == 'self-signed' else true }}" + +matrix_client_element_registration_enabled: "{{ matrix_synapse_enable_registration }}" + +matrix_client_element_enable_presence_by_hs_url: | + {{ + none + if matrix_synapse_presence_enabled + else {matrix_client_element_default_hs_url: false} + }} + +matrix_client_element_welcome_user_id: ~ + +matrix_client_element_jitsi_preferredDomain: "{{ matrix_server_fqn_jitsi if matrix_jitsi_enabled else '' }}" + +###################################################################### +# +# /matrix-client-element +# +###################################################################### + +###################################################################### +# +# matrix-client-hydrogen +# +###################################################################### + +matrix_client_hydrogen_enabled: false + +matrix_client_hydrogen_container_image_self_build: "{{ matrix_architecture not in ['amd64'] }}" + +# Normally, matrix-nginx-proxy is enabled and nginx can reach Hydrogen over the container network. +# If matrix-nginx-proxy is not enabled, or you otherwise have a need for it, you can expose +# the HTTP port to the local host. +matrix_client_hydrogen_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:8768' }}" + +matrix_client_hydrogen_default_hs_url: "{{ matrix_homeserver_url }}" + +matrix_client_hydrogen_self_check_validate_certificates: "{{ false if matrix_ssl_retrieval_method == 'self-signed' else true }}" + +###################################################################### +# +# /matrix-client-hydrogen +# +###################################################################### + +###################################################################### +# +# matrix-client-cinny +# +###################################################################### + +matrix_client_cinny_enabled: false + +matrix_client_cinny_container_image_self_build: "{{ matrix_architecture not in ['arm64', 'amd64'] }}" + +# Normally, matrix-nginx-proxy is enabled and nginx can reach Cinny over the container network. +# If matrix-nginx-proxy is not enabled, or you otherwise have a need for it, you can expose +# the HTTP port to the local host. +matrix_client_cinny_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:8080' }}" + +matrix_client_cinny_default_hs_url: "{{ matrix_homeserver_url }}" + +matrix_client_cinny_self_check_validate_certificates: "{{ false if matrix_ssl_retrieval_method == 'self-signed' else true }}" + +###################################################################### +# +# /matrix-client-cinny +# +###################################################################### + +###################################################################### +# +# matrix-synapse +# +###################################################################### + +matrix_synapse_enabled: "{{ matrix_homeserver_implementation == 'synapse' }}" + +matrix_synapse_container_image_self_build: "{{ matrix_architecture not in ['arm64', 'amd64'] }}" + +# When ma1sd is enabled, we can use it to validate phone numbers. It's something that the homeserver cannot do by itself. +matrix_synapse_account_threepid_delegates_msisdn: "{{ 'http://matrix-ma1sd:' + matrix_ma1sd_container_port | string if matrix_ma1sd_enabled else '' }}" + +# For exposing the Matrix Federation API's TLS port (HTTPS) to the internet on all network interfaces. +matrix_synapse_container_federation_api_tls_host_bind_port: "{{ matrix_federation_public_port if (matrix_synapse_federation_enabled and matrix_synapse_tls_federation_listener_enabled) else '' }}" +# +# For exposing the Synapse Metrics API's port (plain HTTP) to the local host. +matrix_synapse_container_metrics_api_host_bind_port: "{{ '127.0.0.1:9100' if (matrix_synapse_metrics_enabled and not matrix_nginx_proxy_enabled) else '' }}" +# +# For exposing the Synapse Manhole port (plain HTTP) to the local host. +matrix_synapse_container_manhole_api_host_bind_port: "{{ '127.0.0.1:9000' if matrix_synapse_manhole_enabled else '' }}" +# +# For exposing the Synapse worker (and metrics) ports to the local host. +matrix_synapse_workers_container_host_bind_address: "{{ '127.0.0.1' if (matrix_synapse_workers_enabled and not matrix_nginx_proxy_enabled) else '' }}" + +matrix_synapse_database_host: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_synapse_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'synapse.db', rounds=655555) | to_uuid }}" + +matrix_synapse_macaroon_secret_key: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'synapse.mac', rounds=655555) | to_uuid }}" + +# We do not enable TLS in Synapse by default. +# TLS is handled by the matrix-nginx-proxy, which proxies the requests to Synapse. +matrix_synapse_tls_federation_listener_enabled: false +matrix_synapse_tls_certificate_path: ~ +matrix_synapse_tls_private_key_path: ~ + +matrix_synapse_federation_port_openid_resource_required: "{{ not matrix_synapse_federation_enabled and (matrix_dimension_enabled or matrix_ma1sd_enabled) }}" + +# If someone instals Prometheus via the playbook, they most likely wish to monitor Synapse. +matrix_synapse_metrics_enabled: "{{ matrix_prometheus_enabled }}" + +matrix_synapse_email_enabled: "{{ matrix_mailer_enabled }}" +matrix_synapse_email_smtp_host: "matrix-mailer" +matrix_synapse_email_smtp_port: 8025 +matrix_synapse_email_smtp_require_transport_security: false +matrix_synapse_email_notif_from: "Matrix <{{ matrix_mailer_sender_address }}>" + +# Even if TURN doesn't support TLS (it does by default), +# it doesn't hurt to try a secure connection anyway. +# +# When Let's Encrypt certificates are used (the default case), +# we don't enable `turns` endpoints, because WebRTC in Element can't talk to them. +# Learn more here: https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/1145 +matrix_synapse_turn_uris: | + {{ + [] + + + [ + 'turns:' + matrix_server_fqn_matrix + '?transport=udp', + 'turns:' + matrix_server_fqn_matrix + '?transport=tcp', + ] if matrix_coturn_enabled and matrix_coturn_tls_enabled and matrix_ssl_retrieval_method != 'lets-encrypt' else [] + + + [ + 'turn:' + matrix_server_fqn_matrix + '?transport=udp', + 'turn:' + matrix_server_fqn_matrix + '?transport=tcp', + ] if matrix_coturn_enabled else [] + }} + +matrix_synapse_turn_shared_secret: "{{ matrix_coturn_turn_static_auth_secret if matrix_coturn_enabled else '' }}" + +matrix_synapse_self_check_validate_certificates: "{{ false if matrix_ssl_retrieval_method == 'self-signed' else true }}" + +matrix_synapse_systemd_required_services_list: | + {{ + (['docker.service']) + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-goofys.service'] if matrix_s3_media_store_enabled else []) + }} + +matrix_synapse_systemd_wanted_services_list: | + {{ + (['matrix-coturn.service'] if matrix_coturn_enabled else []) + + + (['matrix-mailer.service'] if matrix_mailer_enabled else []) + }} + +# Synapse workers (used for parallel load-scaling) need Redis for IPC. +matrix_synapse_redis_enabled: "{{ matrix_redis_enabled }}" +matrix_synapse_redis_host: "{{ 'matrix-redis' if matrix_redis_enabled else '' }}" +matrix_synapse_redis_password: "{{ matrix_redis_connection_password if matrix_redis_enabled else '' }}" + +matrix_synapse_container_extra_arguments_auto: "{{ matrix_homeserver_container_extra_arguments_auto }}" +matrix_synapse_app_service_config_files_auto: "{{ matrix_homeserver_app_service_config_files_auto }}" + +###################################################################### +# +# /matrix-synapse +# +###################################################################### + +###################################################################### +# +# matrix-synapse-reverse-proxy-companion +# +###################################################################### + +matrix_synapse_reverse_proxy_companion_enabled: "{{ matrix_synapse_enabled }}" + +matrix_synapse_reverse_proxy_companion_client_api_client_max_body_size_mb: "{{ matrix_synapse_max_upload_size_mb }}" + +matrix_synapse_reverse_proxy_companion_container_client_api_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:8008' }}" +matrix_synapse_reverse_proxy_companion_container_federation_api_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:8048' }}" + +matrix_synapse_reverse_proxy_companion_synapse_workers_enabled: "{{ matrix_synapse_workers_enabled }}" +matrix_synapse_reverse_proxy_companion_synapse_workers_list: "{{ matrix_synapse_workers_enabled_list }}" +matrix_synapse_reverse_proxy_companion_synapse_generic_worker_client_server_locations: "{{ matrix_synapse_workers_generic_worker_client_server_endpoints }}" +matrix_synapse_reverse_proxy_companion_synapse_generic_worker_federation_locations: "{{ matrix_synapse_workers_generic_worker_federation_endpoints }}" +matrix_synapse_reverse_proxy_companion_synapse_stream_writer_typing_stream_worker_client_server_locations: "{{ matrix_synapse_workers_stream_writer_typing_stream_worker_client_server_endpoints }}" +matrix_synapse_reverse_proxy_companion_synapse_stream_writer_to_device_stream_worker_client_server_locations: "{{ matrix_synapse_workers_stream_writer_to_device_stream_worker_client_server_endpoints }}" +matrix_synapse_reverse_proxy_companion_synapse_stream_writer_account_data_stream_worker_client_server_locations: "{{ matrix_synapse_workers_stream_writer_account_data_stream_worker_client_server_endpoints }}" +matrix_synapse_reverse_proxy_companion_synapse_stream_writer_receipts_stream_worker_client_server_locations: "{{ matrix_synapse_workers_stream_writer_receipts_stream_worker_client_server_endpoints }}" +matrix_synapse_reverse_proxy_companion_synapse_stream_writer_presence_stream_worker_client_server_locations: "{{ matrix_synapse_workers_stream_writer_presence_stream_worker_client_server_endpoints }}" +matrix_synapse_reverse_proxy_companion_synapse_media_repository_locations: "{{matrix_synapse_workers_media_repository_endpoints|default([]) }}" +matrix_synapse_reverse_proxy_companion_synapse_user_dir_locations: "{{ matrix_synapse_workers_user_dir_worker_client_server_endpoints|default([]) }}" + +matrix_synapse_reverse_proxy_companion_access_log_syslog_integration_enabled: "{{ matrix_prometheus_nginxlog_exporter_enabled }}" +matrix_synapse_reverse_proxy_companion_access_log_syslog_integration_server_port: "{{ (matrix_prometheus_nginxlog_exporter_container_hostname | string +':'+ matrix_prometheus_nginxlog_exporter_container_syslog_port | string) | default('') }}" + +###################################################################### +# +# /matrix-synapse-reverse-proxy-companion +# +###################################################################### + +###################################################################### +# +# matrix-synapse-admin +# +###################################################################### + +matrix_synapse_admin_enabled: false + +# Normally, matrix-nginx-proxy is enabled and nginx can reach Synapse Admin over the container network. +# If matrix-nginx-proxy is not enabled, or you otherwise have a need for it, you can expose +# Synapse Admin's HTTP port to the local host. +matrix_synapse_admin_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:8766' }}" + +matrix_synapse_admin_container_image_self_build: "{{ matrix_architecture not in ['arm64', 'amd64'] }}" + +###################################################################### +# +# /matrix-synapse-admin +# +###################################################################### + +###################################################################### +# +# matrix-prometheus-node-exporter +# +###################################################################### + +matrix_prometheus_node_exporter_enabled: false + +###################################################################### +# +# /matrix-prometheus-node-exporter +# +###################################################################### + +###################################################################### +# +# matrix-prometheus-nginxlog-exporter +# +###################################################################### + +matrix_prometheus_nginxlog_exporter_enabled: false + +###################################################################### +# +# /matrix-prometheus-nginxlog-exporter +# +###################################################################### + +###################################################################### +# +# matrix-prometheus +# +###################################################################### + +matrix_prometheus_enabled: false + +# Normally, matrix-nginx-proxy is enabled and nginx can reach Prometheus over the container network. +# If matrix-nginx-proxy is not enabled, or you otherwise have a need for it, you can expose +# Prometheus' HTTP port to the local host. +matrix_prometheus_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:9090' }}" + +matrix_prometheus_scraper_synapse_enabled: "{{ matrix_synapse_enabled and matrix_synapse_metrics_enabled }}" +matrix_prometheus_scraper_synapse_targets: ['matrix-synapse:{{ matrix_synapse_metrics_port }}'] +matrix_prometheus_scraper_synapse_workers_enabled_list: "{{ matrix_synapse_workers_enabled_list }}" +matrix_prometheus_scraper_synapse_rules_synapse_tag: "{{ matrix_synapse_docker_image_tag }}" + +matrix_prometheus_scraper_node_enabled: "{{ matrix_prometheus_node_exporter_enabled }}" +matrix_prometheus_scraper_node_targets: "{{ ['matrix-prometheus-node-exporter:9100'] if matrix_prometheus_node_exporter_enabled else [] }}" + +matrix_prometheus_scraper_postgres_enabled: "{{ matrix_prometheus_postgres_exporter_enabled }}" +matrix_prometheus_scraper_postgres_targets: "{{ ['matrix-prometheus-postgres-exporter:'+ matrix_prometheus_postgres_exporter_port | string] if matrix_prometheus_scraper_postgres_enabled else [] }}" + +matrix_prometheus_scraper_hookshot_enabled: "{{ matrix_hookshot_metrics_enabled|default(false) }}" +matrix_prometheus_scraper_hookshot_targets: "{{ [matrix_hookshot_container_url | string +':'+ matrix_hookshot_metrics_port | string] if matrix_hookshot_metrics_enabled else [] }}" + +matrix_prometheus_scraper_nginxlog_enabled: "{{ matrix_prometheus_nginxlog_exporter_enabled }}" +matrix_prometheus_scraper_nginxlog_server_port: "{{ (matrix_prometheus_nginxlog_exporter_container_hostname | string +':'+ matrix_prometheus_nginxlog_exporter_container_metrics_port | string) +| default('') }}" + +###################################################################### +# +# /matrix-prometheus +# +###################################################################### + +###################################################################### +# +# matrix-prometheus-postgres-exporter +# +###################################################################### + +matrix_prometheus_postgres_exporter_enabled: false +matrix_prometheus_postgres_exporter_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_prometheus_postgres_exporter_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'prometheus.pg.db', rounds=655555) | to_uuid }}" + +matrix_prometheus_postgres_exporter_systemd_required_services_list: | + {{ + ['docker.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + }} + +###################################################################### +# +# /matrix-prometheus-postgres-exporter +# +###################################################################### + +###################################################################### +# +# matrix-grafana +# +###################################################################### + +matrix_grafana_enabled: false + +# Normally, matrix-nginx-proxy is enabled and nginx can reach Grafana over the container network. +# If matrix-nginx-proxy is not enabled, or you otherwise have a need for it, you can expose +# Grafana's HTTP port to the local host. +matrix_grafana_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:3000' }}" + +matrix_grafana_dashboard_download_urls: | + {{ + (matrix_synapse_grafana_dashboard_urls if matrix_homeserver_implementation == 'synapse' and matrix_synapse_metrics_enabled else []) + + + (matrix_prometheus_node_exporter_dashboard_urls if matrix_prometheus_node_exporter_enabled else []) + + + (matrix_prometheus_postgres_exporter_dashboard_urls if matrix_prometheus_postgres_exporter_enabled else []) + + + (matrix_prometheus_nginxlog_exporter_dashboard_urls if matrix_prometheus_nginxlog_exporter_enabled else []) + }} + +matrix_grafana_default_home_dashboard_path: |- + {{ + { + 'synapse': ('/etc/grafana/dashboards/synapse.json' if matrix_synapse_metrics_enabled else '/etc/grafana/dashboards/node-exporter-full.json'), + 'dendrite': '/etc/grafana/dashboards/node-exporter-full.json', + 'conduit': '/etc/grafana/dashboards/node-exporter-full.json', + }[matrix_homeserver_implementation] + }} + +matrix_grafana_systemd_wanted_services_list: | + {{ + [] + + + (['matrix-prometheus-postgres-exporter.service'] if matrix_prometheus_postgres_exporter_enabled else []) + }} + +###################################################################### +# +# /matrix-grafana +# +###################################################################### + +###################################################################### +# +# matrix-registration +# +###################################################################### + +matrix_registration_enabled: false + +# Normally, matrix-nginx-proxy is enabled and nginx can reach matrix-registration over the container network. +# If matrix-nginx-proxy is not enabled, or you otherwise have a need for it, you can expose +# matrix-registration's HTTP port to the local host. +matrix_registration_container_http_host_bind_port: "{{ '' if matrix_nginx_proxy_enabled else '127.0.0.1:8767' }}" + +matrix_registration_riot_instance: "{{ ('https://' + matrix_server_fqn_element) if matrix_client_element_enabled else 'https://riot.im/app/' }}" + +matrix_registration_shared_secret: |- + {{ + { + 'synapse': matrix_synapse_registration_shared_secret, + 'dendrite': matrix_dendrite_client_api_registration_shared_secret, + 'conduit': '', + }[matrix_homeserver_implementation] + }} + +matrix_registration_server_location: "{{ matrix_homeserver_container_url }}" + +matrix_registration_api_validate_certs: "{{ false if matrix_ssl_retrieval_method == 'self-signed' else true }}" + +matrix_registration_container_image_self_build: "{{ matrix_architecture != 'amd64' }}" + +matrix_registration_systemd_required_services_list: | + {{ + ['docker.service'] + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + }} + +# Postgres is the default, except if not using internal Postgres server +matrix_registration_database_engine: "{{ 'postgres' if devture_postgres_enabled else 'sqlite' }}" +matrix_registration_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" +matrix_registration_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'mx.registr.db', rounds=655555) | to_uuid }}" + +###################################################################### +# +# /matrix-registration +# +###################################################################### + + +###################################################################### +# +# matrix-dendrite +# +###################################################################### + +matrix_dendrite_enabled: "{{ matrix_homeserver_implementation == 'dendrite' }}" + +# Normally, matrix-nginx-proxy is enabled and nginx can reach Dendrite over the container network. +# If matrix-nginx-proxy is not enabled, or you otherwise have a need for it, +# you can expose Dendrite's ports to the host. +# +# For exposing Dendrite's plain HTTP server to the local host. +matrix_dendrite_container_http_host_bind_address: "{{ '' if matrix_nginx_proxy_enabled else ('127.0.0.1:' + matrix_dendrite_http_bind_port | string) }}" +# +# For exposing Dendrite's HTTPS server to the local host. +matrix_dendrite_container_https_host_bind_address: "{{ '' if matrix_nginx_proxy_enabled or not matrix_dendrite_https_bind_port else ('127.0.0.1:' + matrix_dendrite_https_bind_port | string) }}" + +matrix_dendrite_sync_api_real_ip_header: "{{ 'X-Forwarded-For' if matrix_nginx_proxy_enabled else '' }}" + +matrix_dendrite_client_api_registration_shared_secret: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'dendrite.rss', rounds=655555) | to_uuid }}" + +matrix_dendrite_database_hostname: "{{ devture_postgres_connection_hostname if devture_postgres_enabled else '' }}" + +matrix_dendrite_database_password: "{{ '%s' | format(matrix_homeserver_generic_secret_key) | password_hash('sha512', 'dendrite.db', rounds=655555) | to_uuid }}" + +# Even if TURN doesn't support TLS (it does by default), +# it doesn't hurt to try a secure connection anyway. +matrix_dendrite_client_api_turn_uris: | + {{ + [ + 'turns:' + matrix_server_fqn_matrix + '?transport=udp', + 'turns:' + matrix_server_fqn_matrix + '?transport=tcp', + 'turn:' + matrix_server_fqn_matrix + '?transport=udp', + 'turn:' + matrix_server_fqn_matrix + '?transport=tcp', + ] + if matrix_coturn_enabled + else [] + }} + +matrix_dendrite_client_api_turn_shared_secret: "{{ matrix_coturn_turn_static_auth_secret if matrix_coturn_enabled else '' }}" + +matrix_dendrite_disable_tls_validation: "{{ true if matrix_ssl_retrieval_method == 'self-signed' else false }}" + +matrix_dendrite_self_check_validate_certificates: "{{ false if matrix_ssl_retrieval_method == 'self-signed' else true }}" + +matrix_dendrite_trusted_id_servers: "{{ [matrix_server_fqn_matrix] if matrix_ma1sd_enabled else ['matrix.org', 'vector.im'] }}" + +matrix_dendrite_systemd_required_services_list: | + {{ + (['docker.service']) + + + ([devture_postgres_identifier ~ '.service'] if devture_postgres_enabled else []) + + + (['matrix-goofys.service'] if matrix_s3_media_store_enabled else []) + }} + +matrix_dendrite_systemd_wanted_services_list: | + {{ + (['matrix-coturn.service'] if matrix_coturn_enabled else []) + }} + +matrix_dendrite_container_extra_arguments_auto: "{{ matrix_homeserver_container_extra_arguments_auto }}" +matrix_dendrite_app_service_config_files_auto: "{{ matrix_homeserver_app_service_config_files_auto }}" + +###################################################################### +# +# /matrix-dendrite +# +###################################################################### + +###################################################################### +# +# matrix-conduit +# +###################################################################### + +matrix_conduit_enabled: "{{ matrix_homeserver_implementation == 'conduit' }}" + +matrix_conduit_systemd_required_services_list: | + {{ + (['docker.service']) + }} + + +###################################################################### +# +# /matrix-conduit +# +###################################################################### + + +###################################################################### +# +# matrix-user-creator +# +###################################################################### + +matrix_user_creator_users_auto: | + {{ + ([{ + 'username': matrix_bot_matrix_reminder_bot_matrix_user_id_localpart, + 'initial_password': matrix_bot_matrix_reminder_bot_matrix_user_password, + 'initial_type': 'bot', + }] if matrix_bot_matrix_reminder_bot_enabled else []) + + + ([{ + 'username': matrix_bot_honoroit_login, + 'initial_password': matrix_bot_honoroit_password, + 'initial_type': 'bot', + }] if matrix_bot_honoroit_enabled else []) + + + ([{ + 'username': matrix_bot_postmoogle_login, + 'initial_password': matrix_bot_postmoogle_password, + 'initial_type': 'bot', + }] if matrix_bot_postmoogle_enabled else []) + + + ([{ + 'username': matrix_bot_buscarron_login, + 'initial_password': matrix_bot_buscarron_password, + 'initial_type': 'bot', + }] if matrix_bot_buscarron_enabled else []) + }} + +###################################################################### +# +# /matrix-user-creator +# +###################################################################### + + + diff --git a/inventory/.gitkeep b/inventory/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/inventory/scripts/ansible-all-hosts.sh b/inventory/scripts/ansible-all-hosts.sh new file mode 100644 index 0000000..3b611ab --- /dev/null +++ b/inventory/scripts/ansible-all-hosts.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +# +# Run the playbook on multiple hosts with different credentials with this script +# It defaults to ansible tags "setup-all,start". You can pass alternative tags +# to this script as arguments, e.g. +# +# ./inventory/scripts/ansible-all-hosts.sh self-check +# + +# set playbook root path +root=$(dirname "$(readlink -f "$0")")/../.. + +# set default tags or get from first argument if any +tags="${1:-setup-all,start}" + +# init password array +declare -A pws + +# capture passwords for all hosts +for host in "$root"/inventory/*.yml; do + read -rp "sudo password for $(basename "$host"): " -s pw + pws[$host]="$pw" + echo +done + +# run ansible on all captured passwords/hosts +for host in "${!pws[@]}"; do + ansible-playbook "$root"/setup.yml \ + --inventory-file "$host" \ + --extra-vars "ansible_become_pass=${pws[$host]}" \ + --tags="$tags" +done diff --git a/inventory/scripts/jitsi-generate-passwords.sh b/inventory/scripts/jitsi-generate-passwords.sh new file mode 100644 index 0000000..f24a3fb --- /dev/null +++ b/inventory/scripts/jitsi-generate-passwords.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# This is a bash script for generating strong passwords for the Jitsi role in this ansible project: +# https://github.com/spantaleev/matrix-docker-ansible-deploy + +function generatePassword() { + openssl rand -hex 16 +} + +echo "# If this script fails, it's likely because you don't have the openssl tool installed." +echo "# Install it before using this script, or simply create your own passwords manually." + +echo "" + +JICOFO_AUTH_PASSWORD=$(generatePassword) +JVB_AUTH_PASSWORD=$(generatePassword) +JIBRI_RECORDER_PASSWORD=$(generatePassword) +JIBRI_XMPP_PASSWORD=$(generatePassword) + +echo "# Paste these variables into your inventory/host_vars/matrix.DOMAIN/vars.yml file:" +echo "" +echo "matrix_jitsi_jicofo_auth_password: $JICOFO_AUTH_PASSWORD" +echo "matrix_jitsi_jvb_auth_password: $JVB_AUTH_PASSWORD" +echo "matrix_jitsi_jibri_recorder_password: $JIBRI_RECORDER_PASSWORD" +echo "matrix_jitsi_jibri_xmpp_password: $JIBRI_XMPP_PASSWORD" diff --git a/playbooks/jitsi_jvb.yml b/playbooks/jitsi_jvb.yml new file mode 100644 index 0000000..c4aac2e --- /dev/null +++ b/playbooks/jitsi_jvb.yml @@ -0,0 +1,12 @@ +--- +- name: "Set up additional Jitsi JVB servers" + hosts: "jitsi_jvb_servers" + become: true + + roles: + - role: galaxy/com.devture.ansible.role.playbook_help + - role: galaxy/com.devture.ansible.role.systemd_docker_base + + - matrix/matrix-base + - matrix/matrix-jitsi + - matrix/matrix-common-after diff --git a/playbooks/matrix.yml b/playbooks/matrix.yml new file mode 100644 index 0000000..d493db2 --- /dev/null +++ b/playbooks/matrix.yml @@ -0,0 +1,144 @@ +--- +- name: "Set up a All servers" + hosts: "{{ target_all if target_all is defined else 'all' }}" + become: true + + roles: + # Most of the roles below are not distributed with the playbook, but downloaded separately using `ansible-galaxy` via the `make roles` command (see `Makefile`). + - role: galaxy/com.devture.ansible.role.playbook_help + + - role: galaxy/com.devture.ansible.role.systemd_docker_base + + - role: matrix/matrix_playbook_migration + + - when: matrix_playbook_docker_installation_enabled | bool + role: galaxy/geerlingguy.docker + vars: + docker_install_compose: false + tags: + - setup-docker + - setup-all + + - when: devture_docker_sdk_for_python_installation_enabled | bool + role: galaxy/com.devture.ansible.role.docker_sdk_for_python + tags: + - setup-docker + - setup-all + + - when: devture_timesync_installation_enabled | bool + role: galaxy/com.devture.ansible.role.timesync + tags: + - setup-timesync + - setup-all + + +- name: "Set up a Keycloak servers" + hosts: "{{ target_keycloak if target_keycloak is defined else 'keycloak_servers' }}" + become: true + roles: + - keycloak/keycloak_base + tags: + - setup-all + - install-all + + +- name: "Set up a Matrix server" + hosts: "{{ target if target is defined else 'matrix_servers' }}" + become: true + + roles: + # Most of the roles below are not distributed with the playbook, but downloaded separately using `ansible-galaxy` via the `make roles` command (see `Makefile`). + - role: galaxy/com.devture.ansible.role.playbook_help + + - role: galaxy/com.devture.ansible.role.systemd_docker_base + + - role: matrix/matrix_playbook_migration + + + - matrix/matrix-base + - matrix/matrix-dynamic-dns + - matrix/matrix-mailer + + - role: galaxy/com.devture.ansible.role.postgres + + - matrix/matrix-redis + - matrix/matrix-corporal + - matrix/matrix-bridge-appservice-discord + - matrix/matrix-bridge-appservice-slack + - matrix/matrix-bridge-appservice-webhooks + - matrix/matrix-bridge-appservice-irc + - matrix/matrix-bridge-appservice-kakaotalk + - matrix/matrix-bridge-beeper-linkedin + - matrix/matrix-bridge-go-skype-bridge + - matrix/matrix-bridge-mautrix-facebook + - matrix/matrix-bridge-mautrix-twitter + - matrix/matrix-bridge-mautrix-hangouts + - matrix/matrix-bridge-mautrix-googlechat + - matrix/matrix-bridge-mautrix-instagram + - matrix/matrix-bridge-mautrix-signal + - matrix/matrix-bridge-mautrix-telegram + - matrix/matrix-bridge-mautrix-whatsapp + - matrix/matrix-bridge-mautrix-discord + - matrix/matrix-bridge-mx-puppet-discord + - matrix/matrix-bridge-mx-puppet-groupme + - matrix/matrix-bridge-mx-puppet-steam + - matrix/matrix-bridge-mx-puppet-slack + - matrix/matrix-bridge-mx-puppet-twitter + - matrix/matrix-bridge-mx-puppet-instagram + - matrix/matrix-bridge-sms + - matrix/matrix-bridge-heisenbridge + - matrix/matrix-bridge-hookshot + - matrix/matrix-bot-matrix-reminder-bot + - matrix/matrix-bot-matrix-registration-bot + - matrix/matrix-bot-maubot + - matrix/matrix-bot-buscarron + - matrix/matrix-bot-honoroit + - matrix/matrix-bot-postmoogle + - matrix/matrix-bot-go-neb + - matrix/matrix-bot-mjolnir + - matrix/matrix-cactus-comments + - matrix/matrix-synapse + - matrix/matrix-synapse-reverse-proxy-companion + - matrix/matrix-dendrite + - matrix/matrix-conduit + - matrix/matrix-synapse-admin + - matrix/matrix-prometheus-node-exporter + - matrix/matrix-prometheus-postgres-exporter + - matrix/matrix-prometheus-nginxlog-exporter + - matrix/matrix-prometheus + - matrix/matrix-grafana + - matrix/matrix-registration + - matrix/matrix-client-element + - matrix/matrix-client-hydrogen + - matrix/matrix-client-cinny + - matrix/matrix-jitsi + - matrix/matrix-ldap-registration-proxy + - matrix/matrix-ma1sd + - matrix/matrix-dimension + - matrix/matrix-etherpad + - matrix/matrix-email2matrix + - matrix/matrix-sygnal + - matrix/matrix-ntfy + - matrix/matrix-nginx-proxy + - matrix/matrix-coturn + - matrix/matrix-aux + + - role: galaxy/com.devture.ansible.role.postgres_backup + + - matrix/matrix-backup-borg + + - matrix/matrix-user-creator + - matrix/matrix-common-after + + - when: devture_systemd_service_manager_enabled | bool + role: galaxy/com.devture.ansible.role.systemd_service_manager + + # This is pretty much last, because we want it to better serve as a "last known good configuration". + # See: https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/2217#issuecomment-1301487601 + - when: devture_playbook_state_preserver_enabled | bool + role: galaxy/com.devture.ansible.role.playbook_state_preserver + tags: + - setup-all + - install-all + + - role: galaxy/com.devture.ansible.role.playbook_runtime_messages diff --git a/requirements.yml b/requirements.yml new file mode 100644 index 0000000..df47110 --- /dev/null +++ b/requirements.yml @@ -0,0 +1,36 @@ +--- +roles: + - src: geerlingguy.docker + version: 6.0.3 + + - src: git+https://github.com/devture/com.devture.ansible.role.docker_sdk_for_python.git + version: 6ba3be490b6f4c6f35ea109aeb8e533fa231b3a5 + + - src: git+https://github.com/devture/com.devture.ansible.role.playbook_help.git + version: c1f40e82b4d6b072b6f0e885239322bdaaaf554f + + - src: git+https://github.com/devture/com.devture.ansible.role.systemd_docker_base.git + version: 327d2e17f5189ac2480d6012f58cf64a2b46efba + + - src: git+https://github.com/devture/com.devture.ansible.role.timesync.git + version: 660f384f176a9ea3b5cc702bde39e7dc10bf6186 + + - src: git+https://github.com/devture/com.devture.ansible.role.playbook_state_preserver.git + version: ff2fd42e1c1a9e28e3312bbd725395f9c2fc7f16 + + - src: git+https://github.com/devture/com.devture.ansible.role.postgres.git + version: e75973e3a4edc12dfc3e880e43b12ebecbf82c61 + + - src: git+https://github.com/devture/com.devture.ansible.role.postgres_backup.git + version: 77b1f9ae1aafa31c9078178c1036bf744c99d08b + + - src: git+https://github.com/devture/com.devture.ansible.role.systemd_service_manager.git + version: 6ccb88ac5fc27e1e70afcd48278ade4b564a9096 + + - src: git+https://github.com/devture/com.devture.ansible.role.playbook_runtime_messages.git + version: 9b4b088c62b528b73a9a7c93d3109b091dd42ec6 + +collections: + - name: community.general + version: "7.2.1" + source: https://galaxy.ansible.com diff --git a/roles/base/docker/tasks/main.yml b/roles/base/docker/tasks/main.yml new file mode 100644 index 0000000..4e62e8b --- /dev/null +++ b/roles/base/docker/tasks/main.yml @@ -0,0 +1,34 @@ + +- name: Create a docker configuration directory if it does not exist + ansible.builtin.file: + path: /etc/docker/ + state: directory + mode: '0644' + +- name: Manage /etc/docker/daemon.json + template: + src: docker-daemon.json.j2 + dest: /etc/docker/daemon.json + mode: '0644' + register: _cfg_daemon + +- name: Ensure docker deamon is being restarted and running + when: + - (_cfg_daemon is changed) + block: + - name: Reload and restart docker systemctl service + ansible.builtin.systemd: + state: restarted + name: docker + + - name: Pause while Docker restarts + shell: sleep 10 + changed_when: false + + - name: Wait for docker + command: /usr/bin/docker images + register: docker_ready + retries: 10 + delay: 5 + until: docker_ready.rc == 0 + changed_when: false \ No newline at end of file diff --git a/roles/base/docker/templates/docker-daemon.json.j2 b/roles/base/docker/templates/docker-daemon.json.j2 new file mode 100644 index 0000000..68fabf2 --- /dev/null +++ b/roles/base/docker/templates/docker-daemon.json.j2 @@ -0,0 +1,6 @@ +{ +{% if container_registry_mirror != "" %} + "registry-mirrors": ["{{ container_registry_mirror }}"] +{% endif %} + +} diff --git a/roles/gitlab/gitlab_drbd_storage/README.md b/roles/gitlab/gitlab_drbd_storage/README.md new file mode 100644 index 0000000..225dd44 --- /dev/null +++ b/roles/gitlab/gitlab_drbd_storage/README.md @@ -0,0 +1,38 @@ +Role Name +========= + +A brief description of the role goes here. + +Requirements +------------ + +Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. + +Role Variables +-------------- + +A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. + +Dependencies +------------ + +A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. + +Example Playbook +---------------- + +Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: + + - hosts: servers + roles: + - { role: username.rolename, x: 42 } + +License +------- + +BSD + +Author Information +------------------ + +An optional section for the role authors to include contact information, or a website (HTML is not allowed). diff --git a/roles/gitlab/gitlab_drbd_storage/defaults/main.yml b/roles/gitlab/gitlab_drbd_storage/defaults/main.yml new file mode 100644 index 0000000..9dc1087 --- /dev/null +++ b/roles/gitlab/gitlab_drbd_storage/defaults/main.yml @@ -0,0 +1,2 @@ +--- +# defaults file for gitlab_storage diff --git a/roles/gitlab/gitlab_drbd_storage/handlers/main.yml b/roles/gitlab/gitlab_drbd_storage/handlers/main.yml new file mode 100644 index 0000000..c987fc6 --- /dev/null +++ b/roles/gitlab/gitlab_drbd_storage/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for gitlab_storage diff --git a/roles/gitlab/gitlab_drbd_storage/meta/main.yml b/roles/gitlab/gitlab_drbd_storage/meta/main.yml new file mode 100644 index 0000000..24df72e --- /dev/null +++ b/roles/gitlab/gitlab_drbd_storage/meta/main.yml @@ -0,0 +1,52 @@ +galaxy_info: + author: Amir Baleghi + description: Gitlab High availability storage setup Active/Passive mode + company: Eberhard Karl University of Tübingen + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Choose a valid license ID from https://spdx.org - some suggested licenses: + # - BSD-3-Clause (default) + # - MIT + # - GPL-2.0-or-later + # - GPL-3.0-only + # - Apache-2.0 + # - CC-BY-4.0 + license: GPL-3.0-only + + min_ansible_version: 2.14.6 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. diff --git a/roles/gitlab/gitlab_drbd_storage/tasks/drbd_presetup.yml b/roles/gitlab/gitlab_drbd_storage/tasks/drbd_presetup.yml new file mode 100644 index 0000000..2213a94 --- /dev/null +++ b/roles/gitlab/gitlab_drbd_storage/tasks/drbd_presetup.yml @@ -0,0 +1,7 @@ + +- name: Add IP address of all hosts to all hosts of DRBD servers + lineinfile: + dest: /etc/hosts + line: "{{ hostvars[item].ansible_host }} {{ hostvars[item].inventory_hostname }} {{ hostvars[item].inventory_hostname_short }}" + state: present + with_items: "{{ play_hosts }}" \ No newline at end of file diff --git a/roles/gitlab/gitlab_drbd_storage/tasks/drbd_setup.yml b/roles/gitlab/gitlab_drbd_storage/tasks/drbd_setup.yml new file mode 100644 index 0000000..3e09fb7 --- /dev/null +++ b/roles/gitlab/gitlab_drbd_storage/tasks/drbd_setup.yml @@ -0,0 +1,277 @@ + + +- name: Ensure of preconfinguration of DRBD with Pacemaker + block: + - ansible.builtin.include_tasks: "{{ role_path }}/tasks/drbd_presetup.yml" + tags: + - setup-all + - install-all + + +- name: Add linbit-drbd9 stable repository from PPA and install its signing key on Ubuntu target + ansible.builtin.apt_repository: + repo: ppa:linbit/linbit-drbd9-stack + tags: + - setup-all + - install-all + +- name: Install the Pacemaker & DRBD9 packages + ansible.builtin.apt: + pkg: + - drbd-utils=9.25.0-1ppa1~jammy1 + - drbd-dkms=9.2.5-1ppa1~jammy1 + - pacemaker=2.1.2-1ubuntu3.1 + - pcs=0.10.11-2ubuntu3 + - resource-agents=1:4.7.0-1ubuntu7.2 + tags: + - setup-all + - install-all + + +- name: Ensure DRBD configuration is configured + ansible.builtin.template: + src: "{{ role_path }}/templates/drbd.conf.j2" + dest: "/etc/drbd.conf" + mode: 0644 + tags: + - new_storage + +- name: NFS server should stop for new_storage + ansible.builtin.systemd: + name: nfs-kernel-server.service + state: stopped + enabled: true + register: NFS_service_status + when: inventory_hostname in groups["drbd_primary"] + tags: + - new_storage + +- name: Pacemaker cluster stop for new storage configuration + shell: "pcs cluster stop --all" + register: pcs_stop_new_storage + when: inventory_hostname in groups["drbd_primary"] + ignore_errors: true + tags: + - new_storage + + + +- name: Drbdadm create-md for first time + shell: "drbdadm create-md r0_gitlab --force" + register: drbdadm_create_md + tags: + - new_storage + + +- name: Drbdadm up for first time + shell: " drbdadm up r0_gitlab" + register: drbdadm_up_msg + tags: + - new_storage + + +- name: drbdsetup new-current-uuid for first time + shell: "sudo drbdsetup new-current-uuid --clear-bitmap 1" + register: drbdsetup_new_storage + when: inventory_hostname in groups["drbd_primary"] + tags: + - new_storage + +- name: drbdadm primary for first time + shell: "sudo drbdadm primary r0_gitlab" + register: drbdadm_primary_server_msg + when: inventory_hostname in groups["drbd_primary"] + tags: + - new_storage + +- name: Create a xfs filesystem on '/dev/drbd1' + community.general.filesystem: + fstype: xfs + dev: /dev/drbd1 + when: inventory_hostname in groups["drbd_primary"] + tags: + - new_storage + +- name: Drbdadm status + shell: " drbdadm status r0_gitlab" + register: drbdadm_status_msg + tags: + - new_storage + +- name: Drbdadm down + shell: " drbdadm down r0_gitlab" + register: drbdadm_down_msg + tags: + - new_storage + + +- name: Change password of user hacluster + user: + name: hacluster + password: "{{ hacluster_password |password_hash('sha512') }}" + tags: + - setup-all + - install-all + +- ansible.builtin.set_fact: + pacemaker_cluster_list: "{{hostvars[groups['drbd_primary'][0]]['inventory_hostname']}} {% for item in groups['drbd_secondary'] %} {{hostvars[item]['inventory_hostname']}} {% endfor %}" + tags: + - setup-all + - install-all + +- name: Pcs host auth + shell: "pcs host auth {{pacemaker_cluster_list}} -u hacluster -p {{hacluster_password}} " + register: pcs_host_auth_msg + when: inventory_hostname in groups["drbd_primary"] + tags: + - setup-all + - install-all + +- name: Pcs cluster setup ha_cluster + shell: "pcs cluster setup ha_cluster {{pacemaker_cluster_list}} --force " + register: pcs_cluster_setup_msg + when: inventory_hostname in groups["drbd_primary"] + tags: + - setup-all + - install-all + +- name: Pcs cluster start + shell: "pcs cluster start --all " + register: pcs_cluster_start_msg + when: inventory_hostname in groups["drbd_primary"] + tags: + - setup-all + - install-all + +- name: Pcs stonith Set Disable + shell: "pcs property set stonith-enabled=false" + register: pcs_property_set_stonith_msg + when: inventory_hostname in groups["drbd_primary"] + tags: + - setup-all + - install-all + +- name: Pcs no-quorum-policy Set Ignore + shell: "pcs property set no-quorum-policy=ignore" + register: pcs_property_set_quorum_policy_msg + when: inventory_hostname in groups["drbd_primary"] + tags: + - setup-all + - install-all + + +- name: Pcs Resource Create Gitlabdata + shell: "pcs resource create Gitlabdata ocf:linbit:drbd drbd_resource=r0_gitlab op monitor interval=30s " + register: pcs_resource_create_msg + when: inventory_hostname in groups["drbd_primary"] + tags: + - setup-all + - install-all + +- name: Pcs Resource promotable Gitlabdata + shell: "pcs resource promotable Gitlabdata master-max=1 master-node-max=1 clone-max=2 clone-node-max=1 notify=true" + register: pcs_resource_promotable_msg + when: inventory_hostname in groups["drbd_primary"] + tags: + - setup-all + - install-all + +- name: Pcs constraint location Gitlabdata-clone + shell: "pcs constraint location Gitlabdata-clone prefers {{hostvars[groups['drbd_primary'][0]]['inventory_hostname']}}" + register: pcs_resource_promotable_msg + when: inventory_hostname in groups["drbd_primary"] + tags: + - setup-all + - install-all + + + + + +- name: Pcs resource create GitlabFS Filesystem + shell: "pcs resource create GitlabFS Filesystem device='/dev/drbd1' directory='{{nfs_directory}}' fstype='xfs' " + register: pcs_resource_create_GitlabFS_msg + when: inventory_hostname in groups["drbd_primary"] + tags: + - setup-all + - install-all + +- name: Pcs constraint colocation + shell: "pcs constraint colocation add GitlabFS with Promoted Gitlabdata-clone " + register: pcs_resource_create_GitlabFS_msg + when: inventory_hostname in groups["drbd_primary"] + tags: + - setup-all + - install-all + +- name: Pcs constraint ordring GitlabFS with Gitlabdata-clone + shell: "sudo pcs constraint order \ + promote Gitlabdata-clone then start GitlabFS" + register: pcs_resource_promotable_msg + when: inventory_hostname in groups["drbd_primary"] + tags: + - setup-all + - install-all + + + +- name: Waiting for /dev/drbd1 become ready + ansible.builtin.wait_for: + path: /dev/drbd1 + state: present + timeout: 60 + msg: Timeout to find file /dev/drbd1 + when: inventory_hostname in groups["drbd_primary"] + tags: + - setup-all + - install-all + + + +- name: Pcs resource create NFS Service source + shell: "pcs resource create NFSService systemd:nfs-kernel-server op monitor interval=1min" + register: pcs_resource_create_NFSService_msg + when: inventory_hostname in groups["drbd_primary"] + tags: + - setup-all + - install-all + +- name: Pcs constraint colocation NFS Service with GitlabFS + shell: "sudo pcs constraint colocation add NFSService with GitlabFS" + register: pcs_resource_create_NFSService_msg + when: inventory_hostname in groups["drbd_primary"] + tags: + - setup-all + - install-all + + +- name: Pcs constraint colocation order NFS Service then GitlabFS + shell: "sudo pcs constraint order GitlabFS then NFSService" + register: pcs_resource_ordring_NFSService_msg + when: inventory_hostname in groups["drbd_primary"] + tags: + - setup-all + - install-all + + +- name: Ensure started and enabled a pacemaker.service Service + ansible.builtin.systemd: + name: pacemaker.service + state: started + enabled: true + register: pacemaker_service_status + ignore_errors: true + tags: + - setup-gitlab + - install-gitlab + +- name: Ensure started and enabled a corosync.service Service + ansible.builtin.systemd: + name: corosync.service + state: started + enabled: true + register: corosync_service_status + ignore_errors: true + tags: + - setup-gitlab + - install-gitlab diff --git a/roles/gitlab/gitlab_drbd_storage/tasks/main.yml b/roles/gitlab/gitlab_drbd_storage/tasks/main.yml new file mode 100644 index 0000000..4d577f9 --- /dev/null +++ b/roles/gitlab/gitlab_drbd_storage/tasks/main.yml @@ -0,0 +1,49 @@ +--- +# tasks file for gitlab_storage + + +- name: Install the Pacemaker & DRBD9 packages + ansible.builtin.apt: + pkg: + - nfs-kernel-server=1:2.6.1-1ubuntu1.2 + tags: + - setup-all + - install-all + +- name: Ensure of Creating a NFS directory + ansible.builtin.file: + path: "{{nfs_directory}}" + state: directory + mode: '755' + tags: + - setup-all + - install-all + +- name: Install, configure, and start DRBD with Pacemaker + ansible.builtin.include_tasks: "{{ role_path }}/tasks/drbd_setup.yml" + when: drbd_enabled | bool + tags: always + + + +- name: Ensure NFS configuration is configured + ansible.builtin.template: + src: "{{ role_path }}/templates/exports.j2" + dest: "/etc/exports" + mode: 0644 + when: inventory_hostname in groups["drbd_primary"] + tags: + - setup-all + - install-all + + +- name: Restart and enable a NFS server + ansible.builtin.systemd: + name: nfs-kernel-server.service + state: restarted + enabled: true + register: NFS_service_status + when: inventory_hostname in groups["drbd_primary"] + tags: + - setup-all + - install-all \ No newline at end of file diff --git a/roles/gitlab/gitlab_drbd_storage/templates/drbd.conf.j2 b/roles/gitlab/gitlab_drbd_storage/templates/drbd.conf.j2 new file mode 100644 index 0000000..f84766a --- /dev/null +++ b/roles/gitlab/gitlab_drbd_storage/templates/drbd.conf.j2 @@ -0,0 +1,55 @@ +global { + usage-count yes; +} +common { + net { + protocol C; + max-buffers 80k; + max-epoch-size 8000; + sndbuf-size 0; + rcvbuf-size 0; + } +} + +resource r0_gitlab { + device minor 1; + meta-disk internal; + disk { + resync-rate 3123M; # bytes/second, default + c-plan-ahead 20; # 1/10 seconds, default + c-delay-target 10; # 1/10 seconds, default + c-fill-target 1M; # bytes, default + c-max-rate 3123M; # bytes/second, default + c-min-rate 250k; # bytes/second, default + disk-barrier no; + disk-flushes no; + } + options { + quorum off; + on-no-quorum suspend-io; + } + + + on {{hostvars[groups['drbd_primary'][0]]['inventory_hostname']}} { + disk {{hostvars[groups['drbd_primary'][0]]['drbd_storage_path']}}; + address {{hostvars[groups['drbd_primary'][0]]['drbd_ip_address']}}:{{drbd_port}}; + node-id 0; + } + +{% set node_count = 1 %} +{% for item in groups['drbd_secondary'] %} + on {{hostvars[item]['inventory_hostname']}} { + disk {{hostvars[item]['drbd_storage_path']}}; + address {{hostvars[item]['drbd_ip_address']}}:{{drbd_port}}; + node-id {{node_count}}; + } +{% set node_count = node_count + 1 %} +{% endfor %} + + + connection-mesh { + hosts {{hostvars[groups['drbd_primary'][0]]['inventory_hostname']}} {% for item in groups['drbd_secondary'] %} {{hostvars[item]['inventory_hostname']}} {% endfor %} ; + } +} + + diff --git a/roles/gitlab/gitlab_drbd_storage/templates/exports.j2 b/roles/gitlab/gitlab_drbd_storage/templates/exports.j2 new file mode 100644 index 0000000..5df3f6a --- /dev/null +++ b/roles/gitlab/gitlab_drbd_storage/templates/exports.j2 @@ -0,0 +1,7 @@ + + +{% for item in groups['gitlab_servers'] %} + +{{nfs_directory}} {{hostvars[item]['service_ip_address']}}(rw,sync,no_root_squash,no_subtree_check) + +{% endfor %} \ No newline at end of file diff --git a/roles/gitlab/gitlab_drbd_storage/tests/inventory b/roles/gitlab/gitlab_drbd_storage/tests/inventory new file mode 100644 index 0000000..878877b --- /dev/null +++ b/roles/gitlab/gitlab_drbd_storage/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/roles/gitlab/gitlab_drbd_storage/tests/test.yml b/roles/gitlab/gitlab_drbd_storage/tests/test.yml new file mode 100644 index 0000000..5cfae61 --- /dev/null +++ b/roles/gitlab/gitlab_drbd_storage/tests/test.yml @@ -0,0 +1,5 @@ +--- +- hosts: localhost + remote_user: root + roles: + - gitlab_storage diff --git a/roles/gitlab/gitlab_drbd_storage/vars/main.yml b/roles/gitlab/gitlab_drbd_storage/vars/main.yml new file mode 100644 index 0000000..cd26a3f --- /dev/null +++ b/roles/gitlab/gitlab_drbd_storage/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for gitlab_storage diff --git a/roles/gitlab/gitlab_main/README.md b/roles/gitlab/gitlab_main/README.md new file mode 100644 index 0000000..225dd44 --- /dev/null +++ b/roles/gitlab/gitlab_main/README.md @@ -0,0 +1,38 @@ +Role Name +========= + +A brief description of the role goes here. + +Requirements +------------ + +Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. + +Role Variables +-------------- + +A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. + +Dependencies +------------ + +A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. + +Example Playbook +---------------- + +Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: + + - hosts: servers + roles: + - { role: username.rolename, x: 42 } + +License +------- + +BSD + +Author Information +------------------ + +An optional section for the role authors to include contact information, or a website (HTML is not allowed). diff --git a/roles/gitlab/gitlab_main/defaults/main.yml b/roles/gitlab/gitlab_main/defaults/main.yml new file mode 100644 index 0000000..86dba20 --- /dev/null +++ b/roles/gitlab/gitlab_main/defaults/main.yml @@ -0,0 +1,2 @@ +--- +# defaults file for gitlab_main diff --git a/roles/gitlab/gitlab_main/handlers/main.yml b/roles/gitlab/gitlab_main/handlers/main.yml new file mode 100644 index 0000000..32d8136 --- /dev/null +++ b/roles/gitlab/gitlab_main/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for gitlab_main diff --git a/roles/gitlab/gitlab_main/meta/main.yml b/roles/gitlab/gitlab_main/meta/main.yml new file mode 100644 index 0000000..b4833af --- /dev/null +++ b/roles/gitlab/gitlab_main/meta/main.yml @@ -0,0 +1,52 @@ +galaxy_info: + author: Amir Baleghi + description: Gitlab High availability setup Active/Passive mode + company: Eberhard Karl University of Tübingen + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Choose a valid license ID from https://spdx.org - some suggested licenses: + # - BSD-3-Clause (default) + # - MIT + # - GPL-2.0-or-later + # - GPL-3.0-only + # - Apache-2.0 + # - CC-BY-4.0 + license: GPL-3.0-only + + min_ansible_version: 2.14.6 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. diff --git a/roles/gitlab/gitlab_main/tasks/gitlab_presetup.yml b/roles/gitlab/gitlab_main/tasks/gitlab_presetup.yml new file mode 100644 index 0000000..017b76f --- /dev/null +++ b/roles/gitlab/gitlab_main/tasks/gitlab_presetup.yml @@ -0,0 +1,10 @@ + +- name: Add IP address of all hosts to all hosts of Gitlab servers + lineinfile: + dest: /etc/hosts + line: "{{ hostvars[item].ansible_host }} {{ hostvars[item].inventory_hostname }} {{ hostvars[item].inventory_hostname_short }}" + state: present + with_items: "{{ play_hosts }}" + tags: + - setup-gitlab + - install-gitlab \ No newline at end of file diff --git a/roles/gitlab/gitlab_main/tasks/gitlab_setup.yml b/roles/gitlab/gitlab_main/tasks/gitlab_setup.yml new file mode 100644 index 0000000..c616cd9 --- /dev/null +++ b/roles/gitlab/gitlab_main/tasks/gitlab_setup.yml @@ -0,0 +1,211 @@ + + +- name: Install the pre-reqeust packages + ansible.builtin.apt: + pkg: + - curl + - openssh-server + - ca-certificates + - tzdata + - perl + - nfs-common + tags: + - setup-gitlab + - install-gitlab + + +- name: Set Postfix option hostname + debconf: + name=postifx + question="postfix/mailname" + value="{{ fqn_gitlab }}" + vtype="string" + tags: + - setup-gitlab + - install-gitlab + +- name: Set Postfix option type as internet site + ansible.builtin.debconf: + name: postfix + question: postfix/main_mailer_type + value: "'Internet Site'" + vtype: "string" + tags: + - setup-gitlab + - install-gitlab + + +- name: install Postfix for Gitlab + ansible.builtin.apt: + pkg: + - postfix + tags: + - setup-gitlab + - install-gitlab + + +- name: gitlab add repo script + shell: "curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash" + register: run_gitlab_script_db_repo + tags: + - setup-gitlab + - install-gitlab + + +- name: Ensure the NFS mount point is ready or not + shell: "mountpoint -q /var/opt/ " + register: nfs_mounted + failed_when: False + changed_when: False + tags: + - setup-gitlab + - install-gitlab + + +- name: Mount an NFS volume to First Gitlab server as source of sharing Gitlab Data + ansible.posix.mount: + src: "{{hostvars[groups['drbd_primary'][0]]['drbd_ip_address']}}:{{nfs_directory}}" + path: /var/opt + opts: "defaults,hard,rsize=1048576,wsize=1048576,noatime,nofail,_netdev,lookupcache=positive" + state: ephemeral + boot: false + fstype: nfs + when: + - inventory_hostname in groups['gitlab_servers'][0] + - not nfs_mounted + tags: + - setup-gitlab + - install-gitlab + + + +- name: Pacemaker cluster stop for new storage configuration + shell: "pcs cluster stop --all" + register: pcs_stop_new_storage + when: inventory_hostname in groups['gitlab_servers'][0] + ignore_errors: true + tags: + - new_storage + +# - name: clean all the old Gitlab package +# ansible.builtin.debug: +# msg: "new_storage is running." +# tags: new_storage + +- name: Stopped a gitlab-runsvdir Service + ansible.builtin.systemd: + name: gitlab-runsvdir.service + state: stopped + enabled: true + register: gitlab_runsvdir_service_status + ignore_errors: true + tags: + - setup-gitlab + - install-gitlab + +# - name: remove the old Gitlab package +# ansible.builtin.apt: +# pkg: +# - gitlab-ce +# state: absent +# purge: true +# tags: new_storage + + +# - name: Delete unshared old Gitlab data from every node after installation +# ansible.builtin.file: +# state: absent +# path: /var/opt/gitlab/ +# tags: new_storage + +# - name: Unconditionally reboot the Gitlab VMs with all defaults +# ansible.builtin.reboot: + +# - name: Mount an NFS volume to First Gitlab server as source of sharing Gitlab Data again +# ansible.posix.mount: +# src: "{{hostvars[groups['drbd_primary'][0]]['drbd_ip_address']}}:{{nfs_directory}}" +# path: /var/opt +# opts: "defaults,hard,rsize=1048576,wsize=1048576,noatime,nofail,_netdev,lookupcache=positive" +# state: ephemeral +# boot: false +# fstype: nfs +# when: +# - inventory_hostname in groups['gitlab_servers'][0] +# tags: +# - setup-gitlab +# - install-gitlab + + + +- name: started a gitlab-runsvdir Service + ansible.builtin.systemd: + name: gitlab-runsvdir.service + state: started + register: myserviceDetails + until: myserviceDetails.status.ActiveState == "active" + retries: 15 + delay: 2 + ignore_errors: true + tags: + - setup-gitlab + - install-gitlab + + +# - name: Waiting 20 sec for gitlab-runsvdir become ready +# ansible.builtin.wait_for: +# delay: 20 +# timeout: 0 +# tags: +# - setup-all +# - install-all + +- name: Install the Gitlab package + ansible.builtin.apt: + pkg: + - gitlab-ce + tags: + - setup-gitlab + - install-gitlab + + +- name: Update, and reconfigure Gitlab + block: + - ansible.builtin.include_tasks: "{{ role_path }}/tasks/gitlab_update.yml" + when: + - gitlab_enabled | bool + tags: + - setup-gitlab + - install-gitlab + + + +- name: Stop and Disable a gitlab-runsvdir Service + ansible.builtin.systemd: + name: gitlab-runsvdir.service + state: stopped + enabled: false + register: gitlab_runsvdir_service_status + ignore_errors: true + tags: + - setup-gitlab + - install-gitlab + + + +- name: Unmount a mounted volume + ansible.posix.mount: + path: /var/opt + state: unmounted + when: inventory_hostname in groups['gitlab_servers'][0] + tags: + - setup-gitlab + - install-gitlab + + +# - name: Delete unshared Gitlab data from every node after installation +# ansible.builtin.file: +# state: absent +# path: /var/opt/gitlab/ +# tags: +# - setup-gitlab +# - install-gitlab \ No newline at end of file diff --git a/roles/gitlab/gitlab_main/tasks/gitlab_update.yml b/roles/gitlab/gitlab_main/tasks/gitlab_update.yml new file mode 100644 index 0000000..b576dc7 --- /dev/null +++ b/roles/gitlab/gitlab_main/tasks/gitlab_update.yml @@ -0,0 +1,55 @@ + + +- name: Ensure Gitlab configuration is configured + ansible.builtin.template: + src: "{{ role_path }}/templates/gitlab.rb.j2" + dest: "/etc/gitlab/gitlab.rb" + mode: 0600 + tags: + - setup-all + - install-all + +- name: Ensure of Creating a Nginx custom file directory + ansible.builtin.file: + path: "{{nginx_custom_file_path}}" + state: directory + mode: '0644' + tags: + - setup-all + - install-all + + + +# - name: Ensure which Host is running Gitlab services +# shell: "pcs resource status GitlabService" +# register: pcs_status_gitlab_service +# when: inventory_hostname in groups['gitlab_servers'][0] + +- name: Gitlab service reconfigure + shell: "gitlab-ctl reconfigure" + register: gitlab_service_reconfigure_msg + # ignore_errors: true + tags: + - setup-all + - install-all + +- name: Ensure Gitlab Ngnix configuration is configured + ansible.builtin.template: + src: "{{ role_path }}/templates/nginx_custom.conf.j2" + dest: "{{nginx_custom_file_path}}/nginx_custom.conf" + owner: gitlab-www + group: gitlab-www + mode: 0644 + tags: + - setup-all + - install-all + +- name: Gitlab nginx service restart + shell: "gitlab-ctl restart nginx" + register: gitlab_service_restart_nginx_msg + # ignore_errors: true + tags: + - setup-all + - install-all + + diff --git a/roles/gitlab/gitlab_main/tasks/main.yml b/roles/gitlab/gitlab_main/tasks/main.yml new file mode 100644 index 0000000..be679a8 --- /dev/null +++ b/roles/gitlab/gitlab_main/tasks/main.yml @@ -0,0 +1,25 @@ +--- +# tasks file for gitlab_main + + + + +- name: Install, configure, and start Gitlab with Pacemaker + block: + - ansible.builtin.include_tasks: "{{ role_path }}/tasks/gitlab_presetup.yml" + - ansible.builtin.include_tasks: "{{ role_path }}/tasks/gitlab_setup.yml" + - ansible.builtin.include_tasks: "{{ role_path }}/tasks/pacemaker_setup.yml" + when: gitlab_enabled | bool + tags: always + +- name: Update, and restart Gitlab with Pacemaker + block: + - ansible.builtin.include_tasks: "{{ role_path }}/tasks/gitlab_update.yml" + when: gitlab_enabled | bool + tags: + - reconfig-gitlab + + + + + diff --git a/roles/gitlab/gitlab_main/tasks/pacemaker_setup.yml b/roles/gitlab/gitlab_main/tasks/pacemaker_setup.yml new file mode 100644 index 0000000..7acc319 --- /dev/null +++ b/roles/gitlab/gitlab_main/tasks/pacemaker_setup.yml @@ -0,0 +1,120 @@ + + +- name: Install the Pacemaker packages + ansible.builtin.apt: + pkg: + - pacemaker=2.1.2-1ubuntu3.1 + - pcs=0.10.11-2ubuntu3 + - resource-agents=1:4.7.0-1ubuntu7.2 + tags: + - setup-gitlab + - install-gitlab + +- name: Change user password + user: + name: hacluster + password: "{{ hacluster_password|password_hash('sha512') }}" + tags: + - setup-gitlab + - install-gitlab + + +- name: Pcs host auth + shell: "pcs host auth {% for item in groups['gitlab_servers'] %} {{item}} {% endfor %} -u hacluster -p {{hacluster_password}} " + register: pcs_host_auth_msg + when: inventory_hostname in groups['gitlab_servers'][0] + tags: + - setup-gitlab + - install-gitlab + +- name: Pcs cluster setup ha_cluster + shell: "pcs cluster setup ha_cluster {% for item in groups['gitlab_servers'] %} {{item}} {% endfor %} --force " + register: pcs_cluster_setup_msg + when: inventory_hostname in groups['gitlab_servers'][0] + tags: + - setup-gitlab + - install-gitlab + +- name: Pcs cluster start + shell: "pcs cluster start --all " + register: pcs_cluster_start_msg + when: inventory_hostname in groups['gitlab_servers'][0] + tags: + - setup-gitlab + - install-gitlab + +- name: Pcs stonith Set Disable + shell: "pcs property set stonith-enabled=false" + register: pcs_property_set_stonith_msg + when: inventory_hostname in groups['gitlab_servers'][0] + tags: + - setup-gitlab + - install-gitlab + +- name: Pcs no-quorum-policy Set Ignore + shell: "pcs property set no-quorum-policy=ignore" + register: pcs_property_set_quorum_policy_msg + when: inventory_hostname in groups['gitlab_servers'][0] + tags: + - setup-gitlab + - install-gitlab + +- name: Pcs setup Mount point service + shell: "pcs resource create GitlabNFS \ + Filesystem device='{{hostvars[groups['drbd_primary'][0]]['drbd_ip_address']}}:{{nfs_directory}}' \ + directory='/var/opt' fstype='nfs' \ + options='defaults,hard,rsize=1048576,wsize=1048576,noatime,nofail,_netdev,lookupcache=positive' \ + op monitor interval=0 timeout=10 op start interval=0 timeout=20 op stop interval=0 timeout=240" + register: pcs_resource_create_GitlabNFS_msg + when: inventory_hostname in groups['gitlab_servers'][0] + tags: + - setup-gitlab + - install-gitlab + +- name: Pcs create Gitlab service resource + shell: "pcs resource create GitlabService systemd:gitlab-runsvdir op monitor interval=1min" + register: pcs_resource_create_GitlabService_msg + when: inventory_hostname in groups['gitlab_servers'][0] + tags: + - setup-gitlab + - install-gitlab + +- name: Pcs create constraint colocation GitlabService with GitlabNFS + shell: "pcs constraint colocation add GitlabService with GitlabNFS" + register: pcs_constraint_colocation_GitlabService_msg + when: inventory_hostname in groups['gitlab_servers'][0] + tags: + - setup-gitlab + - install-gitlab + +- name: Pcs constraint colocation order NFS GitlabService then GitlabNFS + shell: "sudo pcs constraint order GitlabNFS then GitlabService" + register: pcs_resource_ordring_GitlabService_msg + when: inventory_hostname in groups['gitlab_servers'][0] + tags: + - setup-gitlab + - install-gitlab + +- name: Ensure started and enabled a pacemaker.service Service + ansible.builtin.systemd: + name: pacemaker.service + state: started + enabled: true + register: pacemaker_service_status + ignore_errors: true + tags: + - setup-gitlab + - install-gitlab + +- name: Ensure started and enabled a corosync.service Service + ansible.builtin.systemd: + name: corosync.service + state: started + enabled: true + register: corosync_service_status + ignore_errors: true + tags: + - setup-gitlab + - install-gitlab + + \ No newline at end of file diff --git a/roles/gitlab/gitlab_main/templates/gitlab.rb.j2 b/roles/gitlab/gitlab_main/templates/gitlab.rb.j2 new file mode 100644 index 0000000..728fc63 --- /dev/null +++ b/roles/gitlab/gitlab_main/templates/gitlab.rb.j2 @@ -0,0 +1,3350 @@ +## GitLab configuration settings +##! This file is generated during initial installation and **is not** modified +##! during upgrades. +##! Check out the latest version of this file to know about the different +##! settings that can be configured, when they were introduced and why: +##! https://gitlab.com/gitlab-org/omnibus-gitlab/blame/master/files/gitlab-config-template/gitlab.rb.template + +##! Locally, the complete template corresponding to the installed version can be found at: +##! /opt/gitlab/etc/gitlab.rb.template + +##! You can run `gitlab-ctl diff-config` to compare the contents of the current gitlab.rb with +##! the gitlab.rb.template from the currently running version. + +##! You can run `gitlab-ctl show-config` to display the configuration that will be generated by +##! running `gitlab-ctl reconfigure` + +##! In general, the values specified here should reflect what the default value of the attribute will be. +##! There are instances where this behavior is not possible or desired. For example, when providing passwords, +##! or connecting to third party services. +##! In those instances, we endeavour to provide an example configuration. + +## GitLab URL +##! URL on which GitLab will be reachable. +##! For more details on configuring external_url see: +##! https://docs.gitlab.com/omnibus/settings/configuration.html#configuring-the-external-url-for-gitlab +##! +##! Note: During installation/upgrades, the value of the environment variable +##! EXTERNAL_URL will be used to populate/replace this value. +##! On AWS EC2 instances, we also attempt to fetch the public hostname/IP +##! address from AWS. For more details, see: +##! https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html +external_url 'https://{{ fqn_gitlab }}/' + +## Roles for multi-instance GitLab +##! The default is to have no roles enabled, which results in GitLab running as an all-in-one instance. +##! Options: +##! redis_sentinel_role redis_master_role redis_replica_role geo_primary_role geo_secondary_role +##! postgres_role consul_role application_role monitoring_role +##! For more details on each role, see: +##! https://docs.gitlab.com/omnibus/roles/index.html#roles +##! +# roles ['redis_sentinel_role', 'redis_master_role'] + +## Legend +##! The following notations at the beginning of each line may be used to +##! differentiate between components of this file and to easily select them using +##! a regex. +##! ## Titles, subtitles etc +##! ##! More information - Description, Docs, Links, Issues etc. +##! Configuration settings have a single # followed by a single space at the +##! beginning; Remove them to enable the setting. + +##! **Configuration settings below are optional.** + + +################################################################################ +################################################################################ +## Configuration Settings for GitLab CE and EE ## +################################################################################ +################################################################################ + +################################################################################ +## gitlab.yml configuration +##! Docs: https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/settings/gitlab.yml.md +################################################################################ +# gitlab_rails['gitlab_ssh_host'] = 'ssh.host_example.com' +# gitlab_rails['gitlab_ssh_user'] = '' +# gitlab_rails['time_zone'] = 'UTC' + +### Rails asset / CDN host +###! Defines a url for a host/cdn to use for the Rails assets +###! Docs: https://docs.gitlab.com/omnibus/settings/configuration.html#set-a-content-delivery-network-url +# gitlab_rails['cdn_host'] = 'https://mycdnsubdomain.fictional-cdn.com' + +### Request duration +###! Tells the rails application how long it has to complete a request +###! This value needs to be lower than the worker timeout set in puma. +###! By default, we'll allow 95% of the the worker timeout +# gitlab_rails['max_request_duration_seconds'] = 57 + +### GitLab email server settings +###! Docs: https://docs.gitlab.com/omnibus/settings/smtp.html +###! **Use smtp instead of sendmail/postfix.** + +# gitlab_rails['smtp_enable'] = true +# gitlab_rails['smtp_address'] = "smtp.server" +# gitlab_rails['smtp_port'] = 465 +# gitlab_rails['smtp_user_name'] = "smtp user" +# gitlab_rails['smtp_password'] = "smtp password" +# gitlab_rails['smtp_domain'] = "example.com" +# gitlab_rails['smtp_authentication'] = "login" +# gitlab_rails['smtp_enable_starttls_auto'] = true +# gitlab_rails['smtp_tls'] = false +# gitlab_rails['smtp_pool'] = false + +###! **Can be: 'none', 'peer', 'client_once', 'fail_if_no_peer_cert'** +###! Docs: http://api.rubyonrails.org/classes/ActionMailer/Base.html +# gitlab_rails['smtp_openssl_verify_mode'] = 'none' + +# gitlab_rails['smtp_ca_path'] = "/etc/ssl/certs" +# gitlab_rails['smtp_ca_file'] = "/etc/ssl/certs/ca-certificates.crt" + +### Email Settings + +# gitlab_rails['gitlab_email_enabled'] = true + +##! If your SMTP server does not like the default 'From: gitlab@gitlab.example.com' +##! can change the 'From' with this setting. +# gitlab_rails['gitlab_email_from'] = 'example@example.com' +# gitlab_rails['gitlab_email_display_name'] = 'Example' +# gitlab_rails['gitlab_email_reply_to'] = 'noreply@example.com' +# gitlab_rails['gitlab_email_subject_suffix'] = '' +# gitlab_rails['gitlab_email_smime_enabled'] = false +# gitlab_rails['gitlab_email_smime_key_file'] = '/etc/gitlab/ssl/gitlab_smime.key' +# gitlab_rails['gitlab_email_smime_cert_file'] = '/etc/gitlab/ssl/gitlab_smime.crt' +# gitlab_rails['gitlab_email_smime_ca_certs_file'] = '/etc/gitlab/ssl/gitlab_smime_cas.crt' + +### GitLab user privileges +# gitlab_rails['gitlab_username_changing_enabled'] = true + +### Default Theme +### Available values: +##! `1` for Indigo +##! `2` for Dark +##! `3` for Light +##! `4` for Blue +##! `5` for Green +##! `6` for Light Indigo +##! `7` for Light Blue +##! `8` for Light Green +##! `9` for Red +##! `10` for Light Red +# gitlab_rails['gitlab_default_theme'] = 2 + +### Default project feature settings +# gitlab_rails['gitlab_default_projects_features_issues'] = true +# gitlab_rails['gitlab_default_projects_features_merge_requests'] = true +# gitlab_rails['gitlab_default_projects_features_wiki'] = true +# gitlab_rails['gitlab_default_projects_features_snippets'] = true +# gitlab_rails['gitlab_default_projects_features_builds'] = true +# gitlab_rails['gitlab_default_projects_features_container_registry'] = true + +### Automatic issue closing +###! See https://docs.gitlab.com/ee/customization/issue_closing.html for more +###! information about this pattern. +# gitlab_rails['gitlab_issue_closing_pattern'] = "\b((?:[Cc]los(?:e[sd]?|ing)|\b[Ff]ix(?:e[sd]|ing)?|\b[Rr]esolv(?:e[sd]?|ing)|\b[Ii]mplement(?:s|ed|ing)?)(:?) +(?:(?:issues? +)?%{issue_ref}(?:(?:, *| +and +)?)|([A-Z][A-Z0-9_]+-\d+))+)" + +### Download location +###! When a user clicks e.g. 'Download zip' on a project, a temporary zip file +###! is created in the following directory. +###! Should not be the same path, or a sub directory of any of the `git_data_dirs` +# gitlab_rails['gitlab_repository_downloads_path'] = 'tmp/repositories' + +### Gravatar Settings +# gitlab_rails['gravatar_plain_url'] = 'http://www.gravatar.com/avatar/%{hash}?s=%{size}&d=identicon' +# gitlab_rails['gravatar_ssl_url'] = 'https://secure.gravatar.com/avatar/%{hash}?s=%{size}&d=identicon' + +### Auxiliary jobs +###! Periodically executed jobs, to self-heal Gitlab, do external +###! synchronizations, etc. +###! Docs: https://github.com/ondrejbartas/sidekiq-cron#adding-cron-job +###! https://docs.gitlab.com/ee/ci/yaml/index.html#artifactsexpire_in +# gitlab_rails['stuck_ci_jobs_worker_cron'] = "0 0 * * *" +# gitlab_rails['expire_build_artifacts_worker_cron'] = "*/7 * * * *" +# gitlab_rails['environments_auto_stop_cron_worker_cron'] = "24 * * * *" +# gitlab_rails['pipeline_schedule_worker_cron'] = "19 * * * *" +# gitlab_rails['ci_archive_traces_cron_worker_cron'] = "17 * * * *" +# gitlab_rails['repository_check_worker_cron'] = "20 * * * *" +# gitlab_rails['admin_email_worker_cron'] = "0 0 * * 0" +# gitlab_rails['personal_access_tokens_expiring_worker_cron'] = "0 1 * * *" +# gitlab_rails['personal_access_tokens_expired_notification_worker_cron'] = "0 2 * * *" +# gitlab_rails['repository_archive_cache_worker_cron'] = "0 * * * *" +# gitlab_rails['pages_domain_verification_cron_worker'] = "*/15 * * * *" +# gitlab_rails['pages_domain_ssl_renewal_cron_worker'] = "*/10 * * * *" +# gitlab_rails['pages_domain_removal_cron_worker'] = "47 0 * * *" +# gitlab_rails['remove_unaccepted_member_invites_cron_worker'] = "10 15 * * *" +# gitlab_rails['schedule_migrate_external_diffs_worker_cron'] = "15 * * * *" +# gitlab_rails['ci_platform_metrics_update_cron_worker'] = '47 9 * * *' +# gitlab_rails['analytics_usage_trends_count_job_trigger_worker_cron'] = "50 23 */1 * *" +# gitlab_rails['member_invitation_reminder_emails_worker_cron'] = "0 0 * * *" +# gitlab_rails['user_status_cleanup_batch_worker_cron'] = "* * * * *" +# gitlab_rails['namespaces_in_product_marketing_emails_worker_cron'] = "0 9 * * *" +# gitlab_rails['ssh_keys_expired_notification_worker_cron'] = "0 2 * * *" +# gitlab_rails['ssh_keys_expiring_soon_notification_worker_cron'] = "0 1 * * *" +# gitlab_rails['loose_foreign_keys_cleanup_worker_cron'] = "*/5 * * * *" +# gitlab_rails['ci_runner_versions_reconciliation_worker_cron'] = "@daily" +# gitlab_rails['ci_runners_stale_machines_cleanup_worker_cron'] = "36 * * * *" + +### Webhook Settings +###! Number of seconds to wait for HTTP response after sending webhook HTTP POST +###! request (default: 10) +# gitlab_rails['webhook_timeout'] = 10 + +### GraphQL Settings +###! Tells the rails application how long it has to complete a GraphQL request. +###! We suggest this value to be higher than the database timeout value +###! and lower than the worker timeout set in puma. (default: 30) +# gitlab_rails['graphql_timeout'] = 30 + +### Trusted proxies +###! Customize if you have GitLab behind a reverse proxy which is running on a +###! different machine. +###! **Add the IP address for your reverse proxy to the list, otherwise users +###! will appear signed in from that address.** +# gitlab_rails['trusted_proxies'] = [] + +### Content Security Policy +####! Customize if you want to enable the Content-Security-Policy header, which +####! can help thwart JavaScript cross-site scripting (XSS) attacks. +####! See: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP +# gitlab_rails['content_security_policy'] = { +# 'enabled' => false, +# 'report_only' => false, +# # Each directive is a String (e.g. "'self'"). +# 'directives' => { +# 'base_uri' => nil, +# 'child_src' => nil, +# 'connect_src' => nil, +# 'default_src' => nil, +# 'font_src' => nil, +# 'form_action' => nil, +# 'frame_ancestors' => nil, +# 'frame_src' => nil, +# 'img_src' => nil, +# 'manifest_src' => nil, +# 'media_src' => nil, +# 'object_src' => nil, +# 'script_src' => nil, +# 'style_src' => nil, +# 'worker_src' => nil, +# 'report_uri' => nil, +# } +# } + +### Allowed hosts +###! Customize the `host` headers that should be catered by the Rails +###! application. By default, everything is allowed. +# gitlab_rails['allowed_hosts'] = [] + +### Monitoring settings +###! IP whitelist controlling access to monitoring endpoints +# gitlab_rails['monitoring_whitelist'] = ['127.0.0.0/8', '::1/128'] + +### Shutdown settings +###! Defines an interval to block healthcheck, +###! but continue accepting application requests. +# gitlab_rails['shutdown_blackout_seconds'] = 10 + +### Microsoft Graph Mailer +###! Allows delivery of emails using Microsoft Graph API with OAuth 2.0 client +###! credentials flow. +###! Docs: https://docs.gitlab.com/omnibus/settings/microsoft_graph_mailer.html +# gitlab_rails['microsoft_graph_mailer_enabled'] = false +# gitlab_rails['microsoft_graph_mailer_user_id'] = "YOUR-USER-ID" +# gitlab_rails['microsoft_graph_mailer_tenant'] = "YOUR-TENANT-ID" +# gitlab_rails['microsoft_graph_mailer_client_id'] = "YOUR-CLIENT-ID" +# gitlab_rails['microsoft_graph_mailer_client_secret'] = "YOUR-CLIENT-SECRET-ID" +# gitlab_rails['microsoft_graph_mailer_azure_ad_endpoint'] = "https://login.microsoftonline.com" +# gitlab_rails['microsoft_graph_mailer_graph_endpoint'] = "https://graph.microsoft.com" + +### Reply by email +###! Allow users to comment on issues and merge requests by replying to +###! notification emails. +###! Docs: https://docs.gitlab.com/ee/administration/reply_by_email.html +# gitlab_rails['incoming_email_enabled'] = true + +#### Incoming Email Address +####! The email address including the `%{key}` placeholder that will be replaced +####! to reference the item being replied to. +####! **The placeholder can be omitted but if present, it must appear in the +####! "user" part of the address (before the `@`).** +# gitlab_rails['incoming_email_address'] = "gitlab-incoming+%{key}@gmail.com" + +#### Email account username +####! **With third party providers, this is usually the full email address.** +####! **With self-hosted email servers, this is usually the user part of the +####! email address.** +# gitlab_rails['incoming_email_email'] = "gitlab-incoming@gmail.com" + +#### Email account password +# gitlab_rails['incoming_email_password'] = "[REDACTED]" + +#### IMAP Settings +# gitlab_rails['incoming_email_host'] = "imap.gmail.com" +# gitlab_rails['incoming_email_port'] = 993 +# gitlab_rails['incoming_email_ssl'] = true +# gitlab_rails['incoming_email_start_tls'] = false + +#### Incoming Mailbox Settings (via `mail_room`) +####! The mailbox where incoming mail will end up. Usually "inbox". +# gitlab_rails['incoming_email_mailbox_name'] = "inbox" +####! The IDLE command timeout. +# gitlab_rails['incoming_email_idle_timeout'] = 60 +####! The file name for internal `mail_room` JSON logfile +# gitlab_rails['incoming_email_log_file'] = "/var/log/gitlab/mailroom/mail_room_json.log" +####! This marks incoming messages deleted after delivery. +####! If you are using Microsoft Graph API instead of IMAP, set this to false to retain +####! messages in the inbox since deleted messages are auto-expunged after some time. +# gitlab_rails['incoming_email_delete_after_delivery'] = true +####! Permanently remove messages from the mailbox when they are marked as deleted after delivery +####! Only applies to IMAP. Microsoft Graph will auto-expunge any deleted messages. +# gitlab_rails['incoming_email_expunge_deleted'] = false + +#### Inbox options (for Microsoft Graph) +# gitlab_rails['incoming_email_inbox_method'] = 'microsoft_graph' +# gitlab_rails['incoming_email_inbox_options'] = { +# 'tenant_id': 'YOUR-TENANT-ID', +# 'client_id': 'YOUR-CLIENT-ID', +# 'client_secret': 'YOUR-CLIENT-SECRET', +# 'poll_interval': 60 # Optional +# } + +#### How incoming emails are delivered to Rails process. Accept either sidekiq +#### or webhook. The default config is webhook. +# gitlab_rails['incoming_email_delivery_method'] = "webhook" + +#### Token to authenticate webhook requests. The token must be exactly 32 bytes, +#### encoded with base64 +# gitlab_rails['incoming_email_auth_token'] = nil + +####! The format of mail_room crash logs +# mailroom['exit_log_format'] = "plain" + +### Consolidated (simplified) object storage configuration +###! This uses a single credential for object storage with multiple buckets. +###! It also enables Workhorse to upload files directly with its own S3 client +###! instead of using pre-signed URLs. +###! +###! This configuration will only take effect if the object_store +###! sections are not defined within the types. For example, enabling +###! gitlab_rails['artifacts_object_store_enabled'] or +###! gitlab_rails['lfs_object_store_enabled'] will prevent the +###! consolidated settings from being used. +###! +###! Be sure to use different buckets for each type of object. +###! Docs: https://docs.gitlab.com/ee/administration/object_storage.html +# gitlab_rails['object_store']['enabled'] = false +# gitlab_rails['object_store']['connection'] = {} +# gitlab_rails['object_store']['storage_options'] = {} +# gitlab_rails['object_store']['proxy_download'] = false +# gitlab_rails['object_store']['objects']['artifacts']['bucket'] = nil +# gitlab_rails['object_store']['objects']['external_diffs']['bucket'] = nil +# gitlab_rails['object_store']['objects']['lfs']['bucket'] = nil +# gitlab_rails['object_store']['objects']['uploads']['bucket'] = nil +# gitlab_rails['object_store']['objects']['packages']['bucket'] = nil +# gitlab_rails['object_store']['objects']['dependency_proxy']['bucket'] = nil +# gitlab_rails['object_store']['objects']['terraform_state']['bucket'] = nil +# gitlab_rails['object_store']['objects']['ci_secure_files']['bucket'] = nil +# gitlab_rails['object_store']['objects']['pages']['bucket'] = nil + +### Job Artifacts +# gitlab_rails['artifacts_enabled'] = true +# gitlab_rails['artifacts_path'] = "/var/opt/gitlab/gitlab-rails/shared/artifacts" +####! Job artifacts Object Store +####! Docs: https://docs.gitlab.com/ee/administration/job_artifacts.html#using-object-storage +# gitlab_rails['artifacts_object_store_enabled'] = false +# gitlab_rails['artifacts_object_store_proxy_download'] = false +# gitlab_rails['artifacts_object_store_remote_directory'] = "artifacts" +# gitlab_rails['artifacts_object_store_connection'] = { +# 'provider' => 'AWS', +# 'region' => 'eu-west-1', +# 'aws_access_key_id' => 'AWS_ACCESS_KEY_ID', +# 'aws_secret_access_key' => 'AWS_SECRET_ACCESS_KEY', +# # # The below options configure an S3 compatible host instead of AWS +# # 'aws_signature_version' => 4, # For creation of signed URLs. Set to 2 if provider does not support v4. +# # 'endpoint' => 'https://s3.amazonaws.com', # default: nil - Useful for S3 compliant services such as DigitalOcean Spaces +# # 'host' => 's3.amazonaws.com', +# # 'path_style' => false # Use 'host/bucket_name/object' instead of 'bucket_name.host/object' +# } + +### External merge request diffs +# gitlab_rails['external_diffs_enabled'] = false +# gitlab_rails['external_diffs_when'] = nil +# gitlab_rails['external_diffs_storage_path'] = "/var/opt/gitlab/gitlab-rails/shared/external-diffs" +# gitlab_rails['external_diffs_object_store_enabled'] = false +# gitlab_rails['external_diffs_object_store_proxy_download'] = false +# gitlab_rails['external_diffs_object_store_remote_directory'] = "external-diffs" +# gitlab_rails['external_diffs_object_store_connection'] = { +# 'provider' => 'AWS', +# 'region' => 'eu-west-1', +# 'aws_access_key_id' => 'AWS_ACCESS_KEY_ID', +# 'aws_secret_access_key' => 'AWS_SECRET_ACCESS_KEY', +# # # The below options configure an S3 compatible host instead of AWS +# # 'aws_signature_version' => 4, # For creation of signed URLs. Set to 2 if provider does not support v4. +# # 'endpoint' => 'https://s3.amazonaws.com', # default: nil - Useful for S3 compliant services such as DigitalOcean Spaces +# # 'host' => 's3.amazonaws.com', +# # 'path_style' => false # Use 'host/bucket_name/object' instead of 'bucket_name.host/object' +# } + +### Git LFS +# gitlab_rails['lfs_enabled'] = true +# gitlab_rails['lfs_storage_path'] = "/var/opt/gitlab/gitlab-rails/shared/lfs-objects" +# gitlab_rails['lfs_object_store_enabled'] = false +# gitlab_rails['lfs_object_store_proxy_download'] = false +# gitlab_rails['lfs_object_store_remote_directory'] = "lfs-objects" +# gitlab_rails['lfs_object_store_connection'] = { +# 'provider' => 'AWS', +# 'region' => 'eu-west-1', +# 'aws_access_key_id' => 'AWS_ACCESS_KEY_ID', +# 'aws_secret_access_key' => 'AWS_SECRET_ACCESS_KEY', +# # # The below options configure an S3 compatible host instead of AWS +# # 'aws_signature_version' => 4, # For creation of signed URLs. Set to 2 if provider does not support v4. +# # 'endpoint' => 'https://s3.amazonaws.com', # default: nil - Useful for S3 compliant services such as DigitalOcean Spaces +# # 'host' => 's3.amazonaws.com', +# # 'path_style' => false # Use 'host/bucket_name/object' instead of 'bucket_name.host/object' +# } + +### GitLab uploads +###! Docs: https://docs.gitlab.com/ee/administration/uploads.html +# gitlab_rails['uploads_directory'] = "/var/opt/gitlab/gitlab-rails/uploads" +# gitlab_rails['uploads_storage_path'] = "/opt/gitlab/embedded/service/gitlab-rails/public" +# gitlab_rails['uploads_base_dir'] = "uploads/-/system" +# gitlab_rails['uploads_object_store_enabled'] = false +# gitlab_rails['uploads_object_store_proxy_download'] = false +# gitlab_rails['uploads_object_store_remote_directory'] = "uploads" +# gitlab_rails['uploads_object_store_connection'] = { +# 'provider' => 'AWS', +# 'region' => 'eu-west-1', +# 'aws_access_key_id' => 'AWS_ACCESS_KEY_ID', +# 'aws_secret_access_key' => 'AWS_SECRET_ACCESS_KEY', +# # # The below options configure an S3 compatible host instead of AWS +# # 'host' => 's3.amazonaws.com', +# # 'aws_signature_version' => 4, # For creation of signed URLs. Set to 2 if provider does not support v4. +# # 'endpoint' => 'https://s3.amazonaws.com', # default: nil - Useful for S3 compliant services such as DigitalOcean Spaces +# # 'path_style' => false # Use 'host/bucket_name/object' instead of 'bucket_name.host/object' +# } + +### Terraform state +###! Docs: https://docs.gitlab.com/ee/administration/terraform_state +# gitlab_rails['terraform_state_enabled'] = true +# gitlab_rails['terraform_state_storage_path'] = "/var/opt/gitlab/gitlab-rails/shared/terraform_state" +# gitlab_rails['terraform_state_object_store_enabled'] = false +# gitlab_rails['terraform_state_object_store_remote_directory'] = "terraform" +# gitlab_rails['terraform_state_object_store_connection'] = { +# 'provider' => 'AWS', +# 'region' => 'eu-west-1', +# 'aws_access_key_id' => 'AWS_ACCESS_KEY_ID', +# 'aws_secret_access_key' => 'AWS_SECRET_ACCESS_KEY', +# # # The below options configure an S3 compatible host instead of AWS +# # 'host' => 's3.amazonaws.com', +# # 'aws_signature_version' => 4, # For creation of signed URLs. Set to 2 if provider does not support v4. +# # 'endpoint' => 'https://s3.amazonaws.com', # default: nil - Useful for S3 compliant services such as DigitalOcean Spaces +# # 'path_style' => false # Use 'host/bucket_name/object' instead of 'bucket_name.host/object' +# } + +### CI Secure Files +# gitlab_rails['ci_secure_files_enabled'] = false +# gitlab_rails['ci_secure_files_storage_path'] = "/var/opt/gitlab/gitlab-rails/shared/ci_secure_files" +# gitlab_rails['ci_secure_files_object_store_enabled'] = false +# gitlab_rails['ci_secure_files_object_store_remote_directory'] = "ci-secure-files" +# gitlab_rails['ci_secure_files_object_store_connection'] = { +# 'provider' => 'AWS', +# 'region' => 'eu-west-1', +# 'aws_access_key_id' => 'AWS_ACCESS_KEY_ID', +# 'aws_secret_access_key' => 'AWS_SECRET_ACCESS_KEY', +# # # The below options configure an S3 compatible host instead of AWS +# # 'host' => 's3.amazonaws.com', +# # 'aws_signature_version' => 4, # For creation of signed URLs. Set to 2 if provider does not support v4. +# # 'endpoint' => 'https://s3.amazonaws.com', # default: nil - Useful for S3 compliant services such as DigitalOcean Spaces +# # 'path_style' => false # Use 'host/bucket_name/object' instead of 'bucket_name.host/object' +# } + +### GitLab Pages +# gitlab_rails['pages_object_store_enabled'] = false +# gitlab_rails['pages_object_store_remote_directory'] = "pages" +# gitlab_rails['pages_object_store_connection'] = { +# 'provider' => 'AWS', +# 'region' => 'eu-west-1', +# 'aws_access_key_id' => 'AWS_ACCESS_KEY_ID', +# 'aws_secret_access_key' => 'AWS_SECRET_ACCESS_KEY', +# # # The below options configure an S3 compatible host instead of AWS +# # 'host' => 's3.amazonaws.com', +# # 'aws_signature_version' => 4, # For creation of signed URLs. Set to 2 if provider does not support v4. +# # 'endpoint' => 'https://s3.amazonaws.com', # default: nil - Useful for S3 compliant services such as DigitalOcean Spaces +# # 'path_style' => false # Use 'host/bucket_name/object' instead of 'bucket_name.host/object' +# } +# gitlab_rails['pages_local_store_enabled'] = true +# gitlab_rails['pages_local_store_path'] = "/var/opt/gitlab/gitlab-rails/shared/pages" + +### Impersonation settings +# gitlab_rails['impersonation_enabled'] = true + +### Disable jQuery and CSS animations +# gitlab_rails['disable_animations'] = false + +### Application settings cache expiry in seconds. (default: 60) +# gitlab_rails['application_settings_cache_seconds'] = 60 + +### Usage Statistics +# gitlab_rails['usage_ping_enabled'] = true + +### GitLab Mattermost +###! These settings are void if Mattermost is installed on the same omnibus +###! install +# gitlab_rails['mattermost_host'] = "https://mattermost.example.com" + +### LDAP Settings +###! Docs: https://docs.gitlab.com/ee/administration/auth/ldap/index.html +###! **Be careful not to break the indentation in the ldap_servers block. It is +###! in yaml format and the spaces must be retained. Using tabs will not work.** + +# gitlab_rails['ldap_enabled'] = false +# gitlab_rails['prevent_ldap_sign_in'] = false + +###! **remember to close this block with 'EOS' below** +# gitlab_rails['ldap_servers'] = YAML.load <<-'EOS' +# main: # 'main' is the GitLab 'provider ID' of this LDAP server +# label: 'LDAP' +# host: '_your_ldap_server' +# port: 389 +# uid: 'sAMAccountName' +# bind_dn: '_the_full_dn_of_the_user_you_will_bind_with' +# password: '_the_password_of_the_bind_user' +# encryption: 'plain' # "start_tls" or "simple_tls" or "plain" +# verify_certificates: true +# smartcard_auth: false +# active_directory: true +# allow_username_or_email_login: false +# lowercase_usernames: false +# block_auto_created_users: false +# base: '' +# user_filter: '' +# ## EE only +# group_base: '' +# admin_group: '' +# sync_ssh_keys: false +# +# secondary: # 'secondary' is the GitLab 'provider ID' of second LDAP server +# label: 'LDAP' +# host: '_your_ldap_server' +# port: 389 +# uid: 'sAMAccountName' +# bind_dn: '_the_full_dn_of_the_user_you_will_bind_with' +# password: '_the_password_of_the_bind_user' +# encryption: 'plain' # "start_tls" or "simple_tls" or "plain" +# verify_certificates: true +# smartcard_auth: false +# active_directory: true +# allow_username_or_email_login: false +# lowercase_usernames: false +# block_auto_created_users: false +# base: '' +# user_filter: '' +# ## EE only +# group_base: '' +# admin_group: '' +# sync_ssh_keys: false +# EOS + +### Smartcard authentication settings +###! Docs: https://docs.gitlab.com/ee/administration/auth/smartcard.html +# gitlab_rails['smartcard_enabled'] = false +# gitlab_rails['smartcard_ca_file'] = "/etc/gitlab/ssl/CA.pem" +# gitlab_rails['smartcard_client_certificate_required_host'] = 'smartcard.gitlab.example.com' +# gitlab_rails['smartcard_client_certificate_required_port'] = 3444 +# gitlab_rails['smartcard_required_for_git_access'] = false +# gitlab_rails['smartcard_san_extensions'] = false + +### OmniAuth Settings +###! Docs: https://docs.gitlab.com/ee/integration/omniauth.html +# gitlab_rails['omniauth_enabled'] = nil +# gitlab_rails['omniauth_allow_single_sign_on'] = ['saml'] +# gitlab_rails['omniauth_sync_email_from_provider'] = 'saml' +# gitlab_rails['omniauth_sync_profile_from_provider'] = ['saml'] +# gitlab_rails['omniauth_sync_profile_attributes'] = ['email'] +# gitlab_rails['omniauth_auto_sign_in_with_provider'] = 'saml' +# gitlab_rails['omniauth_block_auto_created_users'] = true +# gitlab_rails['omniauth_auto_link_ldap_user'] = false +# gitlab_rails['omniauth_auto_link_saml_user'] = false +# gitlab_rails['omniauth_auto_link_user'] = ['twitter'] +# gitlab_rails['omniauth_external_providers'] = ['twitter', 'google_oauth2'] +# gitlab_rails['omniauth_allow_bypass_two_factor'] = ['google_oauth2'] +# gitlab_rails['omniauth_providers'] = [ +# { +# "name" => "google_oauth2", +# "app_id" => "YOUR APP ID", +# "app_secret" => "YOUR APP SECRET", +# "args" => { "access_type" => "offline", "approval_prompt" => "" } +# } +# ] +# gitlab_rails['omniauth_cas3_session_duration'] = 28800 +# gitlab_rails['omniauth_saml_message_max_byte_size'] = 250000 + +### FortiAuthenticator authentication settings +# gitlab_rails['forti_authenticator_enabled'] = false +# gitlab_rails['forti_authenticator_host'] = 'forti_authenticator.example.com' +# gitlab_rails['forti_authenticator_port'] = 443 +# gitlab_rails['forti_authenticator_username'] = 'admin' +# gitlab_rails['forti_authenticator_access_token'] = 's3cr3t' + +### FortiToken Cloud authentication settings +# gitlab_rails['forti_token_cloud_enabled'] = false +# gitlab_rails['forti_token_cloud_client_id'] = 'forti_token_cloud_client_id' +# gitlab_rails['forti_token_cloud_client_secret'] = 's3cr3t' + +### DuoAuth authentication settings +# gitlab_rails['duo_auth_enabled'] = false +# gitlab_rails['duo_auth_integration_key'] = 'duo_auth_integration_key' +# gitlab_rails['duo_auth_secret_key'] = 'duo_auth_secret_key' +# gitlab_rails['duo_auth_hostname'] = 'duo_auth.example.com' + +### Backup Settings +###! Docs: https://docs.gitlab.com/omnibus/settings/backups.html + +# gitlab_rails['manage_backup_path'] = true +# gitlab_rails['backup_path'] = "/var/opt/gitlab/backups" +# gitlab_rails['backup_gitaly_backup_path'] = "/opt/gitlab/embedded/bin/gitaly-backup" + +###! Docs: https://docs.gitlab.com/ee/raketasks/backup_restore.html#backup-archive-permissions +# gitlab_rails['backup_archive_permissions'] = 0644 + +# gitlab_rails['backup_pg_schema'] = 'public' + +###! The duration in seconds to keep backups before they are allowed to be deleted +# gitlab_rails['backup_keep_time'] = 604800 + +# gitlab_rails['backup_upload_connection'] = { +# 'provider' => 'AWS', +# 'region' => 'eu-west-1', +# 'aws_access_key_id' => 'AKIAKIAKI', +# 'aws_secret_access_key' => 'secret123', +# # # If IAM profile use is enabled, remove aws_access_key_id and aws_secret_access_key +# 'use_iam_profile' => false +# } +# gitlab_rails['backup_upload_remote_directory'] = 'my.s3.bucket' +# gitlab_rails['backup_multipart_chunk_size'] = 104857600 + +###! **Turns on AWS Server-Side Encryption with Amazon S3-Managed Keys for +###! backups** +# gitlab_rails['backup_encryption'] = 'AES256' +###! The encryption key to use with AWS Server-Side Encryption. +###! Setting this value will enable Server-Side Encryption with customer provided keys; +###! otherwise S3-managed keys are used. +# gitlab_rails['backup_encryption_key'] = '' + +###! **Turns on AWS Server-Side Encryption with Amazon SSE-KMS (AWS managed but customer-master key) +# gitlab_rails['backup_upload_storage_options'] = { +# 'server_side_encryption' => 'aws:kms', +# 'server_side_encryption_kms_key_id' => 'arn:aws:kms:YOUR-KEY-ID-HERE' +# } + +###! **Specifies Amazon S3 storage class to use for backups. Valid values +###! include 'STANDARD', 'STANDARD_IA', and 'REDUCED_REDUNDANCY'** +# gitlab_rails['backup_storage_class'] = 'STANDARD' + +###! Skip parts of the backup. Comma separated. +###! Docs: https://docs.gitlab.com/ee/raketasks/backup_restore.html#excluding-specific-directories-from-the-backup +#gitlab_rails['env'] = { +# "SKIP" => "db,uploads,repositories,builds,artifacts,lfs,registry,pages" +#} + +### For setting up different data storing directory +###! Docs: https://docs.gitlab.com/omnibus/settings/configuration.html#store-git-data-in-an-alternative-directory +###! **If you want to use a single non-default directory to store git data use a +###! path that doesn't contain symlinks.** +# git_data_dirs({ +# "default" => { +# "path" => "/mnt/nfs-01/git-data" +# } +# }) + +### Gitaly settings +# gitlab_rails['gitaly_token'] = 'secret token' + +### For storing GitLab application uploads, eg. LFS objects, build artifacts +###! Docs: https://docs.gitlab.com/ee/development/shared_files.html +# gitlab_rails['shared_path'] = '/var/opt/gitlab/gitlab-rails/shared' + +### For storing encrypted configuration files +###! Docs: https://docs.gitlab.com/ee/administration/encrypted_configuration.html +# gitlab_rails['encrypted_settings_path'] = '/var/opt/gitlab/gitlab-rails/shared/encrypted_settings' + +### Wait for file system to be mounted +###! Docs: https://docs.gitlab.com/omnibus/settings/configuration.html#only-start-omnibus-gitlab-services-after-a-given-file-system-is-mounted +# high_availability['mountpoint'] = ["/var/opt/gitlab/git-data", "/var/opt/gitlab/gitlab-rails/shared"] + +### GitLab Shell settings for GitLab +# gitlab_rails['gitlab_shell_ssh_port'] = 22 +# gitlab_rails['gitlab_shell_git_timeout'] = 800 + +### Extra customization +# gitlab_rails['extra_google_analytics_id'] = '_your_tracking_id' +# gitlab_rails['extra_google_tag_manager_id'] = '_your_tracking_id' +# gitlab_rails['extra_one_trust_id'] = '_your_one_trust_id' +# gitlab_rails['extra_google_tag_manager_nonce_id'] = '_your_google_tag_manager_id' +# gitlab_rails['extra_bizible'] = false +# gitlab_rails['extra_matomo_url'] = '_your_matomo_url' +# gitlab_rails['extra_matomo_site_id'] = '_your_matomo_site_id' +# gitlab_rails['extra_matomo_disable_cookies'] = false +# gitlab_rails['extra_maximum_text_highlight_size_kilobytes'] = 512 + +##! Docs: https://docs.gitlab.com/omnibus/settings/environment-variables.html +# gitlab_rails['env'] = { +# 'BUNDLE_GEMFILE' => "/opt/gitlab/embedded/service/gitlab-rails/Gemfile", +# 'PATH' => "/opt/gitlab/bin:/opt/gitlab/embedded/bin:/bin:/usr/bin" +# } + +# gitlab_rails['rack_attack_git_basic_auth'] = { +# 'enabled' => false, +# 'ip_whitelist' => ["127.0.0.1"], +# 'maxretry' => 10, +# 'findtime' => 60, +# 'bantime' => 3600 +# } + +# gitlab_rails['dir'] = "/var/opt/gitlab/gitlab-rails" +# gitlab_rails['log_directory'] = "/var/log/gitlab/gitlab-rails" +# gitlab_rails['log_group'] = nil + +#### Change the initial default admin password and shared runner registration tokens. +####! **Only applicable on initial setup, changing these settings after database +####! is created and seeded won't yield any change.** +# gitlab_rails['initial_root_password'] = "password" +# gitlab_rails['initial_shared_runners_registration_token'] = "token" + +#### Toggle if root password should be printed to STDOUT during initialization +# gitlab_rails['display_initial_root_password'] = false + +#### Toggle if initial root password should be written to /etc/gitlab/initial_root_password +# gitlab_rails['store_initial_root_password'] = true + +#### Set path to an initial license to be used while bootstrapping GitLab. +####! **Only applicable on initial setup, future license updates need to be done via UI. +####! Updating the file specified in this path won't yield any change after the first reconfigure run. +# gitlab_rails['initial_license_file'] = '/etc/gitlab/company.gitlab-license' + +#### Enable or disable automatic database migrations +# gitlab_rails['auto_migrate'] = true + +#### This is advanced feature used by large gitlab deployments where loading +#### whole RAILS env takes a lot of time. +# gitlab_rails['rake_cache_clear'] = true + +### GitLab database settings +###! Docs: https://docs.gitlab.com/omnibus/settings/database.html +###! **Only needed if you use an external database.** +# gitlab_rails['db_adapter'] = "postgresql" +# gitlab_rails['db_encoding'] = "unicode" +# gitlab_rails['db_collation'] = nil +# gitlab_rails['db_database'] = "gitlabhq_production" +# gitlab_rails['db_username'] = "gitlab" +# gitlab_rails['db_password'] = nil +# gitlab_rails['db_host'] = nil +# gitlab_rails['db_port'] = 5432 +# gitlab_rails['db_socket'] = nil +# gitlab_rails['db_sslmode'] = nil +# gitlab_rails['db_sslcompression'] = 0 +# gitlab_rails['db_sslrootcert'] = nil +# gitlab_rails['db_sslcert'] = nil +# gitlab_rails['db_sslkey'] = nil +# gitlab_rails['db_prepared_statements'] = false +# gitlab_rails['db_statements_limit'] = 1000 +# gitlab_rails['db_connect_timeout'] = nil +# gitlab_rails['db_keepalives'] = nil +# gitlab_rails['db_keepalives_idle'] = nil +# gitlab_rails['db_keepalives_interval'] = nil +# gitlab_rails['db_keepalives_count'] = nil +# gitlab_rails['db_tcp_user_timeout'] = nil +# gitlab_rails['db_application_name'] = nil +# gitlab_rails['db_database_tasks'] = true + +### Gitlab decomposed database settings +###! Docs: https://docs.gitlab.com/omnibus/settings/database.html +# gitlab_rails['databases']['ci']['enable'] = true +# gitlab_rails['databases']['ci']['db_database'] = 'gitlabhq_production' +# gitlab_rails['databases']['ci']['database_tasks'] = false + +### GitLab Redis settings +###! Connect to your own Redis instance +###! Docs: https://docs.gitlab.com/omnibus/settings/redis.html + +#### Redis TCP connection +# gitlab_rails['redis_host'] = "127.0.0.1" +# gitlab_rails['redis_port'] = 6379 +# gitlab_rails['redis_ssl'] = false +# gitlab_rails['redis_password'] = nil +# gitlab_rails['redis_database'] = 0 +# gitlab_rails['redis_enable_client'] = true + +#### Redis local UNIX socket (will be disabled if TCP method is used) +# gitlab_rails['redis_socket'] = "/var/opt/gitlab/redis/redis.socket" + +#### Sentinel support +####! To have Sentinel working, you must enable Redis TCP connection support +####! above and define a few Sentinel hosts below (to get a reliable setup +####! at least 3 hosts). +####! **You don't need to list every sentinel host, but the ones not listed will +####! not be used in a fail-over situation to query for the new master.** +# gitlab_rails['redis_sentinels'] = [ +# {'host' => '127.0.0.1', 'port' => 26379}, +# ] +# gitlab_rails['redis_sentinels_password'] = 'sentinel-requirepass-goes-here' + +#### Cluster support +####! Cluster support is only available for selected Redis instances. `resque.yml` will not +####! support cluster mode to maintain full-compatibility with the GitLab rails application. +####! +####! To have Redis Cluster working, you must declare `redis_{instance}_cluster_nodes` +####! `redis_{instance}_username` and `redis_{instance}_password` are required if ACL +####! is enabled for the Redis servers. +# gitlab_rails['redis_xxxx_cluster_nodes'] = [ +# {'host' => '127.0.0.1', 'port' => 6379}, +# ] + +#### Separate instances support +###! Docs: https://docs.gitlab.com/omnibus/settings/redis.html#running-with-multiple-redis-instances +# gitlab_rails['redis_cache_instance'] = nil +# gitlab_rails['redis_cache_sentinels'] = nil +# gitlab_rails['redis_cache_sentinels_password'] = nil +# gitlab_rails['redis_cache_username'] = nil +# gitlab_rails['redis_cache_password'] = nil +# gitlab_rails['redis_cache_cluster_nodes'] = nil +# gitlab_rails['redis_queues_instance'] = nil +# gitlab_rails['redis_queues_sentinels'] = nil +# gitlab_rails['redis_queues_sentinels_password'] = nil +# gitlab_rails['redis_queues_username'] = nil +# gitlab_rails['redis_queues_password'] = nil +# gitlab_rails['redis_queues_cluster_nodes'] = nil +# gitlab_rails['redis_shared_state_instance'] = nil +# gitlab_rails['redis_shared_state_sentinels'] = nil +# gitlab_rails['redis_shared_state_sentinels_password'] = nil +# gitlab_rails['redis_shared_state_username'] = nil +# gitlab_rails['redis_shared_state_password'] = nil +# gitlab_rails['redis_shared_state_cluster_nodes'] = nil +# gitlab_rails['redis_trace_chunks_instance'] = nil +# gitlab_rails['redis_trace_chunks_sentinels'] = nil +# gitlab_rails['redis_trace_chunks_sentinels_password'] = nil +# gitlab_rails['redis_trace_chunks_username'] = nil +# gitlab_rails['redis_trace_chunks_password'] = nil +# gitlab_rails['redis_trace_chunks_cluster_nodes'] = nil +# gitlab_rails['redis_actioncable_instance'] = nil +# gitlab_rails['redis_actioncable_sentinels'] = nil +# gitlab_rails['redis_actioncable_sentinels_password'] = nil +# gitlab_rails['redis_actioncable_username'] = nil +# gitlab_rails['redis_actioncable_password'] = nil +# gitlab_rails['redis_actioncable_cluster_nodes'] = nil +# gitlab_rails['redis_rate_limiting_instance'] = nil +# gitlab_rails['redis_rate_limiting_sentinels'] = nil +# gitlab_rails['redis_rate_limiting_sentinels_password'] = nil +# gitlab_rails['redis_rate_limiting_username'] = nil +# gitlab_rails['redis_rate_limiting_password'] = nil +# gitlab_rails['redis_rate_limiting_cluster_nodes'] = nil +# gitlab_rails['redis_sessions_instance'] = nil +# gitlab_rails['redis_sessions_sentinels'] = nil +# gitlab_rails['redis_sessions_sentinels_password'] = nil +# gitlab_rails['redis_sessions_username'] = nil +# gitlab_rails['redis_sessions_password'] = nil +# gitlab_rails['redis_sessions_cluster_nodes'] = nil +# gitlab_rails['redis_cluster_rate_limiting_instance'] = nil +# gitlab_rails['redis_cluster_rate_limiting_sentinels'] = nil +# gitlab_rails['redis_cluster_rate_limiting_sentinels_password'] = nil +# gitlab_rails['redis_cluster_rate_limiting_username'] = nil +# gitlab_rails['redis_cluster_rate_limiting_password'] = nil +# gitlab_rails['redis_cluster_rate_limiting_cluster_nodes'] = nil +# gitlab_rails['redis_repository_cache_instance'] = nil +# gitlab_rails['redis_repository_cache_sentinels'] = nil +# gitlab_rails['redis_repository_cache_sentinels_password'] = nil +# gitlab_rails['redis_repository_cache_username'] = nil +# gitlab_rails['redis_repository_cache_password'] = nil +# gitlab_rails['redis_repository_cache_cluster_nodes'] = nil + + +# gitlab_rails['redis_yml_override'] = nil + +################################################################################ +## Container Registry settings +##! Docs: https://docs.gitlab.com/ee/administration/packages/container_registry.html +################################################################################ + +# registry_external_url 'https://registry.example.com' + +### Settings used by GitLab application +# gitlab_rails['registry_enabled'] = true +# gitlab_rails['registry_host'] = "registry.gitlab.example.com" +# gitlab_rails['registry_port'] = "5005" +# gitlab_rails['registry_path'] = "/var/opt/gitlab/gitlab-rails/shared/registry" + +# Notification secret, it's used to authenticate notification requests to GitLab application +# You only need to change this when you use external Registry service, otherwise +# it will be taken directly from notification settings of your Registry +# gitlab_rails['registry_notification_secret'] = nil + +###! **Do not change the following 3 settings unless you know what you are +###! doing** +# gitlab_rails['registry_api_url'] = "http://127.0.0.1:5000" +# gitlab_rails['registry_key_path'] = "/var/opt/gitlab/gitlab-rails/certificate.key" +# gitlab_rails['registry_issuer'] = "omnibus-gitlab-issuer" + +### Settings used by Registry application +# registry['enable'] = true +# registry['username'] = "registry" +# registry['group'] = "registry" +# registry['uid'] = nil +# registry['gid'] = nil +# registry['dir'] = "/var/opt/gitlab/registry" +# registry['registry_http_addr'] = "127.0.0.1:5000" +# registry['debug_addr'] = "localhost:5001" +# registry['log_directory'] = "/var/log/gitlab/registry" +# registry['env_directory'] = "/opt/gitlab/etc/registry/env" +# registry['env'] = { +# 'SSL_CERT_DIR' => "/opt/gitlab/embedded/ssl/certs/" +# } +# registry['log_level'] = "info" +# registry['log_formatter'] = "text" +# registry['rootcertbundle'] = "/var/opt/gitlab/registry/certificate.crt" +# registry['health_storagedriver_enabled'] = true +# registry['middleware'] = nil +# registry['storage_delete_enabled'] = true +# registry['validation_enabled'] = false +# registry['autoredirect'] = false +# registry['compatibility_schema1_enabled'] = false + +### Registry backend storage +###! Docs: https://docs.gitlab.com/ee/administration/packages/container_registry.html#configure-storage-for-the-container-registry +# registry['storage'] = { +# 's3' => { +# 'accesskey' => 's3-access-key', +# 'secretkey' => 's3-secret-key-for-access-key', +# 'bucket' => 'your-s3-bucket', +# 'region' => 'your-s3-region', +# 'regionendpoint' => 'your-s3-regionendpoint' +# }, +# 'redirect' => { +# 'disable' => false +# } +# } + +### Registry notifications endpoints +# registry['notifications'] = [ +# { +# 'name' => 'test_endpoint', +# 'url' => 'https://gitlab.example.com/notify2', +# 'timeout' => '500ms', +# 'threshold' => 5, +# 'backoff' => '1s', +# 'headers' => { +# "Authorization" => ["AUTHORIZATION_EXAMPLE_TOKEN"] +# } +# } +# ] +### Default registry notifications +# registry['default_notifications_timeout'] = "500ms" +# registry['default_notifications_threshold'] = 5 +# registry['default_notifications_backoff'] = "1s" +# registry['default_notifications_headers'] = {} + +################################################################################ +## Error Reporting and Logging with Sentry +################################################################################ +# gitlab_rails['sentry_enabled'] = false +# gitlab_rails['sentry_dsn'] = 'https://@sentry.io/' +# gitlab_rails['sentry_clientside_dsn'] = 'https://@sentry.io/' +# gitlab_rails['sentry_environment'] = 'production' + +################################################################################ +## CI_JOB_JWT +################################################################################ +##! RSA private key used to sign CI_JOB_JWT +# gitlab_rails['ci_jwt_signing_key'] = nil # Will be generated if not set. + +################################################################################ +## GitLab Workhorse +##! Docs: https://gitlab.com/gitlab-org/gitlab/-/blob/master/workhorse/README.md +################################################################################ + +# gitlab_workhorse['enable'] = true +# gitlab_workhorse['ha'] = false +# gitlab_workhorse['alt_document_root'] = nil + +##! Duration to wait for all requests to finish (e.g. "10s" for 10 +##! seconds). By default this is disabled to preserve the existing +##! behavior of fast shutdown. This should not be set higher than 30 +##! seconds, since gitlab-ctl will wait up to 30 seconds (as defined by +##! the SVWAIT variable) and report a timeout error if the process has +##! not shut down. +# gitlab_workhorse['shutdown_timeout'] = nil +# gitlab_workhorse['listen_network'] = "unix" +# gitlab_workhorse['listen_umask'] = 000 +# gitlab_workhorse['listen_addr'] = "/var/opt/gitlab/gitlab-workhorse/sockets/socket" +# gitlab_workhorse['auth_backend'] = "http://localhost:8080" + +##! Enable Redis keywatcher, if this setting is not present it defaults to true +# gitlab_workhorse['workhorse_keywatcher'] = true + +##! the empty string is the default in gitlab-workhorse option parser +# gitlab_workhorse['auth_socket'] = "''" + +##! put an empty string on the command line +# gitlab_workhorse['pprof_listen_addr'] = "''" + +# gitlab_workhorse['prometheus_listen_addr'] = "localhost:9229" + +# gitlab_workhorse['dir'] = "/var/opt/gitlab/gitlab-workhorse" +# gitlab_workhorse['log_directory'] = "/var/log/gitlab/gitlab-workhorse" +# gitlab_workhorse['proxy_headers_timeout'] = "1m0s" + +##! limit number of concurrent API requests, defaults to 0 which is unlimited +# gitlab_workhorse['api_limit'] = 0 + +##! limit number of API requests allowed to be queued, defaults to 0 which +##! disables queuing +# gitlab_workhorse['api_queue_limit'] = 0 + +##! duration after which we timeout requests if they sit too long in the queue +# gitlab_workhorse['api_queue_duration'] = "30s" + +##! Long polling duration for job requesting for runners +# gitlab_workhorse['api_ci_long_polling_duration'] = "60s" + +##! Propagate X-Request-Id if available. Workhorse will generate a random value otherwise. +# gitlab_workhorse['propagate_correlation_id'] = false + +##! A list of CIDR blocks to allow for propagation of correlation ID. +##! propagate_correlation_id should also be set to true. +##! For example: %w(127.0.0.1/32 192.168.0.1/32) +# gitlab_workhorse['trusted_cidrs_for_propagation'] = nil + +##! A list of CIDR blocks that must match remote IP addresses to use +##! X-Forwarded-For HTTP header for the actual client IP. Used in +##! conjuction with propagate_correlation_id and +##! trusted_cidrs_for_propagation. +##! For example: %w(127.0.0.1/32 192.168.0.1/32) +# gitlab_workhorse['trusted_cidrs_for_x_forwarded_for'] = nil + +##! Log format: default is json, can also be text or none. +# gitlab_workhorse['log_format'] = "json" + +# gitlab_workhorse['env_directory'] = "/opt/gitlab/etc/gitlab-workhorse/env" +# gitlab_workhorse['env'] = { +# 'PATH' => "/opt/gitlab/bin:/opt/gitlab/embedded/bin:/bin:/usr/bin", +# 'SSL_CERT_DIR' => "/opt/gitlab/embedded/ssl/certs/" +# } + +##! Resource limitations for the dynamic image scaler. +##! Exceeding these thresholds will cause Workhorse to serve images in their original size. +##! +##! Maximum number of scaler processes that are allowed to execute concurrently. +##! It is recommended for this not to exceed the number of CPUs available. +# gitlab_workhorse['image_scaler_max_procs'] = 4 +##! +##! Maximum file size in bytes for an image to be considered eligible for rescaling +# gitlab_workhorse['image_scaler_max_filesize'] = 250000 + +##! Service name used to register GitLab Workhorse as a Consul service +# gitlab_workhorse['consul_service_name'] = 'workhorse' +##! Semantic metadata used when registering GitLab Workhorse as a Consul service +# gitlab_workhorse['consul_service_meta'] = {} + +################################################################################ +## GitLab User Settings +##! Modify default git user. +##! Docs: https://docs.gitlab.com/omnibus/settings/configuration.html#change-the-name-of-the-git-user-or-group +################################################################################ + +# user['username'] = "git" +# user['group'] = "git" +# user['uid'] = nil +# user['gid'] = nil + +##! The shell for the git user +# user['shell'] = "/bin/sh" + +##! The home directory for the git user +# user['home'] = "/var/opt/gitlab" + +# user['git_user_name'] = "GitLab" +# user['git_user_email'] = "gitlab@#{node['fqdn']}" + +################################################################################ +## GitLab Puma +##! Tweak puma settings. +##! Docs: https://docs.gitlab.com/ee/administration/operations/puma.html +################################################################################ + +# puma['enable'] = true +# puma['ha'] = false +# puma['worker_timeout'] = 60 +# puma['worker_processes'] = 2 +# puma['min_threads'] = 4 +# puma['max_threads'] = 4 + +### Advanced settings +# puma['listen'] = '127.0.0.1' +# puma['port'] = 8080 +# puma['socket'] = '/var/opt/gitlab/gitlab-rails/sockets/gitlab.socket' +# puma['somaxconn'] = 1024 + +### SSL settings +# puma['ssl_listen'] = nil +# puma['ssl_port'] = nil +# puma['ssl_certificate'] = nil +# puma['ssl_certificate_key'] = nil +# puma['ssl_client_certificate'] = nil +# puma['ssl_cipher_filter'] = nil +# puma['ssl_key_password_command'] = nil +# puma['ssl_verify_mode'] = 'none' + +# puma['pidfile'] = '/opt/gitlab/var/puma/puma.pid' +# puma['state_path'] = '/opt/gitlab/var/puma/puma.state' + +###! **We do not recommend changing this setting** +# puma['log_directory'] = "/var/log/gitlab/puma" + +### **Only change these settings if you understand well what they mean** +###! Docs: https://github.com/schneems/puma_worker_killer +# puma['per_worker_max_memory_mb'] = 1024 + +# puma['exporter_enabled'] = false +# puma['exporter_address'] = "127.0.0.1" +# puma['exporter_port'] = 8083 +# puma['exporter_tls_enabled'] = false +# puma['exporter_tls_cert_path'] = "" +# puma['exporter_tls_key_path'] = "" + +# puma['prometheus_scrape_scheme'] = 'http' +# puma['prometheus_scrape_tls_server_name'] = 'localhost' +# puma['prometheus_scrape_tls_skip_verification'] = false + +##! Service name used to register Puma as a Consul service +# puma['consul_service_name'] = 'rails' +##! Semantic metadata used when registering Puma as a Consul service +# puma['consul_service_meta'] = {} + +################################################################################ +## GitLab Sidekiq +################################################################################ + +##! GitLab allows one to start multiple sidekiq processes. These +##! processes can be used to consume a dedicated set of queues. This +##! can be used to ensure certain queues are able to handle additional workload. +##! https://docs.gitlab.com/ee/administration/operations/extra_sidekiq_processes.html + +# sidekiq['enable'] = true +# sidekiq['log_directory'] = "/var/log/gitlab/sidekiq" +# sidekiq['log_format'] = "json" +# sidekiq['shutdown_timeout'] = 4 +# sidekiq['interval'] = nil +# sidekiq['max_concurrency'] = 20 +# sidekiq['min_concurrency'] = nil + +##! GitLab allows route a job to a particular queue determined by an array of ##! routing rules. +##! Each routing rule is a tuple of queue selector query and corresponding queue. By default, +##! the routing rules are not configured (empty array) + +# sidekiq['routing_rules'] = [] + +##! Each entry in the queue_groups array denotes a group of queues that have to be processed by a +##! Sidekiq process. Multiple queues can be processed by the same process by +##! separating them with a comma within the group entry, a `*` will process all queues + +# sidekiq['queue_groups'] = ['*'] + +##! Specifies where Prometheus metrics endpoints should be made available for Sidekiq processes. +# sidekiq['metrics_enabled'] = true +# sidekiq['exporter_log_enabled'] = false +# sidekiq['exporter_tls_enabled'] = false +# sidekiq['exporter_tls_cert_path'] = "" +# sidekiq['exporter_tls_key_path'] = "" +# sidekiq['listen_address'] = "localhost" +# sidekiq['listen_port'] = 8082 + +##! Specifies where health-check endpoints should be made available for Sidekiq processes. +##! Defaults to the same settings as for Prometheus metrics (see above). +# sidekiq['health_checks_enabled'] = true +# sidekiq['health_checks_listen_address'] = "localhost" +# sidekiq['health_checks_listen_port'] = 8092 + +##! Service name used to register Sidekiq as a Consul service +# sidekiq['consul_service_name'] = 'sidekiq' +##! Semantic metadata used when registering Sidekiq as a Consul service +# sidekiq['consul_service_meta'] = {} + +################################################################################ +## gitlab-shell +################################################################################ + +# gitlab_shell['audit_usernames'] = false +# gitlab_shell['log_level'] = 'INFO' +# gitlab_shell['log_format'] = 'json' +# gitlab_shell['http_settings'] = { user: 'username', password: 'password', ca_file: '/etc/ssl/cert.pem', ca_path: '/etc/pki/tls/certs'} +# gitlab_shell['log_directory'] = "/var/log/gitlab/gitlab-shell" + +# gitlab_shell['auth_file'] = "/var/opt/gitlab/.ssh/authorized_keys" + +### Migration to Go feature flags +###! Docs: https://gitlab.com/gitlab-org/gitlab-shell#migration-to-go-feature-flags +# gitlab_shell['migration'] = { enabled: true, features: [] } + +### Git trace log file. +###! If set, git commands receive GIT_TRACE* environment variables +###! Docs: https://git-scm.com/book/es/v2/Git-Internals-Environment-Variables#Debugging +###! An absolute path starting with / – the trace output will be appended to +###! that file. It needs to exist so we can check permissions and avoid +###! throwing warnings to the users. +# gitlab_shell['git_trace_log_file'] = "/var/log/gitlab/gitlab-shell/gitlab-shell-git-trace.log" + +##! **We do not recommend changing this directory.** +# gitlab_shell['dir'] = "/var/opt/gitlab/gitlab-shell" + +################################################################################ +## gitlab-sshd +################################################################################ + +# gitlab_sshd['enable'] = false +# gitlab_sshd['generate_host_keys'] = true +# gitlab_sshd['dir'] = "/var/opt/gitlab/gitlab-sshd" + +# gitlab-sshd outputs most logs to /var/log/gitlab/gitlab-shell/gitlab-shell.log. +# This directory only stores stdout/stderr output from the daemon. +# gitlab_sshd['log_directory'] = "/var/log/gitlab/gitlab-sshd/" + +# gitlab_sshd['env_directory'] = '/opt/gitlab/etc/gitlab-sshd/env' +# gitlab_sshd['listen_address'] = 'localhost:2222' +# gitlab_sshd['metrics_address'] = 'localhost:9122' +# gitlab_sshd['concurrent_sessions_limit'] = 100 +# gitlab_sshd['proxy_protocol'] = false +# gitlab_sshd['proxy_policy'] = 'use' +# gitlab_sshd['proxy_header_timeout'] = '500ms' +# gitlab_sshd['grace_period'] = 55 +# gitlab_sshd['client_alive_interval'] = nil +# gitlab_sshd['ciphers'] = nil +# gitlab_sshd['kex_algorithms'] = nil +# gitlab_sshd['macs'] = nil +# gitlab_sshd['login_grace_time'] = 60 +# gitlab_sshd['host_keys_dir'] = '/var/opt/gitlab/gitlab-sshd' +# gitlab_sshd['host_keys_glob'] = 'ssh_host_*_key' +# gitlab_sshd['host_certs_dir'] = '/var/opt/gitlab/gitlab-sshd' +# gitlab_sshd['host_certs_glob'] = 'ssh_host_*-cert.pub' + +################################################################ +## GitLab PostgreSQL +################################################################ + +###! Changing any of these settings requires a restart of postgresql. +###! By default, reconfigure reloads postgresql if it is running. If you +###! change any of these settings, be sure to run `gitlab-ctl restart postgresql` +###! after reconfigure in order for the changes to take effect. +# postgresql['enable'] = true +# postgresql['listen_address'] = nil +# postgresql['port'] = 5432 + +## Only used when Patroni is enabled. This is the port that PostgreSQL responds to other +## cluster members. This port is used by Patroni to advertize the PostgreSQL connection +## endpoint to the cluster. By default it is the same as postgresql['port']. +# postgresql['connect_port'] = 5432 + +##! **recommend value is 1/4 of total RAM, up to 14GB.** +# postgresql['shared_buffers'] = "256MB" + +### Advanced settings +# postgresql['ha'] = false +# postgresql['dir'] = "/var/opt/gitlab/postgresql" +# postgresql['log_directory'] = "/var/log/gitlab/postgresql" +# postgresql['log_destination'] = nil +# postgresql['logging_collector'] = nil +# postgresql['log_truncate_on_rotation'] = nil +# postgresql['log_rotation_age'] = nil +# postgresql['log_rotation_size'] = nil +##! 'username' affects the system and PostgreSQL user accounts created during installation and cannot be changed +##! on an existing installation. See https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/3606 for more details. +# postgresql['username'] = "gitlab-psql" +# postgresql['group'] = "gitlab-psql" +##! `SQL_USER_PASSWORD_HASH` can be generated using the command `gitlab-ctl pg-password-md5 gitlab` +# postgresql['sql_user_password'] = 'SQL_USER_PASSWORD_HASH' +# postgresql['uid'] = nil +# postgresql['gid'] = nil +# postgresql['shell'] = "/bin/sh" +# postgresql['home'] = "/var/opt/gitlab/postgresql" +# postgresql['user_path'] = "/opt/gitlab/embedded/bin:/opt/gitlab/bin:$PATH" +# postgresql['sql_user'] = "gitlab" +# postgresql['max_connections'] = 400 +# postgresql['md5_auth_cidr_addresses'] = [] +# postgresql['trust_auth_cidr_addresses'] = [] +# postgresql['wal_buffers'] = "-1" +# postgresql['autovacuum_max_workers'] = "3" +# postgresql['autovacuum_freeze_max_age'] = "200000000" +# postgresql['log_statement'] = nil +# postgresql['track_activity_query_size'] = "1024" +# postgresql['shared_preload_libraries'] = nil +# postgresql['dynamic_shared_memory_type'] = nil +# postgresql['hot_standby'] = "off" + +### SSL settings +# See https://www.postgresql.org/docs/13/static/runtime-config-connection.html#GUC-SSL-CERT-FILE for more details +# postgresql['ssl'] = 'on' +# postgresql['hostssl'] = false +# postgresql['ssl_ciphers'] = 'HIGH:MEDIUM:+3DES:!aNULL:!SSLv3:!TLSv1' +# postgresql['ssl_cert_file'] = 'server.crt' +# postgresql['ssl_key_file'] = 'server.key' +# postgresql['ssl_ca_file'] = '/opt/gitlab/embedded/ssl/certs/cacert.pem' +# postgresql['ssl_crl_file'] = nil +# postgresql['cert_auth_addresses'] = { +# 'ADDRESS' => { +# database: 'gitlabhq_production', +# user: 'gitlab' +# } +# } + +### Replication settings +###! Note, some replication settings do not require a full restart. They are documented below. +# postgresql['wal_level'] = "hot_standby" +# postgresql['wal_log_hints'] = 'off' +# postgresql['max_wal_senders'] = 5 +# postgresql['max_replication_slots'] = 0 +# postgresql['max_locks_per_transaction'] = 128 + +# Backup/Archive settings +# postgresql['archive_mode'] = "off" + +###! Changing any of these settings only requires a reload of postgresql. You do not need to +###! restart postgresql if you change any of these and run reconfigure. +# postgresql['work_mem'] = "16MB" +# postgresql['maintenance_work_mem'] = "16MB" +# postgresql['checkpoint_timeout'] = "5min" +# postgresql['checkpoint_completion_target'] = 0.9 +# postgresql['effective_io_concurrency'] = 1 +# postgresql['checkpoint_warning'] = "30s" +# postgresql['effective_cache_size'] = "1MB" +# postgresql['shmmax'] = 17179869184 # or 4294967295 +# postgresql['shmall'] = 4194304 # or 1048575 +# postgresql['autovacuum'] = "on" +# postgresql['log_autovacuum_min_duration'] = "-1" +# postgresql['autovacuum_naptime'] = "1min" +# postgresql['autovacuum_vacuum_threshold'] = "50" +# postgresql['autovacuum_analyze_threshold'] = "50" +# postgresql['autovacuum_vacuum_scale_factor'] = "0.02" +# postgresql['autovacuum_analyze_scale_factor'] = "0.01" +# postgresql['autovacuum_vacuum_cost_delay'] = "20ms" +# postgresql['autovacuum_vacuum_cost_limit'] = "-1" +# postgresql['statement_timeout'] = "60000" +# postgresql['idle_in_transaction_session_timeout'] = "60000" +# postgresql['log_line_prefix'] = "%a" +# postgresql['max_worker_processes'] = 8 +# postgresql['max_parallel_workers_per_gather'] = 0 +# postgresql['log_lock_waits'] = 1 +# postgresql['deadlock_timeout'] = '5s' +# postgresql['track_io_timing'] = 0 +# postgresql['default_statistics_target'] = 1000 + +### Available in PostgreSQL 9.6 and later +# postgresql['min_wal_size'] = "80MB" +# postgresql['max_wal_size'] = "1GB" + +# Backup/Archive settings +# postgresql['archive_command'] = nil +# postgresql['archive_timeout'] = "0" + +### Replication settings +# postgresql['sql_replication_user'] = "gitlab_replicator" +# postgresql['sql_replication_password'] = "md5 hash of postgresql password" # You can generate with `gitlab-ctl pg-password-md5 ` +# postgresql['wal_keep_segments'] = 10 +# postgresql['max_standby_archive_delay'] = "30s" +# postgresql['max_standby_streaming_delay'] = "30s" +# postgresql['synchronous_commit'] = on +# postgresql['synchronous_standby_names'] = '' +# postgresql['hot_standby_feedback'] = 'off' +# postgresql['random_page_cost'] = 2.0 +# postgresql['log_temp_files'] = -1 +# postgresql['log_checkpoints'] = 'off' +# To add custom entries to pg_hba.conf use the following +# postgresql['custom_pg_hba_entries'] = { +# APPLICATION: [ # APPLICATION should identify what the settings are used for +# { +# type: example, +# database: example, +# user: example, +# cidr: example, +# method: example, +# option: example +# } +# ] +# } +# See https://www.postgresql.org/docs/13/static/auth-pg-hba-conf.html for an explanation +# of the values + +### Version settings +# Set this if you have disabled the bundled PostgreSQL but still want to use the backup rake tasks +# postgresql['version'] = 10 + + +##! Automatically restart PostgreSQL service when version changes. +# postgresql['auto_restart_on_version_change'] = true + +################################################################################ +## GitLab Redis +##! **Can be disabled if you are using your own Redis instance.** +##! Docs: https://docs.gitlab.com/omnibus/settings/redis.html +################################################################################ + +# redis['enable'] = true +# redis['ha'] = false +# redis['start_down'] = false +# redis['set_replicaof'] = false +# redis['hz'] = 10 +# redis['dir'] = "/var/opt/gitlab/redis" +# redis['log_directory'] = "/var/log/gitlab/redis" +# redis['log_group'] = nil +# redis['username'] = "gitlab-redis" +# redis['group'] = "gitlab-redis" +# redis['maxclients'] = "10000" +# redis['open_files_ulimit'] = nil # Maximum number of open files allowed for the redis process (defaults to ope +# redis['maxmemory'] = "0" +# redis['maxmemory_policy'] = "noeviction" +# redis['maxmemory_samples'] = "5" +# redis['stop_writes_on_bgsave_error'] = true +# redis['tcp_backlog'] = 511 +# redis['tcp_timeout'] = "60" +# redis['tcp_keepalive'] = "300" +# redis['uid'] = nil +# redis['gid'] = nil +# redis['startup_delay'] = 0 + +### Redis TLS settings +###! To run Redis over TLS, specify values for the following settings +# redis['tls_port'] = nil +# redis['tls_cert_file'] = nil +# redis['tls_key_file'] = nil + +###! Other TLS related optional settings +# redis['tls_dh_params_file'] = nil +# redis['tls_ca_cert_dir'] = '/opt/gitlab/embedded/ssl/certs/' +# redis['tls_ca_cert_file'] = '/opt/gitlab/embedded/ssl/certs/cacert.pem' +# redis['tls_auth_clients'] = 'optional' +# redis['tls_replication'] = nil +# redis['tls_cluster'] = nil +# redis['tls_protocols'] = nil +# redis['tls_ciphers'] = nil +# redis['tls_ciphersuites'] = nil +# redis['tls_prefer_server_ciphers'] = nil +# redis['tls_session_caching'] = nil +# redis['tls_session_cache_size'] = nil +# redis['tls_session_cache_timeout'] = nil + +### Disable or obfuscate unnecessary redis command names +### Uncomment and edit this block to add or remove entries. +### See https://docs.gitlab.com/omnibus/settings/redis.html#renamed-commands +### for detailed usage +### +# redis['rename_commands'] = { +# 'KEYS': '' +#} +# + +###! Configure timeout (in seconds) for runit's sv commands used for managing +###! the Redis service +# redis['runit_sv_timeout'] = nil + +###! **To enable only Redis service in this machine, uncomment +###! one of the lines below (choose master or replica instance types).** +###! Docs: https://docs.gitlab.com/omnibus/settings/redis.html +###! https://docs.gitlab.com/ee/administration/high_availability/redis.html +# redis_master_role['enable'] = true +# redis_replica_role['enable'] = true + +### Redis TCP support (will disable UNIX socket transport) +# redis['bind'] = '0.0.0.0' # or specify an IP to bind to a single one +# redis['port'] = 6379 +# redis['password'] = 'redis-password-goes-here' + +### Redis Sentinel support +###! **You need a master replica Redis replication to be able to do failover** +###! **Please read the documentation before enabling it to understand the +###! caveats:** +###! Docs: https://docs.gitlab.com/ee/administration/high_availability/redis.html + +### Replication support +#### Replica Redis instance +# redis['master'] = false # by default this is true + +#### Replica and Sentinel shared configuration +####! **Both need to point to the master Redis instance to get replication and +####! heartbeat monitoring** +# redis['master_name'] = 'gitlab-redis' +# redis['master_ip'] = nil +# redis['master_port'] = 6379 + +#### Support to run redis replicas in a Docker or NAT environment +####! Docs: https://redis.io/topics/replication#configuring-replication-in-docker-and-nat +# redis['announce_ip'] = nil +# redis['announce_port'] = nil +# redis['announce_ip_from_hostname'] = false + +####! **Master password should have the same value defined in +####! redis['password'] to enable the instance to transition to/from +####! master/replica in a failover event.** +# redis['master_password'] = 'redis-password-goes-here' + +####! Increase these values when your replicas can't catch up with master +# redis['client_output_buffer_limit_normal'] = '0 0 0' +# redis['client_output_buffer_limit_replica'] = '256mb 64mb 60' +# redis['client_output_buffer_limit_pubsub'] = '32mb 8mb 60' + +#####! Redis snapshotting frequency +#####! Set to [] to disable +#####! Set to [''] to clear previously set values +# redis['save'] = [ '900 1', '300 10', '60 10000' ] + +#####! Redis lazy freeing +#####! Defaults to false +# redis['lazyfree_lazy_eviction'] = true +# redis['lazyfree_lazy_expire'] = true +# redis['lazyfree_lazy_server_del'] = true +# redis['replica_lazy_flush'] = true + +#####! Redis threaded I/O +#####! Defaults to disabled +# redis['io_threads'] = 4 +# redis['io_threads_do_reads'] = true + +################################################################################ +## GitLab Web server +##! Docs: https://docs.gitlab.com/omnibus/settings/nginx.html#using-a-non-bundled-web-server +################################################################################ + +##! When bundled nginx is disabled we need to add the external webserver user to +##! the GitLab webserver group. +# web_server['external_users'] = [] +# web_server['username'] = 'gitlab-www' +# web_server['group'] = 'gitlab-www' +# web_server['uid'] = nil +# web_server['gid'] = nil +# web_server['shell'] = '/bin/false' +# web_server['home'] = '/var/opt/gitlab/nginx' + +################################################################################ +## GitLab NGINX +##! Docs: https://docs.gitlab.com/omnibus/settings/nginx.html +################################################################################ + +# nginx['enable'] = true +# nginx['client_max_body_size'] = '250m' +# nginx['redirect_http_to_https'] = false +# nginx['redirect_http_to_https_port'] = 80 + +##! Most root CA's are included by default +# nginx['ssl_client_certificate'] = "/etc/gitlab/ssl/ca.crt" + +##! enable/disable 2-way SSL client authentication +# nginx['ssl_verify_client'] = "off" + +##! if ssl_verify_client on, verification depth in the client certificates chain +# nginx['ssl_verify_depth'] = "1" + +# nginx['ssl_certificate'] = "/etc/gitlab/ssl/#{node['fqdn']}.crt" +# nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/#{node['fqdn']}.key" +# nginx['ssl_ciphers'] = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384" +# nginx['ssl_prefer_server_ciphers'] = "off" + +##! **Recommended by: https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html +##! https://cipherli.st/** +# nginx['ssl_protocols'] = "TLSv1.2 TLSv1.3" + +##! **Recommended in: https://nginx.org/en/docs/http/ngx_http_ssl_module.html** +# nginx['ssl_session_cache'] = "shared:SSL:10m" + +##! **Recommended in: https://ssl-config.mozilla.org/#server=nginx&version=1.17.7&config=intermediate&openssl=1.1.1d&ocsp=false&guideline=5.6** +# nginx['ssl_session_tickets'] = "off" + +##! **Default according to https://nginx.org/en/docs/http/ngx_http_ssl_module.html** +# nginx['ssl_session_timeout'] = "1d" + +# nginx['ssl_dhparam'] = nil # Path to dhparams.pem, eg. /etc/gitlab/ssl/dhparams.pem +# nginx['ssl_password_file'] = nil # Path to file with passphrases for ssl certificate secret keys +# nginx['listen_addresses'] = ['*', '[::]'] + +##! **Defaults to forcing web browsers to always communicate using only HTTPS** +##! Docs: https://docs.gitlab.com/omnibus/settings/nginx.html#setting-http-strict-transport-security +# nginx['hsts_max_age'] = 63072000 +# nginx['hsts_include_subdomains'] = false + +##! Defaults to stripping path information when making cross-origin requests +# nginx['referrer_policy'] = 'strict-origin-when-cross-origin' + +##! **Docs: http://nginx.org/en/docs/http/ngx_http_gzip_module.html** +# nginx['gzip_enabled'] = true +nginx['gzip_enabled'] = true + +##! **Override only if you use a reverse proxy** +##! Docs: https://docs.gitlab.com/omnibus/settings/nginx.html#setting-the-nginx-listen-port +# nginx['listen_port'] = nil +nginx['listen_port'] = 80 + +##! **Override only if your reverse proxy internally communicates over HTTP** +##! Docs: https://docs.gitlab.com/omnibus/settings/nginx.html#supporting-proxied-ssl +# nginx['listen_https'] = nil +nginx['listen_https'] = false + +##! **Override only if you use a reverse proxy with proxy protocol enabled** +##! Docs: https://docs.gitlab.com/omnibus/settings/nginx.html#configuring-proxy-protocol +# nginx['proxy_protocol'] = false + +# nginx['custom_gitlab_server_config'] = "location ^~ /foo-namespace/bar-project/raw/ {\n deny all;\n}\n" +# nginx['custom_nginx_config'] = "include /etc/nginx/conf.d/example.conf;" + nginx['custom_nginx_config'] = "include {{nginx_custom_file_path}}/nginx_custom.conf;" +# nginx['proxy_read_timeout'] = 3600 +# nginx['proxy_connect_timeout'] = 300 +nginx['proxy_connect_timeout'] = 3600 +# nginx['proxy_set_headers'] = { +# "Host" => "$http_host_with_default", +# "X-Real-IP" => "$remote_addr", +# "X-Forwarded-For" => "$proxy_add_x_forwarded_for", +# "X-Forwarded-Proto" => "https", +# "X-Forwarded-Ssl" => "on", +# "Upgrade" => "$http_upgrade", +# "Connection" => "$connection_upgrade" +# } +# nginx['proxy_cache_path'] = 'proxy_cache keys_zone=gitlab:10m max_size=1g levels=1:2' +# nginx['proxy_cache'] = 'gitlab' +# nginx['proxy_custom_buffer_size'] = '4k' +# nginx['http2_enabled'] = true +# nginx['real_ip_trusted_addresses'] = [] +# nginx['real_ip_header'] = nil +# nginx['real_ip_recursive'] = nil +# nginx['custom_error_pages'] = { +# '404' => { +# 'title' => 'Example title', +# 'header' => 'Example header', +# 'message' => 'Example message' +# } +# } + +### Advanced settings +# nginx['dir'] = "/var/opt/gitlab/nginx" +# nginx['log_directory'] = "/var/log/gitlab/nginx" +# nginx['log_group'] = nil +# nginx['error_log_level'] = "error" +nginx['error_log_level'] = "info" +# nginx['worker_processes'] = 4 +# nginx['worker_connections'] = 10240 +# nginx['log_format'] = '$remote_addr - $remote_user [$time_local] "$request_method $filtered_request_uri $server_protocol" $status $body_bytes_sent "$filtered_http_referer" "$http_user_agent" $gzip_ratio' +# nginx['sendfile'] = 'on' +# nginx['tcp_nopush'] = 'on' +# nginx['tcp_nodelay'] = 'on' +# nginx['hide_server_tokens'] = 'off' +# nginx['gzip_http_version'] = "1.0" +# nginx['gzip_comp_level'] = "2" +# nginx['gzip_proxied'] = "any" +# nginx['gzip_types'] = [ "text/plain", "text/css", "application/x-javascript", "text/xml", "application/xml", "application/xml+rss", "text/javascript", "application/json" ] +# nginx['keepalive_timeout'] = 65 +nginx['keepalive_timeout'] = 3600 +# nginx['keepalive_time'] = '1h' +# nginx['cache_max_size'] = '5000m' +# nginx['server_names_hash_bucket_size'] = 64 +##! These paths have proxy_request_buffering disabled +# nginx['request_buffering_off_path_regex'] = "/api/v\\d/jobs/\\d+/artifacts$|/import/gitlab_project$|\\.git/git-receive-pack$|\\.git/gitlab-lfs/objects|\\.git/info/lfs/objects/batch$" + +### Nginx status +# nginx['status'] = { +# "enable" => true, +# "listen_addresses" => ["127.0.0.1"], +# "fqdn" => "dev.example.com", +# "port" => 9999, +# "vts_enable" => true, +# "options" => { +# "server_tokens" => "off", # Don't show the version of NGINX +# "access_log" => "off", # Disable logs for stats +# "allow" => "127.0.0.1", # Only allow access from localhost +# "deny" => "all" # Deny access to anyone else +# } +# } + +##! Service name used to register Nginx as a Consul service +# nginx['consul_service_name'] = 'nginx' +##! Semantic metadata used when registering NGINX as a Consul service +# nginx['consul_service_meta'] = {} + +################################################################################ +## GitLab Logging +##! Docs: https://docs.gitlab.com/omnibus/settings/logs.html +################################################################################ + +# logging['svlogd_size'] = 200 * 1024 * 1024 # rotate after 200 MB of log data +# logging['svlogd_num'] = 30 # keep 30 rotated log files +# logging['svlogd_timeout'] = 24 * 60 * 60 # rotate after 24 hours +# logging['svlogd_filter'] = "gzip" # compress logs with gzip +# logging['svlogd_udp'] = nil # transmit log messages via UDP +# logging['svlogd_prefix'] = nil # custom prefix for log messages +# logging['logrotate_frequency'] = "daily" # rotate logs daily +# logging['logrotate_maxsize'] = nil # rotate logs when they grow bigger than size bytes even before the specified time interval (daily, weekly, monthly, or yearly) +# logging['logrotate_size'] = nil # do not rotate by size by default +# logging['logrotate_rotate'] = 30 # keep 30 rotated logs +# logging['logrotate_compress'] = "compress" # see 'man logrotate' +# logging['logrotate_method'] = "copytruncate" # see 'man logrotate' +# logging['logrotate_postrotate'] = nil # no postrotate command by default +# logging['logrotate_dateformat'] = nil # use date extensions for rotated files rather than numbers e.g. a value of "-%Y-%m-%d" would give rotated files like production.log-2016-03-09.gz +# logging['log_group'] = nil # assign this group to specified log directories and use it for runit-managed logs, can be overridden per-service + +### UDP log forwarding +##! Docs: http://docs.gitlab.com/omnibus/settings/logs.html#udp-log-forwarding + +##! remote host to ship log messages to via UDP +# logging['udp_log_shipping_host'] = nil + +##! override the hostname used when logs are shipped via UDP, +## by default the system hostname will be used. +# logging['udp_log_shipping_hostname'] = nil + +##! remote port to ship log messages to via UDP +# logging['udp_log_shipping_port'] = 514 + + +################################################################################ +## Logrotate +##! Docs: https://docs.gitlab.com/omnibus/settings/logs.html#logrotate +##! You can disable built in logrotate feature. +################################################################################ +# logrotate['enable'] = true +# logrotate['log_directory'] = "/var/log/gitlab/logrotate" +# logrotate['log_group'] = nil + +################################################################################ +## Users and groups accounts +##! Disable management of users and groups accounts. +##! **Set only if creating accounts manually** +##! Docs: https://docs.gitlab.com/omnibus/settings/configuration.html#disable-user-and-group-account-management +################################################################################ + +# manage_accounts['enable'] = true + +################################################################################ +## Storage directories +##! Disable managing storage directories +##! Docs: https://docs.gitlab.com/omnibus/settings/configuration.html#disable-storage-directories-management +################################################################################ + +##! **Set only if the select directories are created manually** +# manage_storage_directories['enable'] = false +# manage_storage_directories['manage_etc'] = false + +################################################################################ +## Runtime directory +##! Docs: https://docs.gitlab.com//omnibus/settings/configuration.html#configuring-runtime-directory +################################################################################ + +# runtime_dir '/run' + +################################################################################ +## Git +##! Advanced setting for configuring git system settings for omnibus-gitlab +##! internal git +################################################################################ + +##! The format of the Omnibus gitconfig is: +##! { "section" => ["subsection = value"] } +##! For example: +##! { "pack" => ["threads = 1"] } +##! For multiple options under one header use array of comma separated values, +##! eg.: +##! { "receive" => ["fsckObjects = true"], "alias" => ["st = status", "co = checkout"] } +# omnibus_gitconfig['system'] = {} + +################################################################################ +## GitLab Pages +##! Docs: https://docs.gitlab.com/ee/administration/pages/ +################################################################################ + +##! Define to enable GitLab Pages +# pages_external_url "http://pages.example.com/" +# gitlab_pages['enable'] = false + +##! Configure to expose GitLab Pages on external IP address, serving the HTTP +# gitlab_pages['external_http'] = [] + +##! Configure to expose GitLab Pages on external IP address, serving the HTTPS +# gitlab_pages['external_https'] = [] + +##! Configure to expose GitLab Pages on external IP address, serving the HTTPS over PROXYv2 +# gitlab_pages['external_https_proxyv2'] = [] + +##! Configure cert when using external IP address +# gitlab_pages['cert'] = "/etc/gitlab/ssl/#{Gitlab['gitlab_pages']['domain']}.crt" +# gitlab_pages['cert_key'] = "/etc/gitlab/ssl/#{Gitlab['gitlab_pages']['domain']}.key" + +##! Configure to use the default list of cipher suites +# gitlab_pages['insecure_ciphers'] = false + +##! Configure to enable health check endpoint on GitLab Pages +# gitlab_pages['status_uri'] = "/@status" + +##! Tune the maximum number of concurrent connections GitLab Pages will handle. +##! Default to 0 for unlimited connections. +# gitlab_pages['max_connections'] = 0 + +##! Configure the maximum length of URIs accepted by GitLab Pages +##! By default is limited for security reasons. Set 0 for unlimited +# gitlab_pages['max_uri_length'] = 1024 + +##! Setting the propagate_correlation_id to true allows installations behind a reverse proxy +##! generate and set a correlation ID to requests sent to GitLab Pages. If a reverse proxy +##! sets the header value X-Request-ID, the value will be propagated in the request chain. +# gitlab_pages['propagate_correlation_id'] = false + +##! Configure to use JSON structured logging in GitLab Pages +# gitlab_pages['log_format'] = "json" + +##! Configure verbose logging for GitLab Pages +# gitlab_pages['log_verbose'] = false + +##! Error Reporting and Logging with Sentry +# gitlab_pages['sentry_enabled'] = false +# gitlab_pages['sentry_dsn'] = 'https://@sentry.io/' +# gitlab_pages['sentry_environment'] = 'production' + +##! Listen for requests forwarded by reverse proxy +# gitlab_pages['listen_proxy'] = "localhost:8090" + +# gitlab_pages['redirect_http'] = true +# gitlab_pages['use_http2'] = true +# gitlab_pages['dir'] = "/var/opt/gitlab/gitlab-pages" +# gitlab_pages['log_directory'] = "/var/log/gitlab/gitlab-pages" +# gitlab_pages['log_group'] = nil + +# gitlab_pages['artifacts_server'] = true +# gitlab_pages['artifacts_server_url'] = nil # Defaults to external_url + '/api/v4' +# gitlab_pages['artifacts_server_timeout'] = 10 + +##! Prometheus metrics for Pages docs: https://gitlab.com/gitlab-org/gitlab-pages/#enable-prometheus-metrics +# gitlab_pages['metrics_address'] = ":9235" + +##! Specifies the minimum TLS version ("tls1.2" or "tls1.3") +# gitlab_pages['tls_min_version'] = "tls1.2" + +##! Specifies the maximum TLS version ("tls1.2" or "tls1.3") +# gitlab_pages['tls_max_version'] = "tls1.3" + +##! Pages access control +# gitlab_pages['access_control'] = false +# gitlab_pages['gitlab_id'] = nil # Automatically generated if not present +# gitlab_pages['gitlab_secret'] = nil # Generated if not present +# gitlab_pages['auth_redirect_uri'] = nil # Defaults to projects subdomain of pages_external_url and + '/auth' +# gitlab_pages['gitlab_server'] = nil # Defaults to external_url +# gitlab_pages['internal_gitlab_server'] = nil # Defaults to gitlab_server, can be changed to internal load balancer +# gitlab_pages['auth_secret'] = nil # Generated if not present +# gitlab_pages['auth_scope'] = nil # Defaults to api, can be changed to read_api to increase security +# gitlab_pages['auth_cookie_session_timeout'] = "10m" # Authentication cookie session timeout (truncated to seconds). A zero value means the cookie will be deleted after the browser session ends + +##! GitLab Pages Server Shutdown Timeout +##! Duration ("30s" for 30 seconds) +# gitlab_pages['server_shutdown_timeout'] = "30s" + +##! GitLab API HTTP client connection timeout +# gitlab_pages['gitlab_client_http_timeout'] = "10s" + +##! GitLab API JWT Token expiry time +# gitlab_pages['gitlab_client_jwt_expiry'] = "30s" + +##! Advanced settings for API-based configuration for GitLab Pages. +##! The recommended default values are set inside GitLab Pages. +##! Should be changed only if absolutely needed. + +##! The maximum time a domain's configuration is stored in the cache. +# gitlab_pages['gitlab_cache_expiry'] = "600s" +##! The interval at which a domain's configuration is set to be due to refresh (default: 60s). +# gitlab_pages['gitlab_cache_refresh'] = "60s" +##! The interval at which expired items are removed from the cache (default: 60s). +# gitlab_pages['gitlab_cache_cleanup'] = "60s" +##! The maximum time to wait for a response from the GitLab API per request. +# gitlab_pages['gitlab_retrieval_timeout'] = "30s" +##! The interval to wait before retrying to resolve a domain's configuration via the GitLab API. +# gitlab_pages['gitlab_retrieval_interval'] = "1s" +##! The maximum number of times to retry to resolve a domain's configuration via the API +# gitlab_pages['gitlab_retrieval_retries'] = 3 + +##! Define custom gitlab-pages HTTP headers for the whole instance +# gitlab_pages['headers'] = [] + +##! Shared secret used for authentication between Pages and GitLab +# gitlab_pages['api_secret_key'] = nil # Will be generated if not set. Base64 encoded and exactly 32 bytes long. + +##! Advanced settings for serving GitLab Pages from zip archives. +##! The recommended default values are set inside GitLab Pages. +##! Should be changed only if absolutely needed. + +##! The maximum time an archive will be cached in memory. +# gitlab_pages['zip_cache_expiration'] = "60s" +##! Zip archive cache cleaning interval. +# gitlab_pages['zip_cache_cleanup'] = "30s" +##! The interval to refresh a cache archive if accessed before expiring. +# gitlab_pages['zip_cache_refresh'] = "30s" +##! The maximum amount of time it takes to open a zip archive from the file system or object storage. +# gitlab_pages['zip_open_timeout'] = "30s" +##! Zip HTTP Client timeout +# gitlab_pages['zip_http_client_timeout'] = "30m" + +##! ReadTimeout is the maximum duration for reading the entire request, including the body. A zero or negative value means there will be no timeout. +# gitlab_pages['server_read_timeout'] = "5s" +##! ReadHeaderTimeout is the amount of time allowed to read request headers. A zero or negative value means there will be no timeout. +# gitlab_pages['server_read_header_timeout'] = "1s" +##! WriteTimeout is the maximum duration before timing out writes of the response. A zero or negative value means there will be no timeout. +# gitlab_pages['server_write_timeout'] = "5m" +##! KeepAlive specifies the keep-alive period for network connections accepted by this listener. If zero, keep-alives are enabled if supported by the protocol and operating system. If negative, keep-alives are disabled. +# gitlab_pages['server_keep_alive'] = "15s" + +##! Enable serving content from disk instead of Object Storage +# gitlab_pages['enable_disk'] = nil + +##! Rate-limiting options below work in report-only mode: +##! they only count rejected requests, but don't reject them +##! enable `FF_ENABLE_RATE_LIMITER=true` environment variable to +##! reject requests. + +##! Rate limits as described in https://docs.gitlab.com/ee/administration/pages/#rate-limits + +##! Rate limit HTTP requests per second from a single IP, 0 means is disabled +# gitlab_pages['rate_limit_source_ip'] = 50.0 +##! Rate limit HTTP requests from a single IP, maximum burst allowed per second +# gitlab_pages['rate_limit_source_ip_burst'] = 600 +##! Rate limit HTTP requests per second to a single domain, 0 means is disabled +# gitlab_pages['rate_limit_domain'] = 0 +##! Rate limit HTTP requests to a single domain, maximum burst allowed per second +# gitlab_pages['rate_limit_domain_burst'] = 10000 + +##! Rate limit new TLS connections per second from a single IP, 0 means is disabled +# gitlab_pages['rate_limit_tls_source_ip'] = 50.0 +##! Rate limit new TLS connections from a single IP, maximum burst allowed per second +# gitlab_pages['rate_limit_tls_source_ip_burst'] = 600 +##!Rate limit new TLS connections per second from to a single domain, 0 means is disabled +# gitlab_pages['rate_limit_tls_domain'] = 0 +##! Rate limit new TLS connections to a single domain, maximum burst allowed per second +# gitlab_pages['rate_limit_tls_domain_burst'] = 10000 + +##! The maximum size of the _redirects file, in bytes +# gitlab_pages['redirects_max_config_size'] = 65536 +##! The maximum number of path segments allowed in _redirects rules URLs +# gitlab_pages['redirects_max_path_segments'] = 25 +##! The maximum number of rules allowed in _redirects +# gitlab_pages['redirects_max_rule_count'] = 1000 + +# gitlab_pages['env_directory'] = "/opt/gitlab/etc/gitlab-pages/env" +# gitlab_pages['env'] = { +# 'SSL_CERT_DIR' => "#{node['package']['install-dir']}/embedded/ssl/certs/" +# } + +################################################################################ +## GitLab Pages NGINX +################################################################################ + +# All the settings defined in the "GitLab Nginx" section are also available in +# this "GitLab Pages NGINX" section, using the key `pages_nginx`. However, +# those settings should be explicitly set. That is, settings given as +# `nginx['some_setting']` WILL NOT be automatically replicated as +# `pages_nginx['some_setting']` and should be set separately. + +# Below you can find settings that are exclusive to "GitLab Pages NGINX" +# pages_nginx['enable'] = true + +# gitlab_rails['pages_path'] = "/var/opt/gitlab/gitlab-rails/shared/pages" + +################################################################################ +## GitLab CI +##! Docs: https://docs.gitlab.com/ee/ci/quick_start/ +################################################################################ + +# gitlab_ci['gitlab_ci_all_broken_builds'] = true +# gitlab_ci['gitlab_ci_add_pusher'] = true +# gitlab_ci['builds_directory'] = '/var/opt/gitlab/gitlab-ci/builds' + +################################################################################ +## GitLab Kubernetes Agent Server +##! Docs: https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/blob/master/README.md +################################################################################ + +##! Settings used by the GitLab application +# gitlab_rails['gitlab_kas_enabled'] = true +# gitlab_rails['gitlab_kas_external_url'] = 'ws://gitlab.example.com/-/kubernetes-agent/' +# gitlab_rails['gitlab_kas_internal_url'] = 'grpc://localhost:8153' +# gitlab_rails['gitlab_kas_external_k8s_proxy_url'] = 'https://gitlab.example.com/-/kubernetes-agent/k8s-proxy/' + +##! Define to enable GitLab KAS +# gitlab_kas_external_url "ws://gitlab.example.com/-/kubernetes-agent/" +# gitlab_kas['enable'] = true + +##! Agent configuration for GitLab KAS +# gitlab_kas['agent_configuration_poll_period'] = 20 +# gitlab_kas['agent_gitops_poll_period'] = 20 +# gitlab_kas['agent_gitops_project_info_cache_ttl'] = 300 +# gitlab_kas['agent_gitops_project_info_cache_error_ttl'] = 60 +# gitlab_kas['agent_info_cache_ttl'] = 300 +# gitlab_kas['agent_info_cache_error_ttl'] = 60 + +##! Shared secret used for authentication between KAS and GitLab +# gitlab_kas['api_secret_key'] = nil # Will be generated if not set. Base64 encoded and exactly 32 bytes long. + +##! Shared secret used for authentication between different KAS instances in a multi-node setup +# gitlab_kas['private_api_secret_key'] = nil # Will be generated if not set. Base64 encoded and exactly 32 bytes long. + +##! Listen configuration for GitLab KAS +# gitlab_kas['listen_address'] = 'localhost:8150' +# gitlab_kas['listen_network'] = 'tcp' +# gitlab_kas['listen_websocket'] = true +# gitlab_kas['certificate_file'] = "/path/to/certificate.pem" +# gitlab_kas['key_file'] = "/path/to/key.pem" +# gitlab_kas['observability_listen_network'] = 'tcp' +# gitlab_kas['observability_listen_address'] = 'localhost:8151' +# gitlab_kas['internal_api_listen_network'] = 'tcp' +# gitlab_kas['internal_api_listen_address'] = 'localhost:8153' +# gitlab_kas['internal_api_certificate_file'] = "/path/to/certificate.pem" +# gitlab_kas['internal_api_key_file'] = "/path/to/key.pem" +# gitlab_kas['kubernetes_api_listen_address'] = 'localhost:8154' +# gitlab_kas['kubernetes_api_certificate_file'] = "/path/to/certificate.pem" +# gitlab_kas['kubernetes_api_key_file'] = "/path/to/key.pem" +# gitlab_kas['private_api_listen_network'] = 'tcp' +# gitlab_kas['private_api_listen_address'] = 'localhost:8155' +# gitlab_kas['private_api_certificate_file'] = "/path/to/certificate.pem" +# gitlab_kas['private_api_key_file'] = "/path/to/key.pem" + +##! Metrics configuration for GitLab KAS +# gitlab_kas['metrics_usage_reporting_period'] = 60 + +##! Log configuration for GitLab KAS +# gitlab_kas['log_level'] = 'info' + +##! Environment variables for GitLab KAS +# gitlab_kas['env'] = { +# 'SSL_CERT_DIR' => "/opt/gitlab/embedded/ssl/certs/", +# # In a multi-node setup, this address MUST be reachable from other KAS instances. In a single-node setup, it can be on localhost for simplicity +# 'OWN_PRIVATE_API_URL' => 'grpc://localhost:8155' +# } + +##! Error Reporting and Logging with Sentry +# gitlab_kas['sentry_dsn'] = 'https://@sentry.io/' +# gitlab_kas['sentry_environment'] = 'production' + +##! Directories for GitLab KAS +# gitlab_kas['dir'] = '/var/opt/gitlab/gitlab-kas' +# gitlab_kas['log_directory'] = '/var/log/gitlab/gitlab-kas' +# gitlab_kas['log_group'] = nil +# gitlab_kas['env_directory'] = '/opt/gitlab/etc/gitlab-kas/env' + +################################################################################ +## GitLab Suggested Reviewers (EE Only) +##! Docs: https://docs.gitlab.com/ee/user/project/merge_requests/reviews/#suggested-reviewers +################################################################################ + +##! Shared secret used for authentication between Suggested Reviewers and GitLab +# suggested_reviewers['api_secret_key'] = nil # Will be generated if not set. Base64 encoded and exactly 32 bytes long. + +################################################################################ +## GitLab Mattermost +##! Docs: https://docs.gitlab.com/omnibus/gitlab-mattermost +################################################################################ + +# mattermost_external_url 'http://mattermost.example.com' + +# mattermost['enable'] = false +# mattermost['username'] = 'mattermost' +# mattermost['group'] = 'mattermost' +# mattermost['uid'] = nil +# mattermost['gid'] = nil +# mattermost['home'] = '/var/opt/gitlab/mattermost' +# mattermost['database_name'] = 'mattermost_production' +# mattermost['env'] = { +# 'SSL_CERT_DIR' => "/opt/gitlab/embedded/ssl/certs/" +# } +# mattermost['service_address'] = "127.0.0.1" +# mattermost['service_port'] = "8065" +# mattermost['service_site_url'] = nil +# mattermost['service_allowed_untrusted_internal_connections'] = "" +# mattermost['service_enable_api_team_deletion'] = true +# mattermost['team_site_name'] = "GitLab Mattermost" +# mattermost['sql_driver_name'] = 'mysql' +# mattermost['sql_data_source'] = "mmuser:mostest@tcp(dockerhost:3306)/mattermost_test?charset=utf8mb4,utf8" +# mattermost['log_file_directory'] = '/var/log/gitlab/mattermost/' +# mattermost['gitlab_enable'] = false +# mattermost['gitlab_id'] = "12345656" +# mattermost['gitlab_secret'] = "123456789" +# mattermost['gitlab_scope'] = "" +# mattermost['gitlab_auth_endpoint'] = "http://gitlab.example.com/oauth/authorize" +# mattermost['gitlab_token_endpoint'] = "http://gitlab.example.com/oauth/token" +# mattermost['gitlab_user_api_endpoint'] = "http://gitlab.example.com/api/v4/user" +# mattermost['file_directory'] = "/var/opt/gitlab/mattermost/data" +# mattermost['plugin_directory'] = "/var/opt/gitlab/mattermost/plugins" +# mattermost['plugin_client_directory'] = "/var/opt/gitlab/mattermost/client-plugins" + +################################################################################ +## Mattermost NGINX +################################################################################ + +# All the settings defined in the "GitLab Nginx" section are also available in +# this "Mattermost NGINX" section, using the key `mattermost_nginx`. However, +# those settings should be explicitly set. That is, settings given as +# `nginx['some_setting']` WILL NOT be automatically replicated as +# `mattermost_nginx['some_setting']` and should be set separately. + +# Below you can find settings that are exclusive to "Mattermost NGINX" +# mattermost_nginx['enable'] = false + +# mattermost_nginx['custom_gitlab_mattermost_server_config'] = "location ^~ /foo-namespace/bar-project/raw/ {\n deny all;\n}\n" +# mattermost_nginx['proxy_set_headers'] = { +# "Host" => "$http_host", +# "X-Real-IP" => "$remote_addr", +# "X-Forwarded-For" => "$proxy_add_x_forwarded_for", +# "X-Frame-Options" => "SAMEORIGIN", +# "X-Forwarded-Proto" => "https", +# "X-Forwarded-Ssl" => "on", +# "Upgrade" => "$http_upgrade", +# "Connection" => "$connection_upgrade" +# } + + +################################################################################ +## Registry NGINX +################################################################################ + +# All the settings defined in the "GitLab Nginx" section are also available in +# this "Registry NGINX" section, using the key `registry_nginx`. However, those +# settings should be explicitly set. That is, settings given as +# `nginx['some_setting']` WILL NOT be automatically replicated as +# `registry_nginx['some_setting']` and should be set separately. + +# Below you can find settings that are exclusive to "Registry NGINX" +# registry_nginx['enable'] = false + +# registry_nginx['proxy_set_headers'] = { +# "Host" => "$http_host", +# "X-Real-IP" => "$remote_addr", +# "X-Forwarded-For" => "$proxy_add_x_forwarded_for", +# "X-Forwarded-Proto" => "https", +# "X-Forwarded-Ssl" => "on" +# } + +# When the registry is automatically enabled using the same domain as `external_url`, +# it listens on this port +# registry_nginx['listen_port'] = 5050 + +################################################################################ +## Prometheus +##! Docs: https://docs.gitlab.com/ee/administration/monitoring/prometheus/ +################################################################################ + +###! **To enable only Monitoring service in this machine, uncomment +###! the line below.** +###! Docs: https://docs.gitlab.com/ee/administration/high_availability +# monitoring_role['enable'] = true + +# prometheus['enable'] = true +# prometheus['monitor_kubernetes'] = true +# prometheus['username'] = 'gitlab-prometheus' +# prometheus['group'] = 'gitlab-prometheus' +# prometheus['uid'] = nil +# prometheus['gid'] = nil +# prometheus['shell'] = '/bin/sh' +# prometheus['home'] = '/var/opt/gitlab/prometheus' +# prometheus['log_directory'] = '/var/log/gitlab/prometheus' +# prometheus['log_group'] = nil +# prometheus['rules_files'] = ['/var/opt/gitlab/prometheus/rules/*.rules'] +# prometheus['scrape_interval'] = 15 +# prometheus['scrape_timeout'] = 15 +# prometheus['external_labels'] = { } +# prometheus['env_directory'] = '/opt/gitlab/etc/prometheus/env' +# prometheus['env'] = { +# 'SSL_CERT_DIR' => "/opt/gitlab/embedded/ssl/certs/" +# } +# +### Custom scrape configs +# +# Prometheus can scrape additional jobs via scrape_configs. The default automatically +# includes all of the exporters supported by the omnibus config. +# +# See: https://prometheus.io/docs/operating/configuration/# +# +# Example: +# +# prometheus['scrape_configs'] = [ +# { +# 'job_name': 'example', +# 'static_configs' => [ +# 'targets' => ['hostname:port'], +# ], +# }, +# ] +# +### Custom alertmanager config +# +# To configure external alertmanagers, create an alertmanager config. +# +# See: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#alertmanager_config +# +# prometheus['alertmanagers'] = [ +# { +# 'static_configs' => [ +# { +# 'targets' => [ +# 'hostname:port' +# ] +# } +# ] +# } +# ] +# +### Custom Prometheus flags +# +# prometheus['flags'] = { +# 'storage.tsdb.path' => "/var/opt/gitlab/prometheus/data", +# 'storage.tsdb.retention.time' => "15d", +# 'config.file' => "/var/opt/gitlab/prometheus/prometheus.yml" +# } + +##! Advanced settings. Should be changed only if absolutely needed. +# prometheus['listen_address'] = 'localhost:9090' +# + +##! Service name used to register Prometheus as a Consul service +# prometheus['consul_service_name'] = 'prometheus' +##! Semantic metadata used when registering Prometheus as a Consul service +# prometheus['consul_service_meta'] = {} + +################################################################################ +###! **Only needed if Prometheus and Rails are not on the same server.** +### For example, in a multi-node architecture, Prometheus will be installed on the monitoring node, while Rails will be on the Rails node. +### https://docs.gitlab.com/ee/administration/monitoring/prometheus/index.html#using-an-external-prometheus-server +### This value should be the address at which Prometheus is available to a GitLab Rails(Puma, Sidekiq) node. +################################################################################ +# gitlab_rails['prometheus_address'] = 'your.prom:9090' + +################################################################################ +## Prometheus Alertmanager +################################################################################ + +# alertmanager['enable'] = true +# alertmanager['home'] = '/var/opt/gitlab/alertmanager' +# alertmanager['log_directory'] = '/var/log/gitlab/alertmanager' +# alertmanager['log_group'] = nil +# alertmanager['admin_email'] = 'admin@example.com' +# alertmanager['flags'] = { +# 'web.listen-address' => "localhost:9093", +# 'storage.path' => "/var/opt/gitlab/alertmanager/data", +# 'config.file' => "/var/opt/gitlab/alertmanager/alertmanager.yml" +# } +# alertmanager['env_directory'] = '/opt/gitlab/etc/alertmanager/env' +# alertmanager['env'] = { +# 'SSL_CERT_DIR' => "/opt/gitlab/embedded/ssl/certs/" +# } + +##! Advanced settings. Should be changed only if absolutely needed. +# alertmanager['listen_address'] = 'localhost:9093' +# alertmanager['global'] = {} + +################################################################################ +## Prometheus Node Exporter +##! Docs: https://docs.gitlab.com/ee/administration/monitoring/prometheus/node_exporter.html +################################################################################ + +# node_exporter['enable'] = true +# node_exporter['home'] = '/var/opt/gitlab/node-exporter' +# node_exporter['log_directory'] = '/var/log/gitlab/node-exporter' +# node_exporter['log_group'] = nil +# node_exporter['flags'] = { +# 'collector.textfile.directory' => "/var/opt/gitlab/node-exporter/textfile_collector" +# } +# node_exporter['env_directory'] = '/opt/gitlab/etc/node-exporter/env' +# node_exporter['env'] = { +# 'SSL_CERT_DIR' => "/opt/gitlab/embedded/ssl/certs/" +# } + +##! Advanced settings. Should be changed only if absolutely needed. +# node_exporter['listen_address'] = 'localhost:9100' + +##! Service name used to register Node Exporter as a Consul service +# node_exporter['consul_service_name'] = 'node-exporter' +##! Semantic metadata used when registering Node Exporter as a Consul service +# node_exporter['consul_service_meta'] = {} + +################################################################################ +## Prometheus Redis exporter +##! Docs: https://docs.gitlab.com/ee/administration/monitoring/prometheus/redis_exporter.html +################################################################################ + +# redis_exporter['enable'] = true +# redis_exporter['log_directory'] = '/var/log/gitlab/redis-exporter' +# redis_exporter['log_group'] = nil +# redis_exporter['flags'] = { +# 'redis.addr' => "unix:///var/opt/gitlab/redis/redis.socket", +# } +# redis_exporter['env_directory'] = '/opt/gitlab/etc/redis-exporter/env' +# redis_exporter['env'] = { +# 'SSL_CERT_DIR' => "/opt/gitlab/embedded/ssl/certs/" +# } + +##! Advanced settings. Should be changed only if absolutely needed. +# redis_exporter['listen_address'] = 'localhost:9121' + +##! Service name used to register Redis Exporter as a Consul service +# redis_exporter['consul_service_name'] = 'redis-exporter' +##! Semantic metadata used when registering Redis Exporter as a Consul service +# redis_exporter['consul_service_meta'] = {} + +################################################################################ +## Prometheus Postgres exporter +##! Docs: https://docs.gitlab.com/ee/administration/monitoring/prometheus/postgres_exporter.html +################################################################################ + +# postgres_exporter['enable'] = true +# postgres_exporter['home'] = '/var/opt/gitlab/postgres-exporter' +# postgres_exporter['log_directory'] = '/var/log/gitlab/postgres-exporter' +# postgres_exporter['log_group'] = nil +# postgres_exporter['flags'] = {} +# postgres_exporter['listen_address'] = 'localhost:9187' +# postgres_exporter['env_directory'] = '/opt/gitlab/etc/postgres-exporter/env' +# postgres_exporter['env'] = { +# 'SSL_CERT_DIR' => "/opt/gitlab/embedded/ssl/certs/" +# } +# postgres_exporter['sslmode'] = nil +# postgres_exporter['per_table_stats'] = false + +##! Service name used to register Postgres Exporter as a Consul service +# postgres_exporter['consul_service_name'] = 'postgres-exporter' +##! Semantic metadata used when registering Postgres Exporter as a Consul service +# postgres_exporter['consul_service_meta'] = {} + +################################################################################ +## Prometheus PgBouncer exporter (EE only) +##! Docs: https://docs.gitlab.com/ee/administration/monitoring/prometheus/pgbouncer_exporter.html +################################################################################ + +# pgbouncer_exporter['enable'] = false +# pgbouncer_exporter['log_directory'] = "/var/log/gitlab/pgbouncer-exporter" +# pgbouncer_exporter['log_group'] = nil +# pgbouncer_exporter['listen_address'] = 'localhost:9188' +# pgbouncer_exporter['env_directory'] = '/opt/gitlab/etc/pgbouncer-exporter/env' +# pgbouncer_exporter['env'] = { +# 'SSL_CERT_DIR' => "/opt/gitlab/embedded/ssl/certs/" +# } + +################################################################################ +## Prometheus Gitlab exporter +##! Docs: https://docs.gitlab.com/ee/administration/monitoring/prometheus/gitlab_exporter.html +################################################################################ + + +# gitlab_exporter['enable'] = true +# gitlab_exporter['log_directory'] = "/var/log/gitlab/gitlab-exporter" +# gitlab_exporter['log_group'] = nil +# gitlab_exporter['home'] = "/var/opt/gitlab/gitlab-exporter" + +##! Advanced settings. Should be changed only if absolutely needed. +# gitlab_exporter['server_name'] = 'webrick' +# gitlab_exporter['listen_address'] = 'localhost' +# gitlab_exporter['listen_port'] = '9168' + +##! TLS settings. +# gitlab_exporter['tls_enabled'] = false +# gitlab_exporter['tls_cert_path'] = '/etc/gitlab/ssl/gitlab-exporter.crt' +# gitlab_exporter['tls_key_path'] = '/etc/gitlab/ssl/gitlab-exporter.key' + +##! Prometheus scrape related configs +# gitlab_exporter['prometheus_scrape_scheme'] = 'http' +# gitlab_exporter['prometheus_scrape_tls_server_name'] = 'localhost' +# gitlab_exporter['prometheus_scrape_tls_skip_verification'] = false + +##! Manage gitlab-exporter sidekiq probes. false by default when Sentinels are +##! found. +# gitlab_exporter['probe_sidekiq'] = true + +##! Manage gitlab-exporter elasticsearch probes. Add authorization header if security +##! is enabled. +# gitlab_exporter['probe_elasticsearch'] = false +# gitlab_exporter['elasticsearch_url'] = 'http://localhost:9200' +# gitlab_exporter['elasticsearch_authorization'] = 'Basic ' + +##! Service name used to register GitLab Exporter as a Consul service +# gitlab_exporter['consul_service_name'] = 'gitlab-exporter' +##! Semantic metadata used when registering GitLab Exporter as a Consul service +# gitlab_exporter['consul_service_meta'] = {} + +# To completely disable prometheus, and all of it's exporters, set to false +# prometheus_monitoring['enable'] = true + +################################################################################ +## Grafana Dashboards +##! Docs: https://docs.gitlab.com/ee/administration/monitoring/prometheus/#prometheus-as-a-grafana-data-source +################################################################################ + +# grafana['enable'] = false +# grafana['enable_deprecated_service'] = false +# grafana['log_directory'] = '/var/log/gitlab/grafana' +# grafana['log_group'] = nil +# grafana['home'] = '/var/opt/gitlab/grafana' +# grafana['admin_password'] = 'admin' +# grafana['allow_user_sign_up'] = false +# grafana['basic_auth_enabled'] = false +# grafana['disable_login_form'] = true +# grafana['gitlab_application_id'] = 'GITLAB_APPLICATION_ID' +# grafana['gitlab_secret'] = 'GITLAB_SECRET' +# grafana['env_directory'] = '/opt/gitlab/etc/grafana/env' +# grafana['allowed_groups'] = [] +# grafana['gitlab_auth_sign_up'] = true +# grafana['env'] = { +# 'SSL_CERT_DIR' => "#{node['package']['install-dir']}/embedded/ssl/certs/" +# } +# grafana['metrics_enabled'] = false +# grafana['metrics_basic_auth_username'] = 'grafana_metrics' # default: nil +# grafana['metrics_basic_auth_password'] = 'please_set_a_unique_password' # default: nil +# grafana['alerting_enabled'] = false + +### SMTP Configuration +# +# See: http://docs.grafana.org/administration/configuration/#smtp +# +# grafana['smtp'] = { +# 'enabled' => true, +# 'host' => 'localhost:25', +# 'user' => nil, +# 'password' => nil, +# 'cert_file' => nil, +# 'key_file' => nil, +# 'skip_verify' => false, +# 'from_address' => 'admin@grafana.localhost', +# 'from_name' => 'Grafana', +# 'ehlo_identity' => 'dashboard.example.com', +# 'startTLS_policy' => nil +# } + +# Grafana usage reporting defaults to gitlab_rails['usage_ping_enabled'] +# grafana['reporting_enabled'] = true + +### Dashboards +# +# See: http://docs.grafana.org/administration/provisioning/#dashboards +# +# NOTE: Setting this will override the default. +# +# grafana['dashboards'] = [ +# { +# 'name' => 'GitLab Omnibus', +# 'orgId' => 1, +# 'folder' => 'GitLab Omnibus', +# 'type' => 'file', +# 'disableDeletion' => true, +# 'updateIntervalSeconds' => 600, +# 'options' => { +# 'path' => '/opt/gitlab/embedded/service/grafana-dashboards', +# } +# } +# ] + +### Datasources +# +# See: http://docs.grafana.org/administration/provisioning/#example-datasource-config-file +# +# NOTE: Setting this will override the default. +# +# grafana['datasources'] = [ +# { +# 'name' => 'GitLab Omnibus', +# 'type' => 'prometheus', +# 'access' => 'proxy', +# 'url' => 'http://localhost:9090' +# } +# ] + +##! Advanced settings. Should be changed only if absolutely needed. +# grafana['http_addr'] = 'localhost' +# grafana['http_port'] = 3000 + +################################################################################ +## Gitaly +##! Docs: https://docs.gitlab.com/ee/administration/gitaly/configure_gitaly.html +################################################################################ + +# The gitaly['enable'] option exists for the purpose of cluster +# deployments, see https://docs.gitlab.com/ee/administration/gitaly/index.html . +# gitaly['enable'] = true +# gitaly['dir'] = "/var/opt/gitlab/gitaly" +# gitaly['log_group'] = nil +# gitaly['bin_path'] = "/opt/gitlab/embedded/bin/gitaly" +# gitaly['env_directory'] = "/opt/gitlab/etc/gitaly/env" +# gitaly['env'] = { +# 'PATH' => "/opt/gitlab/bin:/opt/gitlab/embedded/bin:/bin:/usr/bin", +# 'HOME' => '/var/opt/gitlab', +# 'TZ' => ':/etc/localtime', +# 'PYTHONPATH' => "/opt/gitlab/embedded/lib/python3.9/site-packages", +# 'ICU_DATA' => "/opt/gitlab/embedded/share/icu/current", +# 'SSL_CERT_DIR' => "/opt/gitlab/embedded/ssl/certs/", +# 'WRAPPER_JSON_LOGGING' => true +# } + +# gitaly['open_files_ulimit'] = 15000 # Maximum number of open files allowed for the gitaly process +##! Service name used to register Gitaly as a Consul service +# gitaly['consul_service_name'] = 'gitaly' +##! Semantic metadata used when registering Gitaly as a Consul service +# gitaly['consul_service_meta'] = {} +# gitaly['configuration'] = { +# socket_path: '/var/opt/gitlab/gitaly/gitaly.socket', +# runtime_dir: '/var/opt/gitlab/gitaly/run', +# listen_addr: 'localhost:8075', +# prometheus_listen_addr: 'localhost:9236', +# tls_listen_addr: 'localhost:9075', +# tls: { +# certificate_path: '/var/opt/gitlab/gitaly/certificate.pem', +# key_path: '/var/opt/gitlab/gitaly/key.pem', +# }, +# graceful_restart_timeout: '1m', # Grace time for a gitaly process to finish ongoing requests +# logging: { +# dir: "/var/log/gitlab/gitaly", +# level: 'warn', +# format: 'json', +# sentry_dsn: 'https://:@sentry.io/', +# sentry_environment: 'production', +# }, +# prometheus: { +# grpc_latency_buckets: [0.001, 0.005, 0.025, 0.1, 0.5, 1.0, 10.0, 30.0, 60.0, 300.0, 1500.0], +# }, +# auth: { +# token: '', +# transitioning: false, # When true, auth is logged to Prometheus but NOT enforced +# }, +# git: { +# catfile_cache_size: 100, # Number of 'git cat-file' processes kept around for re-use +# bin_path: '/opt/gitlab/embedded/bin/git', # A custom path for the 'git' executable +# use_bundled_binaries: true, # Whether to use bundled Git. +# signing_key: '/var/opt/gitlab/gitaly/signing_key.gpg', +# ## Gitaly knows to set up the required default configuration for spawned Git +# ## commands automatically. It should thus not be required to configure anything +# ## here, except in very special situations where you must e.g. tweak specific +# ## performance-related settings or enable debugging facilities. It is not safe in +# ## general to set Git configuration that may change Git output in ways that are +# ## unexpected by Gitaly. +# config: [ +# { key: 'pack.threads', value: '4' }, +# { key: 'http.http://example.com.proxy', value: 'http://example.proxy.com' }, +# ], +# }, +# hooks: { +# custom_hooks_dir: '/var/opt/gitlab/gitaly/custom_hooks', +# }, +# daily_maintenance: { +# disabled: false, +# start_hour: 22, +# start_minute: 30, +# duration: '30m', +# storages: ['default'], +# }, +# cgroups: { +# mountpoint: '/sys/fs/cgroup', +# hierarchy_root: 'gitaly', +# memory_bytes: 1048576, +# cpu_shares: 512, +# cpu_quota_us: 400000, +# repositories: { +# count: 1000, +# memory_bytes: 12884901888, +# cpu_shares: 128, +# cpu_quota_us: 200000 +# }, +# }, +# concurrency: [ +# { +# rpc: '/gitaly.SmartHTTPService/PostReceivePack', +# max_per_repo: 20, +# }, +# { +# rpc: '/gitaly.SSHService/SSHUploadPack', +# max_per_repo: 5, +# }, +# ], +# rate_limiting: [ +# { +# rpc: '/gitaly.SmartHTTPService/PostReceivePack', +# interval: '1m', +# burst: 10, +# }, +# { +# rpc: '/gitaly.SSHService/SSHUploadPack', +# interval: '1m', +# burst: 5, +# }, +# ], +# pack_objects_cache: { +# enabled: true, +# dir: '/var/opt/gitlab/git-data/repositories/+gitaly/PackObjectsCache', +# max_age: '5m', +# }, +# } + +################################################################################ +## Praefect +##! Docs: https://docs.gitlab.com/ee/administration/gitaly/praefect.html +################################################################################ + +# praefect['enable'] = false +# praefect['dir'] = "/var/opt/gitlab/praefect" +# praefect['log_directory'] = "/var/log/gitlab/praefect" +# praefect['log_group'] = nil +# praefect['env_directory'] = "/opt/gitlab/etc/praefect/env" +# praefect['env'] = { +# 'SSL_CERT_DIR' => "/opt/gitlab/embedded/ssl/certs/", +# 'GITALY_PID_FILE' => "/var/opt/gitlab/praefect/praefect.pid", +# 'WRAPPER_JSON_LOGGING' => true +# } +# praefect['wrapper_path'] = "/opt/gitlab/embedded/bin/gitaly-wrapper" +# praefect['auto_migrate'] = true +##! Service name used to register Praefect as a Consul service +# praefect['consul_service_name'] = 'praefect' +##! Semantic metadata used when registering Praefect as a Consul service +# praefect['consul_service_meta'] = {} +# praefect['configuration'] = { +# listen_addr: 'localhost:2305', +# prometheus_listen_addr: 'localhost:9652', +# tls_listen_addr: 'localhost:3305', +# auth: { +# token: '', +# transitioning: false, +# }, +# logging: { +# format: 'json', +# level: 'warn', +# }, +# failover: { +# enabled: true, +# }, +# background_verification: { +# delete_invalid_records: false, +# verification_interval: '72h', +# }, +# reconciliation: { +# scheduling_interval: '5m', +# histogram_buckets: [0.001, 0.005, 0.025, 0.1, 0.5, 1.0, 10.0], +# }, +# tls: { +# certificate_path: '/var/opt/gitlab/prafect/certificate.pem', +# key_path: '/var/opt/gitlab/prafect/key.pem', +# }, +# database: { +# host: 'postgres.external', +# port: 6432, +# user: 'praefect', +# password: 'secret', +# dbname: 'praefect_production', +# sslmode: 'disable', +# sslcert: '/path/to/client-cert', +# sslkey: '/path/to/client-key', +# sslrootcert: '/path/to/rootcert', +# session_pooled: { +# host: 'postgres.internal', +# port: 5432, +# user: 'praefect', +# password: 'secret', +# dbname: 'praefect_production_direct', +# sslmode: 'disable', +# sslcert: '/path/to/client-cert', +# sslkey: '/path/to/client-key', +# sslrootcert: '/path/to/rootcert', +# }, +# }, +# sentry: { +# sentry_dsn: 'https://:@sentry.io/', +# sentry_environment: 'production', +# }, +# prometheus: { +# grpc_latency_buckets: [0.001, 0.005, 0.025, 0.1, 0.5, 1.0, 10.0, 30.0, 60.0, 300.0, 1500.0], +# }, +# graceful_stop_timeout: '1m', +# virtual_storage: [ +# { +# name: 'default', +# default_replication_factor: 3, +# node: [ +# { +# storage: 'praefect-internal-0', +# address: 'tcp://10.23.56.78:8075', +# token: 'abc123', +# }, +# { +# storage: 'praefect-internal-1', +# address: 'tcp://10.76.23.31:8075', +# token: 'xyz456', +# }, +# ], +# }, +# { +# name: 'alternative', +# node: [ +# { +# storage: 'praefect-internal-2', +# address: 'tcp://10.34.1.16:8075', +# token: 'abc321', +# }, +# { +# storage: 'praefect-internal-3', +# address: 'tcp://10.23.18.6:8075', +# token: 'xyz890', +# }, +# ], +# }, +# ], +# } + +################################################################################ +# Storage check +################################################################################ +# storage_check['enable'] = false +# storage_check['target'] = 'unix:///var/opt/gitlab/gitlab-rails/sockets/gitlab.socket' +# storage_check['log_directory'] = '/var/log/gitlab/storage-check' +# storage_check['log_group'] = nil + +################################################################################ +# Let's Encrypt integration +################################################################################ +# letsencrypt['enable'] = nil +# letsencrypt['contact_emails'] = [] # This should be an array of email addresses to add as contacts +# letsencrypt['group'] = 'root' +# letsencrypt['key_size'] = 2048 +# letsencrypt['owner'] = 'root' +# letsencrypt['wwwroot'] = '/var/opt/gitlab/nginx/www' +# See http://docs.gitlab.com/omnibus/settings/ssl.html#automatic-renewal for more on these sesttings +# letsencrypt['auto_renew'] = true +# letsencrypt['auto_renew_hour'] = 0 +# letsencrypt['auto_renew_minute'] = nil # Should be a number or cron expression, if specified. +# letsencrypt['auto_renew_day_of_month'] = "*/4" +# letsencrypt['auto_renew_log_directory'] = '/var/log/gitlab/lets-encrypt' + +##! Turn off automatic init system detection. To skip init detection in +##! non-docker containers. Recommended not to change. +# package['detect_init'] = true + +##! Attempt to modify kernel paramaters. To skip this in containers where the +##! relevant file system is read-only, set the value to false. +# package['modify_kernel_parameters'] = true + +##! Specify maximum number of tasks that can be created by the systemd unit +##! Will be populated as TasksMax value to the unit file if user is on a systemd +##! version that supports it (>= 227). Will be a no-op if user is not on systemd. +# package['systemd_tasks_max'] = 4915 + +##! Settings to configure order of GitLab's systemd unit. +##! Note: We do not recommend changing these values unless absolutely necessary +# package['systemd_after'] = 'multi-user.target' +# package['systemd_wanted_by'] = 'multi-user.target' + +##! Settings to control secret generation and storage +##! Note: We do not recommend changing these values unless absolutely necessary +##! Set to false to only parse secrets from `gitlab-secrets.json` file but not generate them. +# package['generate_default_secrets'] = true +##! Set to false to prevent creating `gitlab-secrets.json` file +# package['generate_secrets_json_file'] = true +################################################################################ +################################################################################ +## Configuration Settings for GitLab EE only ## +################################################################################ +################################################################################ + + +################################################################################ +## Auxiliary cron jobs applicable to GitLab EE only +################################################################################ +# +# gitlab_rails['geo_repository_sync_worker_cron'] = "*/5 * * * *" +# gitlab_rails['geo_secondary_registry_consistency_worker'] = "* * * * *" +# gitlab_rails['geo_secondary_usage_data_cron_worker'] = "0 0 * * 0" +# gitlab_rails['geo_prune_event_log_worker_cron'] = "*/5 * * * *" +# gitlab_rails['geo_repository_verification_primary_batch_worker_cron'] = "*/5 * * * *" +# gitlab_rails['geo_repository_verification_secondary_scheduler_worker_cron'] = "*/5 * * * *" +# gitlab_rails['ldap_sync_worker_cron'] = "30 1 * * *" +# gitlab_rails['ldap_group_sync_worker_cron'] = "0 * * * *" +# gitlab_rails['historical_data_worker_cron'] = "0 12 * * *" +# gitlab_rails['elastic_index_bulk_cron'] = "*/1 * * * *" +# gitlab_rails['analytics_devops_adoption_create_all_snapshots_worker_cron'] = "0 4 * * 0" +# gitlab_rails['ci_runners_stale_group_runners_prune_worker_cron'] = "30 * * * *" + +################################################################################ +## Kerberos (EE Only) +##! Docs: https://docs.gitlab.com/ee/integration/kerberos.html#http-git-access +################################################################################ + +# gitlab_rails['kerberos_enabled'] = true +# gitlab_rails['kerberos_keytab'] = /etc/http.keytab +# gitlab_rails['kerberos_service_principal_name'] = HTTP/gitlab.example.com@EXAMPLE.COM +# gitlab_rails['kerberos_simple_ldap_linking_allowed_realms'] = ['example.com','kerberos.example.com'] +# gitlab_rails['kerberos_use_dedicated_port'] = true +# gitlab_rails['kerberos_port'] = 8443 +# gitlab_rails['kerberos_https'] = true + +################################################################################ +## Package repository +##! Docs: https://docs.gitlab.com/ee/administration/packages/ +################################################################################ + +# gitlab_rails['packages_enabled'] = true +# gitlab_rails['packages_storage_path'] = "/var/opt/gitlab/gitlab-rails/shared/packages" +# gitlab_rails['packages_object_store_enabled'] = false +# gitlab_rails['packages_object_store_proxy_download'] = false +# gitlab_rails['packages_object_store_remote_directory'] = "packages" +# gitlab_rails['packages_object_store_connection'] = { +# 'provider' => 'AWS', +# 'region' => 'eu-west-1', +# 'aws_access_key_id' => 'AWS_ACCESS_KEY_ID', +# 'aws_secret_access_key' => 'AWS_SECRET_ACCESS_KEY', +# # # The below options configure an S3 compatible host instead of AWS +# # 'host' => 's3.amazonaws.com', +# # 'aws_signature_version' => 4, # For creation of signed URLs. Set to 2 if provider does not support v4. +# # 'endpoint' => 'https://s3.amazonaws.com', # default: nil - Useful for S3 compliant services such as DigitalOcean Spaces +# # 'path_style' => false # Use 'host/bucket_name/object' instead of 'bucket_name.host/object' +# } + +################################################################################ +## Dependency proxy +##! Docs: https://docs.gitlab.com/ee/administration/packages/dependency_proxy.html +################################################################################ + +# gitlab_rails['dependency_proxy_enabled'] = true +# gitlab_rails['dependency_proxy_storage_path'] = "/var/opt/gitlab/gitlab-rails/shared/dependency_proxy" +# gitlab_rails['dependency_proxy_object_store_enabled'] = false +# gitlab_rails['dependency_proxy_object_store_proxy_download'] = false +# gitlab_rails['dependency_proxy_object_store_remote_directory'] = "dependency_proxy" +# gitlab_rails['dependency_proxy_object_store_connection'] = { +# 'provider' => 'AWS', +# 'region' => 'eu-west-1', +# 'aws_access_key_id' => 'AWS_ACCESS_KEY_ID', +# 'aws_secret_access_key' => 'AWS_SECRET_ACCESS_KEY', +# # # The below options configure an S3 compatible host instead of AWS +# # 'host' => 's3.amazonaws.com', +# # 'aws_signature_version' => 4, # For creation of signed URLs. Set to 2 if provider does not support v4. +# # 'endpoint' => 'https://s3.amazonaws.com', # default: nil - Useful for S3 compliant services such as DigitalOcean Spaces +# # 'path_style' => false # Use 'host/bucket_name/object' instead of 'bucket_name.host/object' +# } + +################################################################################ +## GitLab Sentinel (EE Only) +##! Docs: http://docs.gitlab.com/ce/administration/high_availability/redis.html#high-availability-with-sentinel +################################################################################ + +##! **Make sure you configured all redis['master_*'] keys above before +##! continuing.** + +##! To enable Sentinel and disable all other services in this machine, +##! uncomment the line below (if you've enabled Redis role, it will keep it). +##! Docs: https://docs.gitlab.com/ee/administration/high_availability/redis.html +# redis_sentinel_role['enable'] = true + +# sentinel['enable'] = true + +##! Bind to all interfaces, uncomment to specify an IP and bind to a single one +# sentinel['bind'] = '0.0.0.0' + +##! Uncomment to change default port +# sentinel['port'] = 26379 + +##! Uncomment to require a Sentinel password. This may be different from the Redis master password. +# sentinel['password'] = 'sentinel-password-goes-here' + +#### Support to run sentinels in a Docker or NAT environment +#####! Docs: https://redis.io/topics/sentinel#sentinel-docker-nat-and-possible-issues +# In an standard case, Sentinel will run in the same network service as Redis, so the same IP will be announce for Redis and Sentinel +# Only define these values if it is needed to announce for Sentinel a differen IP service than Redis +# sentinel['announce_ip'] = nil # If not defined, its value will be taken from redis['announce_ip'] or nil if not present +# sentinel['announce_port'] = nil # If not defined, its value will be taken from sentinel['port'] or nil if redis['announce_ip'] not present + +##! Quorum must reflect the amount of voting sentinels it take to start a +##! failover. +##! **Value must NOT be greater then the amount of sentinels.** +##! The quorum can be used to tune Sentinel in two ways: +##! 1. If a the quorum is set to a value smaller than the majority of Sentinels +##! we deploy, we are basically making Sentinel more sensible to master +##! failures, triggering a failover as soon as even just a minority of +##! Sentinels is no longer able to talk with the master. +##! 2. If a quorum is set to a value greater than the majority of Sentinels, we +##! are making Sentinel able to failover only when there are a very large +##! number (larger than majority) of well connected Sentinels which agree +##! about the master being down. +# sentinel['quorum'] = 1 + +### Consider unresponsive server down after x amount of ms. +# sentinel['down_after_milliseconds'] = 10000 + +### Specifies the failover timeout in milliseconds. +##! It is used in many ways: +##! +##! - The time needed to re-start a failover after a previous failover was +##! already tried against the same master by a given Sentinel, is two +##! times the failover timeout. +##! +##! - The time needed for a replica replicating to a wrong master according +##! to a Sentinel current configuration, to be forced to replicate +##! with the right master, is exactly the failover timeout (counting since +##! the moment a Sentinel detected the misconfiguration). +##! +##! - The time needed to cancel a failover that is already in progress but +##! did not produced any configuration change (REPLICAOF NO ONE yet not +##! acknowledged by the promoted replica). +##! +##! - The maximum time a failover in progress waits for all the replicas to be +##! reconfigured as replicas of the new master. However even after this time +##! the replicas will be reconfigured by the Sentinels anyway, but not with +##! the exact parallel-syncs progression as specified. +# sentinel['failover_timeout'] = 60000 + +### Sentinel TLS settings +###! To run Sentinel over TLS, specify values for the following settings +# sentinel['tls_port'] = nil +# sentinel['tls_cert_file'] = nil +# sentinel['tls_key_file'] = nil + +###! Other TLS related optional settings +# sentinel['tls_dh_params_file'] = nil +# sentinel['tls_ca_cert_dir'] = '/opt/gitlab/embedded/ssl/certs/' +# sentinel['tls_ca_cert_file'] = '/opt/gitlab/embedded/ssl/certs/cacert.pem' +# sentinel['tls_auth_clients'] = 'optional' +# sentinel['tls_replication'] = nil +# sentinel['tls_cluster'] = nil +# sentinel['tls_protocols'] = nil +# sentinel['tls_ciphers'] = nil +# sentinel['tls_ciphersuites'] = nil +# sentinel['tls_prefer_server_ciphers'] = nil +# sentinel['tls_session_caching'] = nil +# sentinel['tls_session_cache_size'] = nil +# sentinel['tls_session_cache_timeout'] = nil + +### Sentinel hostname support +###! When enabled, Redis will leverage hostname support +###! Generally this does not need to be changed as we determine this based on +###! the provided input from `redis['announce_ip']` +###! * This is configured to `true` when a fully qualified hostname is provided +###! * This is configured to `false` when an IP address is provided +# sentinel['use_hostnames'] = + +### Sentinel log settings +# sentinel['log_directory'] = '/var/log/gitlab/sentinel' + +################################################################################ +## Additional Database Settings (EE only) +##! Docs: https://docs.gitlab.com/ee/administration/database_load_balancing.html +################################################################################ +# gitlab_rails['db_load_balancing'] = { 'hosts' => ['secondary1.example.com'] } + +################################################################################ +## GitLab Geo +##! Docs: https://docs.gitlab.com/ee/gitlab-geo +################################################################################ +##! Geo roles 'geo_primary_role' and 'geo_secondary_role' are set above with +##! other roles. For more information, see: https://docs.gitlab.com/omnibus/roles/index.html#roles. + +# This is an optional identifier which Geo nodes can use to identify themselves. +# For example, if external_url is the same for two secondaries, you must specify +# a unique Geo node name for those secondaries. +# +# If it is blank, it defaults to external_url. +# gitlab_rails['geo_node_name'] = nil + +# gitlab_rails['geo_registry_replication_enabled'] = true +# gitlab_rails['geo_registry_replication_primary_api_url'] = 'https://example.com:5050' + + +################################################################################ +## GitLab Geo Secondary (EE only) +################################################################################ +# geo_secondary['auto_migrate'] = true +# geo_secondary['db_adapter'] = "postgresql" +# geo_secondary['db_encoding'] = "unicode" +# geo_secondary['db_collation'] = nil +# geo_secondary['db_database'] = "gitlabhq_geo_production" +# geo_secondary['db_username'] = "gitlab_geo" +# geo_secondary['db_password'] = nil +# geo_secondary['db_host'] = "/var/opt/gitlab/geo-postgresql" +# geo_secondary['db_port'] = 5431 +# geo_secondary['db_socket'] = nil +# geo_secondary['db_sslmode'] = nil +# geo_secondary['db_sslcompression'] = 0 +# geo_secondary['db_sslrootcert'] = nil +# geo_secondary['db_sslca'] = nil +# geo_secondary['db_prepared_statements'] = false +# geo_secondary['db_database_tasks'] = true + +################################################################################ +## GitLab Geo Secondary Tracking Database (EE only) +################################################################################ + +# geo_postgresql['enable'] = false +# geo_postgresql['ha'] = false +# geo_postgresql['dir'] = '/var/opt/gitlab/geo-postgresql' +# geo_postgresql['pgbouncer_user'] = nil +# geo_postgresql['pgbouncer_user_password'] = nil +##! `SQL_USER_PASSWORD_HASH` can be generated using the command `gitlab-ctl pg-password-md5 gitlab` +# geo_postgresql['sql_user_password'] = 'SQL_USER_PASSWORD_HASH' +# geo_postgresql['log_directory'] = '/var/log/gitlab/geo-postgresql' + +##! Automatically restart PostgreSQL service when version changes. +# geo_postgresql['auto_restart_on_version_change'] = true + +################################################################################ +## GitLab Geo Log Cursor Daemon (EE only) +################################################################################ + +# geo_logcursor['log_directory'] = '/var/log/gitlab/geo-logcursor' +# geo_logcursor['log_group'] = nil + +################################################################################ +## Unleash +##! These settings are for GitLab internal use. +##! They are used to control feature flags during GitLab development. +##! Docs: https://docs.gitlab.com/ee/development/feature_flags +################################################################################ +# gitlab_rails['feature_flags_unleash_enabled'] = false +# gitlab_rails['feature_flags_unleash_url'] = nil +# gitlab_rails['feature_flags_unleash_app_name'] = nil +# gitlab_rails['feature_flags_unleash_instance_id'] = nil + +################################################################################ +# Pgbouncer (EE only) +# See [GitLab PgBouncer documentation](http://docs.gitlab.com/omnibus/settings/database.html#enabling-pgbouncer-ee-only) +# See the [PgBouncer page](https://pgbouncer.github.io/config.html) for details +################################################################################ +# pgbouncer['enable'] = false +# pgbouncer['log_directory'] = '/var/log/gitlab/pgbouncer' +# pgbouncer['log_group'] = nil +# pgbouncer['data_directory'] = '/var/opt/gitlab/pgbouncer' +# pgbouncer['env_directory'] = '/opt/gitlab/etc/pgbouncer/env' +# pgbouncer['env'] = { +# 'SSL_CERT_DIR' => "/opt/gitlab/embedded/ssl/certs/" +# } +# pgbouncer['listen_addr'] = '0.0.0.0' +# pgbouncer['listen_port'] = '6432' +# pgbouncer['pool_mode'] = 'transaction' +# pgbouncer['server_reset_query'] = 'DISCARD ALL' +# pgbouncer['application_name_add_host'] = '1' +# pgbouncer['max_client_conn'] = '2048' +# pgbouncer['default_pool_size'] = '100' +# pgbouncer['min_pool_size'] = '0' +# pgbouncer['reserve_pool_size'] = '5' +# pgbouncer['reserve_pool_timeout'] = '5.0' +# pgbouncer['server_round_robin'] = '0' +# pgbouncer['log_connections'] = '0' +# pgbouncer['server_idle_timeout'] = '30' +# pgbouncer['dns_max_ttl'] = '15.0' +# pgbouncer['dns_zone_check_period'] = '0' +# pgbouncer['dns_nxdomain_ttl'] = '15.0' +# pgbouncer['admin_users'] = %w(gitlab-psql postgres pgbouncer) +# pgbouncer['stats_users'] = %w(gitlab-psql postgres pgbouncer) +# pgbouncer['ignore_startup_parameters'] = 'extra_float_digits' +# pgbouncer['databases'] = { +# DATABASE_NAME: { +# host: HOSTNAME, +# port: PORT +# user: USERNAME, +# password: PASSWORD +###! generate this with `echo -n '$password + $username' | md5sum` +# } +# ... +# } +# pgbouncer['logfile'] = nil +# pgbouncer['unix_socket_dir'] = nil +# pgbouncer['unix_socket_mode'] = '0777' +# pgbouncer['unix_socket_group'] = nil +# pgbouncer['auth_type'] = 'md5' +# pgbouncer['auth_hba_file'] = nil +# pgbouncer['auth_query'] = 'SELECT username, password FROM public.pg_shadow_lookup($1)' +# pgbouncer['users'] = { +# USERNAME: { +# 'password': MD5_PASSWORD_HASH, +# } +# } +# postgresql['pgbouncer_user'] = nil +# postgresql['pgbouncer_user_password'] = nil +# pgbouncer['server_reset_query_always'] = 0 +# pgbouncer['server_check_query'] = 'select 1' +# pgbouncer['server_check_delay'] = 30 +# pgbouncer['max_db_connections'] = nil +# pgbouncer['max_user_connections'] = nil +# pgbouncer['syslog'] = 0 +# pgbouncer['syslog_facility'] = 'daemon' +# pgbouncer['syslog_ident'] = 'pgbouncer' +# pgbouncer['log_disconnections'] = 1 +# pgbouncer['log_pooler_errors'] = 1 +# pgbouncer['stats_period'] = 60 +# pgbouncer['verbose'] = 0 +# pgbouncer['server_lifetime'] = 3600 +# pgbouncer['server_connect_timeout'] = 15 +# pgbouncer['server_login_retry'] = 15 +# pgbouncer['query_timeout'] = 0 +# pgbouncer['query_wait_timeout'] = 120 +# pgbouncer['client_idle_timeout'] = 0 +# pgbouncer['client_login_timeout'] = 60 +# pgbouncer['autodb_idle_timeout'] = 3600 +# pgbouncer['suspend_timeout'] = 10 +# pgbouncer['idle_transaction_timeout'] = 0 +# pgbouncer['pkt_buf'] = 4096 +# pgbouncer['listen_backlog'] = 128 +# pgbouncer['sbuf_loopcnt'] = 5 +# pgbouncer['max_packet_size'] = 2147483647 +# pgbouncer['tcp_defer_accept'] = 0 +# pgbouncer['tcp_socket_buffer'] = 0 +# pgbouncer['tcp_keepalive'] = 1 +# pgbouncer['tcp_keepcnt'] = 0 +# pgbouncer['tcp_keepidle'] = 0 +# pgbouncer['tcp_keepintvl'] = 0 +# pgbouncer['disable_pqexec'] = 0 + +## Pgbouncer client TLS options +# pgbouncer['client_tls_sslmode'] = 'disable' +# pgbouncer['client_tls_ca_file'] = nil +# pgbouncer['client_tls_key_file'] = nil +# pgbouncer['client_tls_cert_file'] = nil +# pgbouncer['client_tls_protocols'] = 'all' +# pgbouncer['client_tls_dheparams'] = 'auto' +# pgbouncer['client_tls_ecdhcurve'] = 'auto' +# +## Pgbouncer server TLS options +# pgbouncer['server_tls_sslmode'] = 'disable' +# pgbouncer['server_tls_ca_file'] = nil +# pgbouncer['server_tls_key_file'] = nil +# pgbouncer['server_tls_cert_file'] = nil +# pgbouncer['server_tls_protocols'] = 'all' +# pgbouncer['server_tls_ciphers'] = 'fast' + +################################################################################ +# Patroni (EE only) +################################################################################ +# patroni['enable'] = false + +# patroni['dir'] = '/var/opt/gitlab/patroni' +# patroni['ctl_command'] = '/opt/gitlab/embedded/bin/patronictl' + +## Patroni dynamic configuration settings +# patroni['loop_wait'] = 10 +# patroni['ttl'] = 30 +# patroni['retry_timeout'] = 10 +# patroni['maximum_lag_on_failover'] = 1_048_576 +# patroni['max_timelines_history'] = 0 +# patroni['master_start_timeout'] = 300 +# patroni['use_pg_rewind'] = true +# patroni['remove_data_directory_on_rewind_failure'] = false +# patroni['remove_data_directory_on_diverged_timelines'] = false +# patroni['use_slots'] = true +# patroni['replication_password'] = nil +# patroni['replication_slots'] = {} +# patroni['callbacks'] = {} +# patroni['recovery_conf'] = {} +# patroni['tags'] = {} + +## Standby cluster replication settings +# patroni['standby_cluster']['enable'] = false +# patroni['standby_cluster']['host'] = nil +# patroni['standby_cluster']['port'] = 5432 +# patroni['standby_cluster']['primary_slot_name'] = nil + +## Global/Universal settings +# patroni['scope'] = 'gitlab-postgresql-ha' +# patroni['name'] = nil + +## Log settings +# patroni['log_directory'] = '/var/log/gitlab/patroni' +# patroni['log_group'] = nil +# patroni['log_level'] = 'INFO' + +## Consul specific settings +# patroni['consul']['url'] = 'http://127.0.0.1:8500' +# patroni['consul']['service_check_interval'] = '10s' +# patroni['consul']['register_service'] = true +# patroni['consul']['checks'] = [] + +## PostgreSQL configuration override +# patroni['postgresql']['hot_standby'] = 'on' + +## The following must hold the same values on all nodes. +## Leave unassined to use PostgreSQL's default values. +# patroni['postgresql']['wal_level'] = 'replica' +# patroni['postgresql']['wal_log_hints'] = 'on' +# patroni['postgresql']['max_worker_processes'] = 8 +# patroni['postgresql']['max_locks_per_transaction'] = 64 +# patroni['postgresql']['max_connections'] = 400 +# patroni['postgresql']['checkpoint_timeout'] = 30 + +## The following can hold different values on all nodes. +## Leave unassined to use PostgreSQL's default values. +# patroni['postgresql']['wal_keep_segments'] = 8 +# patroni['postgresql']['max_wal_senders'] = 5 +# patroni['postgresql']['max_replication_slots'] = 5 + +## Permanent replication slots for Streaming Replication +# patroni['replication_slots'] = { +# 'geo_secondary' => { 'type' => 'physical' } +# } + +## The address and port that Patroni API binds to and listens on. +# patroni['listen_address'] = nil +# patroni['port'] = '8008' + +## The address of the Patroni node that is advertized to other cluster +## members to communicate with its API and PostgreSQL. If it is not specified, +## it tries to use the first available private IP and falls back to the default +## network interface. +# patroni['connect_address'] = nil + +## The port that Patroni API responds to other cluster members. This port is +## advertized and by default is the same as patroni['port']. +# patroni['connect_port'] = '8008' + +## Specifies the set of hosts that are allowed to call unsafe REST API endpoints. +## Each item can be an hostname, IP address, or CIDR address. +## All hosts are allowed if this is unset. +# patroni['allowlist'] = [] +# patroni['allowlist_include_members'] = false + +## The username and password to use for basic auth on write commands to the +## Patroni API. If not specified then the API does not use basic auth. +# patroni['username'] = nil +# patroni['password'] = nil + +## TLS configuration for Patroni API. Both certificate and key files are +## required to enable TLS. If not specified then the API uses plain HTTP. +# patroni['tls_certificate_file'] = nil +# patroni['tls_key_file'] = nil +# patroni['tls_key_password'] = nil +# patroni['tls_ca_file'] = nil +# patroni['tls_ciphers'] = nil +# patroni['tls_client_mode'] = nil +# patroni['tls_client_certificate_file'] = nil +# patroni['tls_client_key_file'] = nil +# patroni['tls_verify'] = true + +################################################################################ +# Consul (EEP only) +################################################################################ +# consul['enable'] = false +# consul['dir'] = '/var/opt/gitlab/consul' +# consul['username'] = 'gitlab-consul' +# consul['group'] = 'gitlab-consul' +# consul['config_file'] = '/var/opt/gitlab/consul/config.json' +# consul['config_dir'] = '/var/opt/gitlab/consul/config.d' +# consul['data_dir'] = '/var/opt/gitlab/consul/data' +# consul['log_directory'] = '/var/log/gitlab/consul' +# consul['log_group'] = nil +# consul['env_directory'] = '/opt/gitlab/etc/consul/env' +# consul['env'] = { +# 'SSL_CERT_DIR' => "/opt/gitlab/embedded/ssl/certs/" +# } +# consul['monitoring_service_discovery'] = false +# consul['node_name'] = nil +# consul['script_directory'] = '/var/opt/gitlab/consul/scripts' +# consul['configuration'] = { +# 'client_addr' => nil, +# 'datacenter' => 'gitlab_consul', +# 'enable_script_checks' => true, +# 'server' => false +# } +# consul['services'] = [] +# consul['service_config'] = { +# 'postgresql' => { +# 'service' => { +# 'name' => "postgresql", +# 'address' => '', +# 'port' => 5432, +# 'checks' => [ +# { +# 'script' => "/var/opt/gitlab/consul/scripts/check_postgresql", +# 'interval' => "10s" +# } +# ] +# } +# } +# } +# consul['watchers'] = [] +# +# consul['custom_config_dir'] = '/path/to/service/configs/directory' +# + +#### HTTP API ports +# consul['http_port'] = nil +# consul['https_port'] = nil + +#### Gossip encryption +# consul['encryption_key'] = nil +# consul['encryption_verify_incoming'] = nil +# consul['encryption_verify_outgoing'] = nil + +#### TLS settings +# consul['use_tls'] = false +# consul['tls_ca_file'] = nil +# consul['tls_certificate_file'] = nil +# consul['tls_key_file'] = nil +# consul['tls_verify_client'] = nil + +################################################################################ +# Service desk email settings +################################################################################ +### Service desk email +###! Allow users to create new service desk issues by sending an email to +###! service desk address. +###! Docs: https://docs.gitlab.com/ee/user/project/service_desk.html +# gitlab_rails['service_desk_email_enabled'] = false + +#### Service Desk Mailbox Settings (via `mail_room`) +#### Service Desk Email Address +####! The email address including the `%{key}` placeholder that will be replaced +####! to reference the item being replied to. +####! **The placeholder can be omitted but if present, it must appear in the +####! "user" part of the address (before the `@`).** +# gitlab_rails['service_desk_email_address'] = "contact_project+%{key}@gmail.com" + +#### Service Desk Email account username +####! **With third party providers, this is usually the full email address.** +####! **With self-hosted email servers, this is usually the user part of the +####! email address.** +# gitlab_rails['service_desk_email_email'] = "contact_project@gmail.com" + +#### Service Desk Email account password +# gitlab_rails['service_desk_email_password'] = "[REDACTED]" + +####! The mailbox where service desk mail will end up. Usually "inbox". +# gitlab_rails['service_desk_email_mailbox_name'] = "inbox" +####! The IDLE command timeout. +# gitlab_rails['service_desk_email_idle_timeout'] = 60 +####! The file name for internal `mail_room` JSON logfile +# gitlab_rails['service_desk_email_log_file'] = "/var/log/gitlab/mailroom/mail_room_json.log" + +#### Service Desk IMAP Settings +# gitlab_rails['service_desk_email_host'] = "imap.gmail.com" +# gitlab_rails['service_desk_email_port'] = 993 +# gitlab_rails['service_desk_email_ssl'] = true +# gitlab_rails['service_desk_email_start_tls'] = false + +#### Inbox options (for Microsoft Graph) +# gitlab_rails['service_desk_email_inbox_method'] = 'microsoft_graph' +# gitlab_rails['service_desk_email_inbox_options'] = { +# 'tenant_id': 'YOUR-TENANT-ID', +# 'client_id': 'YOUR-CLIENT-ID', +# 'client_secret': 'YOUR-CLIENT-SECRET', +# 'poll_interval': 60 # Optional +# } + +#### How service desk emails are delivered to Rails process. Accept either +#### sidekiq or webhook. The default config is webhook. +# gitlab_rails['service_desk_email_delivery_method'] = "webhook" + +#### Token to authenticate webhook requests. The token must be exactly 32 bytes, +#### encoded with base64 +# gitlab_rails['service_desk_email_auth_token'] = nil + +################################################################################ +## Spamcheck (EE only) +################################################################################# + +# spamcheck['enable'] = false +# spamcheck['dir'] = '/var/opt/gitlab/spamcheck' +# spamcheck['port'] = 8001 +# spamcheck['external_port'] = nil +# spamcheck['monitoring_address'] = ':8003' +# spamcheck['log_level'] = 'info' +# spamcheck['log_format'] = 'json' +# spamcheck['log_output'] = 'stdout' +# spamcheck['monitor_mode'] = false +# spamcheck['allowlist'] = {} +# spamcheck['denylist'] = {} +# spamcheck['log_directory'] = "/var/log/gitlab/spamcheck" +# spamcheck['log_group'] = nil +# spamcheck['env_directory'] = "/opt/gitlab/etc/spamcheck/env" +# spamcheck['env'] = { +# 'SSL_CERT_DIR' => '/opt/gitlab/embedded/ssl/cers' +# } +# spamcheck['classifier']['log_directory'] = "/var/log/gitlab/spam-classifier" diff --git a/roles/gitlab/gitlab_main/templates/nginx_custom.conf.j2 b/roles/gitlab/gitlab_main/templates/nginx_custom.conf.j2 new file mode 100644 index 0000000..bd25bc4 --- /dev/null +++ b/roles/gitlab/gitlab_main/templates/nginx_custom.conf.j2 @@ -0,0 +1,7 @@ + +large_client_header_buffers 4 64k; +proxy_send_timeout 3600s; +grpc_read_timeout 3600s; +grpc_send_timeout 3600s; +client_body_timeout 3600s; +send_timeout 3600s; diff --git a/roles/gitlab/gitlab_main/tests/inventory b/roles/gitlab/gitlab_main/tests/inventory new file mode 100644 index 0000000..878877b --- /dev/null +++ b/roles/gitlab/gitlab_main/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/roles/gitlab/gitlab_main/tests/test.yml b/roles/gitlab/gitlab_main/tests/test.yml new file mode 100644 index 0000000..02aeaa6 --- /dev/null +++ b/roles/gitlab/gitlab_main/tests/test.yml @@ -0,0 +1,5 @@ +--- +- hosts: localhost + remote_user: root + roles: + - gitlab_main diff --git a/roles/gitlab/gitlab_main/vars/main.yml b/roles/gitlab/gitlab_main/vars/main.yml new file mode 100644 index 0000000..a9654d0 --- /dev/null +++ b/roles/gitlab/gitlab_main/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for gitlab_main diff --git a/roles/keycloak/keycloak_base/defaults/main.yml b/roles/keycloak/keycloak_base/defaults/main.yml new file mode 100644 index 0000000..6bc9769 --- /dev/null +++ b/roles/keycloak/keycloak_base/defaults/main.yml @@ -0,0 +1,21 @@ +--- +Keycloak_container_enabled : true + + +keycloak_docker_image : quay.io/keycloak/keycloak:latest +# keycloak_docker_image_customized: "localhost/keycloak:customized" + + + +keycloak_customized_files_path: "/opt/keycloak" + +keycloak_keys_files_path: "{{keycloak_customized_files_path}}/keys" +keycloak_keysstore_file_path: "{{keycloak_keys_files_path}}/keycloak.novacloud.ir.keystore" + +keycloak_port : 8443 + +keycloak_published_port: "8080:8080" + +postgres_container_image : postgres + +postgres_files_path : "{{keycloak_customized_files_path}}/postgres" diff --git a/roles/keycloak/keycloak_base/tasks/main.yml b/roles/keycloak/keycloak_base/tasks/main.yml new file mode 100644 index 0000000..dcc3485 --- /dev/null +++ b/roles/keycloak/keycloak_base/tasks/main.yml @@ -0,0 +1,7 @@ +--- +- block: + - when: Keycloak_container_enabled | bool + ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_all.yml" + tags: + - setup-all + - install-all diff --git a/roles/keycloak/keycloak_base/tasks/setup_all.yml b/roles/keycloak/keycloak_base/tasks/setup_all.yml new file mode 100644 index 0000000..4c432e2 --- /dev/null +++ b/roles/keycloak/keycloak_base/tasks/setup_all.yml @@ -0,0 +1,114 @@ +--- + +- name: Ensure Keycloak paths exist + ansible.builtin.file: + path: "{{ item.path }}" + state: directory + mode: 0750 + # owner: "{{ matrix_user_username }}" + # group: "{{ matrix_user_groupname }}" + with_items: + - {path: "{{ postgres_files_path }}", when: true} + # - {path: "{{ keycloak_keys_files_path }}", when: true} + + +- name: Create a network + community.docker.docker_network: + name: "{{ matrix_docker_network }}" + +- name: Pull an image {{ postgres_container_image }} + community.docker.docker_image: + name: "{{ postgres_container_image }}" + source: pull + pull: + platform: amd64 + +- name: run Postgres in a container + docker_container: + name: "{{keycloak_postgresql_database_hostname}}" + image: "{{postgres_container_image}}" + restart_policy: always + state: started + privileged: yes + networks: + - name: keycloak-network + env: + POSTGRES_DB : "{{keycloak_postgresql_database}}" + POSTGRES_USER : "{{keycloak_postgresql_database_username}}" + POSTGRES_PASSWORD: "{{ keycloak_postgresql_database_password }}" + volumes: + - "{{ postgres_files_path }}:/var/lib/postgresql/data" + + +- name: Pull an image {{ keycloak_docker_image }} + community.docker.docker_image: + name: "{{ keycloak_docker_image }}" + source: pull + pull: + platform: amd64 + +- name: run Keycloak in a container + docker_container: + name: keycloak + image: "{{keycloak_docker_image}}" + restart_policy: always + state: started + privileged: yes + exposed_ports: + - "{{keycloak_port}}" + published_ports: + - "{{keycloak_published_port}}" + - 8443:8443 + env: + KC_DB : "postgres" + KC_DB_URL : "jdbc:postgresql://{{ keycloak_postgresql_database_hostname }}/{{ keycloak_postgresql_database }}" + KC_DB_USERNAME: "{{ keycloak_postgresql_database_username }}" + KC_DB_PASSWORD : "{{ keycloak_postgresql_database_password }}" + KC_HOSTNAME : "{{ fqn_keycloak }}" + KC_FEATURES : "token-exchange" + KC_HEALTH_ENABLED : "true" + KC_METRICS_ENABLED : "true" + KEYCLOAK_ADMIN : "admin" + KC_HOSTNAME_STRICT: "false" + # KC_LOG_LEVEL: "debug" + # KC_HTTPS_KEY_STORE_FILE: "{{keycloak_keysstore_file_path}}" + # KC_HTTPS_KEY_STORE_PASSWORD: "{{keycloak_keysstore_file_password}}" + KC_PROXY : "edge" + # KC_HTTP_ENABLED: "true" + KEYCLOAK_ADMIN_PASSWORD : "{{ keycloak_admin_password }}" + networks: + - name: keycloak-network + #volumes: + # - "/opt/keycloak/keys/:/opt/keycloak/keys/" + command: start + + + + + + # - name: Ensure Keycloak paths exist + # ansible.builtin.file: + # path: "{{ item.path }}" + # state: directory + # mode: 0750 + # owner: "{{ matrix_user_username }}" + # group: "{{ matrix_user_groupname }}" + # with_items: + # - {path: "{{ keycloak_customized_files_path }}", when: true} + + # - name: Ensure customizations Keycloak Dockerfile is created + # ansible.builtin.template: + # src: "{{ role_path }}/templates/Dockerfile.j2" + # dest: "{{ keycloak_customized_files_path }}/Dockerfile" + # owner: "{{ matrix_user_username }}" + # group: "{{ matrix_user_groupname }}" + # mode: 0640 + + # - name: Ensure customized Docker image for Keycloak is built + # community.docker.docker_image: + # name: "{{ keycloak_docker_image_customized }}" + # source: build + # build: + # dockerfile: Dockerfile + # path: "{{ keycloak_customized_files_path }}" + # pull: true diff --git a/roles/keycloak/keycloak_base/templates/Dockerfile.j2 b/roles/keycloak/keycloak_base/templates/Dockerfile.j2 new file mode 100644 index 0000000..ecffdde --- /dev/null +++ b/roles/keycloak/keycloak_base/templates/Dockerfile.j2 @@ -0,0 +1,23 @@ +FROM {{ keycloak_docker_image }} + +# Enable health and metrics support +ENV KC_HEALTH_ENABLED=true +ENV KC_METRICS_ENABLED=true + +# Configure a database vendor +ENV KC_DB=postgres + +WORKDIR /opt/keycloak +# for demonstration purposes only, please make sure to use proper certificates in production instead +RUN keytool -genkeypair -storepass password -storetype PKCS12 -keyalg RSA -keysize 2048 -dname "CN=server" -alias server -ext "SAN:c=DNS:localhost,IP:127.0.0.1" -keystore conf/server.keystore +RUN /opt/keycloak/bin/kc.sh build + +FROM quay.io/keycloak/keycloak:latest +COPY --from=builder /opt/keycloak/ /opt/keycloak/ + +# change these values to point to a running postgres instance +ENV KC_DB_URL= +ENV KC_DB_USERNAME=admin +ENV KC_DB_PASSWORD= {{ devture_postgres_connection_password }} +ENV KC_HOSTNAME=localhost +ENTRYPOINT ["/opt/keycloak/bin/kc.sh"] \ No newline at end of file diff --git a/roles/keycloak/keycloak_custom/tasks/main.yml b/roles/keycloak/keycloak_custom/tasks/main.yml new file mode 100644 index 0000000..183692c --- /dev/null +++ b/roles/keycloak/keycloak_custom/tasks/main.yml @@ -0,0 +1,35 @@ + +- name: Create or update Keycloak realm + community.general.keycloak_realm: + auth_client_id: admin-cli + auth_keycloak_url: "https://{{ fqn_keycloak }}" + auth_realm: master + auth_username: admin + auth_password: "{{ keycloak_admin_password }}" + id: "{{keycloak_realm_name}}" + realm: "{{keycloak_realm_name}}" + state: present + tags: + - setup-all + - install-all + + +- name: Create or update Keycloak client + community.general.keycloak_client: + auth_client_id: admin-cli + auth_keycloak_url: "https://{{ fqn_keycloak }}" + auth_realm: master + realm: "{{keycloak_realm_name}}" + auth_username: admin + auth_password: "{{ keycloak_admin_password }}" + client_id: "{{keycloak_client_id}}" + secret: "{{vault_synapse_keycloak}}" + redirect_uris: "https://matrix.test-plantmicrobe.de/_synapse/client/oidc/callback" + frontchannel_logout: true + attributes: + backchannel.logout.url: "https://matrix.test-plantmicrobe.de/_synapse/client/oidc/backchannel_logout" + state: present + # delegate_to: localhost + tags: + - setup-all + - install-all \ No newline at end of file diff --git a/roles/nginx-proxy/defaults/main.yml b/roles/nginx-proxy/defaults/main.yml new file mode 100644 index 0000000..72ad05b --- /dev/null +++ b/roles/nginx-proxy/defaults/main.yml @@ -0,0 +1,663 @@ +--- +# Project source code URL: https://github.com/nginx/nginx +matrix_nginx_proxy_enabled: true +matrix_nginx_proxy_version: 1.23.2-alpine + +# We use an official nginx image, which we fix-up to run unprivileged. +# An alternative would be an `nginxinc/nginx-unprivileged` image, but +# that is frequently out of date. +matrix_nginx_proxy_docker_image: "{{ matrix_container_global_registry_prefix }}nginx:{{ matrix_nginx_proxy_version }}" +matrix_nginx_proxy_docker_image_force_pull: "{{ matrix_nginx_proxy_docker_image.endswith(':latest') }}" + +matrix_nginx_proxy_base_path: "{{ matrix_base_data_path }}/nginx-proxy" +matrix_nginx_proxy_data_path: "{{ matrix_nginx_proxy_base_path }}/data" +matrix_nginx_proxy_data_path_in_container: "/nginx-data" +matrix_nginx_proxy_data_path_extension: "/matrix-domain" +matrix_nginx_proxy_confd_path: "{{ matrix_nginx_proxy_base_path }}/conf.d" + +# List of systemd services that matrix-nginx-proxy.service depends on +matrix_nginx_proxy_systemd_required_services_list: ['docker.service'] + +# List of systemd services that matrix-nginx-proxy.service wants +matrix_nginx_proxy_systemd_wanted_services_list: [] + +# A list of additional container networks that matrix-nginx-proxy would be connected to. +# The playbook does not create these networks, so make sure they already exist. +# +# Use this to expose matrix-nginx-proxy to another reverse proxy, which runs in a different container network, +# without exposing all other Matrix services to that other reverse-proxy. +# +# For background, see: https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1498 +matrix_nginx_proxy_container_additional_networks: [] + +# A list of additional "volumes" to mount in the container. +# This list gets populated dynamically at runtime. You can provide a different default value, +# if you wish to mount your own files into the container. +# Contains definition objects like this: `{"src": "/outside", "dst": "/inside", "options": "rw|ro|slave|.."} +matrix_nginx_proxy_container_additional_volumes: [] + +# A list of extra arguments to pass to the container +matrix_nginx_proxy_container_extra_arguments: [] + +# Controls whether matrix-nginx-proxy serves its vhosts over HTTPS or HTTP. +# +# If enabled: +# - SSL certificates would be expected to be available (see `matrix_ssl_retrieval_method`) +# - the HTTP vhost would be made a redirect to the HTTPS vhost +# +# If not enabled: +# - you don't need any SSL certificates (you can set `matrix_ssl_retrieval_method: none`) +# - naturally, there's no HTTPS vhost +# - services are served directly from the HTTP vhost +matrix_nginx_proxy_https_enabled: true + +# Controls whether matrix-nginx-proxy trusts an upstream server's X-Forwarded-Proto header +# +# Required if you disable HTTPS for the container (see `matrix_nginx_proxy_https_enabled`) and have an upstream server handle it instead. +matrix_nginx_proxy_trust_forwarded_proto: false +matrix_nginx_proxy_x_forwarded_proto_value: "{{ '$http_x_forwarded_proto' if matrix_nginx_proxy_trust_forwarded_proto else '$scheme' }}" + +# Controls whether the matrix-nginx-proxy container exposes its HTTP port (tcp/8080 in the container). +# +# Takes an ":" or "" value (e.g. "127.0.0.1:80"), or empty string to not expose. +matrix_nginx_proxy_container_http_host_bind_port: '80' + +# Controls whether the matrix-nginx-proxy container exposes its HTTPS port (tcp/8443 in the container). +# +# Takes an ":" or "" value (e.g. "127.0.0.1:443"), or empty string to not expose. +# +# This only makes sense and applies if `matrix_nginx_proxy_https_enabled` is set to `true`. +# Otherwise, there are no HTTPS vhosts to expose. +matrix_nginx_proxy_container_https_host_bind_port: '443' + +# Controls whether the matrix-nginx-proxy container exposes the Matrix Federation port (tcp/8448 in the container). +# +# Takes an ":" or "" value (e.g. "127.0.0.1:8448"), or empty string to not expose. +# +# This only makes sense and applies if `matrix_nginx_proxy_proxy_matrix_federation_api_enabled` is set to `true`. +# Otherwise, there is no Matrix Federation port to expose. +# +# This port can take HTTP or HTTPS traffic, depending on `matrix_nginx_proxy_https_enabled`. +# When HTTPS is disabled, you'd likely want to only expose the port locally, and front it with another HTTPS-enabled reverse-proxy. +matrix_nginx_proxy_container_federation_host_bind_port: '8448' + +# Controls whether matrix-nginx-proxy should serve the base domain. +# +# This is useful for when you only have your Matrix server, but you need to serve +# to serve `/.well-known/matrix/*` files from the base domain for the needs of +# Server-Discovery (Federation) and for Client-Discovery. +# +# Besides serving these Matrix files, a homepage would be served with content +# as specified in the `matrix_nginx_proxy_base_domain_homepage_template` variable. +# You can also put additional files to use for this webpage +# in the `{{ matrix_nginx_proxy_data_path }}/matrix-domain` (`/matrix/nginx-proxy/data/matrix-domain`) directory. +matrix_nginx_proxy_base_domain_serving_enabled: false + +# Controls whether the base domain directory and default index.html file are created. +matrix_nginx_proxy_base_domain_create_directory: true + +matrix_nginx_proxy_base_domain_hostname: "{{ matrix_domain }}" + +# Controls whether `matrix_nginx_proxy_base_domain_homepage_template` would be dumped to an `index.html` file +# in the `/matrix/nginx-proxy/data/matrix-domain` directory. +# +# If you would instead like to serve a static website by yourself, you can disable this. +# When disabled, you're expected to put website files in `/matrix/nginx-proxy/data/matrix-domain` manually +# and can expect that the playbook won't intefere with the `index.html` file. +matrix_nginx_proxy_base_domain_homepage_enabled: true + +matrix_nginx_proxy_base_domain_homepage_template: |- + + + + + Hello from {{ matrix_domain }}! + + + +# Option to disable the access log +matrix_nginx_proxy_access_log_enabled: true + +# Controls whether proxying the riot domain should be done. +matrix_nginx_proxy_proxy_riot_compat_redirect_enabled: false +matrix_nginx_proxy_proxy_riot_compat_redirect_hostname: "riot.{{ matrix_domain }}" + +# Controls whether proxying for Synapse should be done. +matrix_nginx_proxy_proxy_synapse_enabled: false +matrix_nginx_proxy_proxy_synapse_hostname: "matrix-nginx-proxy" +matrix_nginx_proxy_proxy_synapse_federation_api_enabled: "{{ matrix_nginx_proxy_proxy_matrix_federation_api_enabled }}" +# The addresses where the Matrix Client API is, when using Synapse. +matrix_nginx_proxy_proxy_synapse_client_api_addr_with_container: "" +matrix_nginx_proxy_proxy_synapse_client_api_addr_sans_container: "" +# The addresses where the Federation API is, when using Synapse. +matrix_nginx_proxy_proxy_synapse_federation_api_addr_with_container: "" +matrix_nginx_proxy_proxy_synapse_federation_api_addr_sans_container: "" +# A list of strings containing additional configuration blocks to add to the Synapse's server configuration (matrix-synapse.conf). +matrix_nginx_proxy_proxy_synapse_additional_server_configuration_blocks: [] + +# Controls whether proxying for Dendrite should be done. +matrix_nginx_proxy_proxy_dendrite_enabled: false +matrix_nginx_proxy_proxy_dendrite_hostname: "matrix-nginx-proxy" +matrix_nginx_proxy_proxy_dendrite_federation_api_enabled: "{{ matrix_nginx_proxy_proxy_matrix_federation_api_enabled }}" +# Controls whether the Client API server (usually at matrix.DOMAIN:443) should explicitly reject `/_matrix/federation` endpoints. +# Normally, Dendrite Monolith serves both APIs (Client & Federation) at the same port, so we can serve federation at `matrix.DOMAIN:443` too. +matrix_nginx_proxy_proxy_dendrite_block_federation_api_on_client_port: true +# The addresses where the Matrix Client API is, when using Dendrite. +matrix_nginx_proxy_proxy_dendrite_client_api_addr_with_container: "" +matrix_nginx_proxy_proxy_dendrite_client_api_addr_sans_container: "" +# A list of strings containing additional configuration blocks to add to the Dendrite's server configuration (matrix-dendrite.conf). +matrix_nginx_proxy_proxy_dendrite_additional_server_configuration_blocks: [] + +# Controls whether proxying for Conduit should be done. +matrix_nginx_proxy_proxy_conduit_enabled: false +matrix_nginx_proxy_proxy_conduit_hostname: "matrix-nginx-proxy" +matrix_nginx_proxy_proxy_conduit_federation_api_enabled: "{{ matrix_nginx_proxy_proxy_matrix_federation_api_enabled }}" +# Controls whether the Client API server (usually at matrix.DOMAIN:443) should explicitly reject `/_matrix/federation` endpoints. +matrix_nginx_proxy_proxy_conduit_block_federation_api_on_client_port: true +# The addresses where the Matrix Client API is, when using Conduit. +matrix_nginx_proxy_proxy_conduit_client_api_addr_with_container: "" +matrix_nginx_proxy_proxy_conduit_client_api_addr_sans_container: "" +# The addresses where the Federation API is, when using Conduit. +matrix_nginx_proxy_proxy_conduit_federation_api_addr_with_container: "" +matrix_nginx_proxy_proxy_conduit_federation_api_addr_sans_container: "" +# A list of strings containing additional configuration blocks to add to the Conduit's server configuration (matrix-conduit.conf). +matrix_nginx_proxy_proxy_conduit_additional_server_configuration_blocks: [] + +# Controls whether proxying the Element domain should be done. +matrix_nginx_proxy_proxy_element_enabled: false +matrix_nginx_proxy_proxy_element_hostname: "{{ matrix_server_fqn_element }}" + +# Controls whether proxying the Hydrogen domain should be done. +matrix_nginx_proxy_proxy_hydrogen_enabled: false +matrix_nginx_proxy_proxy_hydrogen_hostname: "{{ matrix_server_fqn_hydrogen }}" + +# Controls whether proxying the Cinny domain should be done. +matrix_nginx_proxy_proxy_cinny_enabled: false +matrix_nginx_proxy_proxy_cinny_hostname: "{{ matrix_server_fqn_cinny }}" + +# Controls whether proxying the buscarron domain should be done. +matrix_nginx_proxy_proxy_buscarron_enabled: false +matrix_nginx_proxy_proxy_buscarron_hostname: "{{ matrix_server_fqn_buscarron }}" + +# Controls whether proxying the matrix domain should be done. +matrix_nginx_proxy_proxy_matrix_enabled: false +matrix_nginx_proxy_proxy_matrix_hostname: "{{ matrix_server_fqn_matrix }}" +matrix_nginx_proxy_proxy_matrix_federation_hostname: "{{ matrix_nginx_proxy_proxy_matrix_hostname }}" +# The port name used for federation in the nginx configuration. +# This is not necessarily the port that it's actually on, +# as port-mapping happens (`-p ..`) for the `matrix-nginx-proxy` container. +matrix_nginx_proxy_proxy_matrix_federation_port: 8448 + +# Controls whether proxying the dimension domain should be done. +matrix_nginx_proxy_proxy_dimension_enabled: false +matrix_nginx_proxy_proxy_dimension_hostname: "{{ matrix_server_fqn_dimension }}" + +# Controls whether proxying the etherpad domain should be done. +matrix_nginx_proxy_proxy_etherpad_enabled: false +matrix_nginx_proxy_proxy_etherpad_hostname: "{{ matrix_server_fqn_etherpad }}" + +# Controls whether proxying the goneb domain should be done. +matrix_nginx_proxy_proxy_bot_go_neb_enabled: false +matrix_nginx_proxy_proxy_bot_go_neb_hostname: "{{ matrix_server_fqn_bot_go_neb }}" + +# Controls whether proxying the jitsi domain should be done. +matrix_nginx_proxy_proxy_jitsi_enabled: false +matrix_nginx_proxy_proxy_jitsi_hostname: "{{ matrix_server_fqn_jitsi }}" + +# Controls whether proxying the grafana domain should be done. +matrix_nginx_proxy_proxy_grafana_enabled: false +matrix_nginx_proxy_proxy_grafana_hostname: "{{ matrix_server_fqn_grafana }}" + +# Controls whether proxying the sygnal domain should be done. +matrix_nginx_proxy_proxy_sygnal_enabled: false +matrix_nginx_proxy_proxy_sygnal_hostname: "{{ matrix_server_fqn_sygnal }}" + +# Controls whether proxying the ntfy domain should be done. +matrix_nginx_proxy_proxy_ntfy_enabled: false +matrix_nginx_proxy_proxy_ntfy_hostname: "{{ matrix_server_fqn_ntfy }}" + + +matrix_nginx_proxy_proxy_keycloak_enabled: false +matrix_nginx_proxy_proxy_keycloak_hostname: "{{ fqn_keycloak }}" + +matrix_nginx_proxy_proxy_gitlab_enabled: false +matrix_nginx_proxy_proxy_gitlab_hostname: "{{ fqn_gitlab }}" + +# Controls whether proxying for (Prometheus) metrics (`/metrics/*`) for the various services should be done (on the matrix domain) +# If the internal Prometheus server (`matrix-prometheus` role) is used, proxying is not necessary, since Prometheus can access each container directly. +# This is only useful when an external Prometheus will be collecting metrics. +# +# To control what kind of metrics are exposed under `/metrics/` (e.g `/metrics/node-exporter`, `/metrics/postgres-exporter`, etc.), +# use `matrix_SERVICE_metrics_proxying_enabled` variables in each respective role. +# Roles inject themselves into the matrix-nginx-proxy configuration. +# +# To protect the metrics endpoints, see `matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_enabled` +matrix_nginx_proxy_proxy_matrix_metrics_enabled: false + +# Controls whether Basic Auth is enabled for all `/metrics/*` endpoints. +# +# You can provide the Basic Auth credentials in 2 ways: +# 1. A single username/password pair using `matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_username` and `matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_password` +# 2. Using raw content (`htpasswd`-generated file) provided in `matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_raw_content` +matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_enabled: false + +# `matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_username` and `matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_password` specify +# the Basic Auth username/password for protecting `/metrics/*` endpoints. +# Alternatively, use `matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_raw_content`. +matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_username: "" +matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_password: "" + +# `matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_raw_content` value will be written verbatim to the htpasswd file protecting `/metrics/*` endpoints. +# Use this when a single username/password is not enough and you'd like to get more control over credentials. +# +# Read the manpage at `man 1 htpasswd` to learn more, then encrypt your password, and paste the encrypted value here. +# e.g. `htpasswd -c mypass.htpasswd prometheus` and enter `mysecurepw` when prompted yields `prometheus:$apr1$wZhqsn.U$7LC3kMmjUbjNAZjyMyvYv/` +# The whole thing is needed here. matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_raw_content: "prometheus:$apr1$wZhqsn.U$7LC3kMmjUbjNAZjyMyvYv/" +matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_raw_content: "" + +# Specifies the path to the htpasswd file holding the htpasswd credentials for protecting `/metrics/*` endpoints +# This is not meant to be modified. +matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_path: "{{ matrix_nginx_proxy_data_path_in_container if matrix_nginx_proxy_enabled else matrix_nginx_proxy_data_path }}/matrix-metrics-htpasswd" + +# Specifies the Apache container image to use +# when `matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_username` and `matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_password` are provided. +# This image provides the `htpasswd` tool which we use for generating the htpasswd file protecting `/metrics/*`. +# To avoid using this, use `matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_raw_content` instead of supplying username/password. +# Learn more in: `roles/nginx-proxy/tasks/nginx-proxy/setup_metrics_auth.yml`. +matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_apache_container_image: "{{ matrix_container_global_registry_prefix }}httpd:{{ matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_apache_container_image_tag }}" +matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_apache_container_image_tag: "2.4.54-alpine3.16" +matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_apache_container_force_pull: "{{ matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_apache_container_image_tag.endswith(':latest') }}" + +# A list of strings containing additional configuration blocks to add to the `location /metrics` configuration (matrix-domain.conf). +# Do not modify `matrix_nginx_proxy_proxy_matrix_metrics_additional_location_configuration_blocks` and `matrix_nginx_proxy_proxy_matrix_metrics_additional_system_location_configuration_blocks`. +# If you'd like to inject your own configuration blocks, use `matrix_nginx_proxy_proxy_matrix_metrics_additional_user_location_configuration_blocks`. +matrix_nginx_proxy_proxy_matrix_metrics_additional_location_configuration_blocks: "{{ matrix_nginx_proxy_proxy_matrix_metrics_additional_system_location_configuration_blocks + matrix_nginx_proxy_proxy_matrix_metrics_additional_user_location_configuration_blocks }}" +matrix_nginx_proxy_proxy_matrix_metrics_additional_system_location_configuration_blocks: [] +matrix_nginx_proxy_proxy_matrix_metrics_additional_user_location_configuration_blocks: [] + +# Controls whether proxying for the matrix-corporal API (`/_matrix/corporal`) should be done (on the matrix domain) +matrix_nginx_proxy_proxy_matrix_corporal_api_enabled: false +matrix_nginx_proxy_proxy_matrix_corporal_api_addr_with_container: "matrix-corporal:41081" +matrix_nginx_proxy_proxy_matrix_corporal_api_addr_sans_container: "127.0.0.1:41081" + +# Controls whether proxying for the User Directory Search API (`/_matrix/client/r0/user_directory/search`) should be done (on the matrix domain). +# This can be used to forward the API endpoint to another service, augmenting the functionality of Synapse's own User Directory Search. +# To learn more, see: https://github.com/ma1uta/ma1sd/blob/master/docs/features/directory.md +matrix_nginx_proxy_proxy_matrix_user_directory_search_enabled: false +matrix_nginx_proxy_proxy_matrix_user_directory_search_addr_with_container: "matrix-ma1sd:{{ matrix_ma1sd_container_port }}" +matrix_nginx_proxy_proxy_matrix_user_directory_search_addr_sans_container: "127.0.0.1:{{ matrix_ma1sd_container_port }}" + +# Controls whether proxying for 3PID-based registration (`/_matrix/client/r0/register/(email|msisdn)/requestToken`) should be done (on the matrix domain). +# This allows another service to control registrations involving 3PIDs. +# To learn more, see: https://github.com/ma1uta/ma1sd/blob/master/docs/features/registration.md +matrix_nginx_proxy_proxy_matrix_3pid_registration_enabled: false +matrix_nginx_proxy_proxy_matrix_3pid_registration_addr_with_container: "matrix-ma1sd:{{ matrix_ma1sd_container_port }}" +matrix_nginx_proxy_proxy_matrix_3pid_registration_addr_sans_container: "127.0.0.1:{{ matrix_ma1sd_container_port }}" + +# Controls whether proxying for the Identity API (`/_matrix/identity`) should be done (on the matrix domain) +matrix_nginx_proxy_proxy_matrix_identity_api_enabled: false +matrix_nginx_proxy_proxy_matrix_identity_api_addr_with_container: "matrix-ma1sd:{{ matrix_ma1sd_container_port }}" +matrix_nginx_proxy_proxy_matrix_identity_api_addr_sans_container: "127.0.0.1:{{ matrix_ma1sd_container_port }}" + +# The addresses where the Matrix Client API is. +# Certain extensions (like matrix-corporal) may override this in order to capture all traffic. +matrix_nginx_proxy_proxy_matrix_client_api_addr_with_container: "matrix-nginx-proxy:12080" +matrix_nginx_proxy_proxy_matrix_client_api_addr_sans_container: "127.0.0.1:12080" + +# This needs to be equal or higher than the maximum upload size accepted by Synapse. +matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb: 100 + + +# Tells whether `/_synapse/client` is forwarded to the Matrix Client API server. +matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_synapse_client_api_enabled: true + +# Tells whether `/_synapse/oidc` is forwarded to the Matrix Client API server. +# Enable this if you need OpenID Connect authentication support. +matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_synapse_oidc_api_enabled: false + +# Tells whether `/_synapse/admin` is forwarded to the Matrix Client API server. +# Following these recommendations (https://github.com/matrix-org/synapse/blob/master/docs/reverse_proxy.md), by default, we don't. +matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_synapse_admin_api_enabled: false + +# `matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_prefixes` holds +# the location prefixes that get forwarded to the Matrix Client API server. +# These locations get combined into a regex like this `^(/_matrix|/_synapse/client)`. +matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_prefix_regexes: | + {{ + (['/_matrix']) + + + (['/_synapse/client'] if matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_synapse_client_api_enabled else []) + + + (['/_synapse/oidc'] if matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_synapse_oidc_api_enabled else []) + + + (['/_synapse/admin'] if matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_synapse_admin_api_enabled else []) + }} + +# Specifies where requests for the root URI (`/`) on the `matrix.` domain should be redirected. +# If this has an empty value, they're just passed to the homeserver, which serves a static page. +# If you'd like to make `https://matrix.DOMAIN` redirect to `https://element.DOMAIN` (or something of that sort), specify the domain name here. +# Example value: `element.DOMAIN` (or `{{ matrix_server_fqn_element }}`). +matrix_nginx_proxy_proxy_matrix_client_redirect_root_uri_to_domain: "" + +# Controls whether proxying for the Matrix Federation API should be done. +matrix_nginx_proxy_proxy_matrix_federation_api_enabled: false +matrix_nginx_proxy_proxy_matrix_federation_api_addr_with_container: "matrix-nginx-proxy:12088" +matrix_nginx_proxy_proxy_matrix_federation_api_addr_sans_container: "127.0.0.1:12088" +matrix_nginx_proxy_proxy_matrix_federation_api_client_max_body_size_mb: "{{ (matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb | int) * 3 }}" +matrix_nginx_proxy_proxy_matrix_federation_api_ssl_certificate: "{{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_matrix_hostname }}/fullchain.pem" +matrix_nginx_proxy_proxy_matrix_federation_api_ssl_certificate_key: "{{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_matrix_hostname }}/privkey.pem" +matrix_nginx_proxy_proxy_matrix_federation_api_ssl_trusted_certificate: "{{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_matrix_hostname }}/chain.pem" + +# The tmpfs at /tmp needs to be large enough to handle multiple concurrent file uploads. +matrix_nginx_proxy_tmp_directory_size_mb: "{{ (matrix_nginx_proxy_proxy_matrix_federation_api_client_max_body_size_mb | int) * 50 }}" +matrix_nginx_proxy_tmp_cache_directory_size_mb: "{{ (matrix_nginx_proxy_synapse_cache_max_size_mb | int) * 2 }}" +# A list of strings containing additional configuration blocks to add to the nginx server configuration (nginx.conf). +# for big matrixservers to enlarge the number of open files to prevent timeouts +# matrix_nginx_proxy_proxy_additional_configuration_blocks: +# - 'worker_rlimit_nofile 30000;' +matrix_nginx_proxy_proxy_additional_configuration_blocks: [] + +# A list of strings containing additional configuration blocks to add to the nginx event server configuration (nginx.conf). +matrix_nginx_proxy_proxy_event_additional_configuration_blocks: [] + +# A list of strings containing additional configuration blocks to add to the nginx http's server configuration (nginx-http.conf). +matrix_nginx_proxy_proxy_http_additional_server_configuration_blocks: [] + +# A list of strings containing additional configuration blocks to add to the base matrix server configuration (matrix-domain.conf). +matrix_nginx_proxy_proxy_matrix_additional_server_configuration_blocks: [] + +# A list of strings containing additional configuration blocks to add to Riot's server configuration (matrix-riot-web.conf). +matrix_nginx_proxy_proxy_riot_additional_server_configuration_blocks: [] + +# A list of strings containing additional configuration blocks to add to Element's server configuration (matrix-client-element.conf). +matrix_nginx_proxy_proxy_element_additional_server_configuration_blocks: [] + +# A list of strings containing additional configuration blocks to add to Hydrogen's server configuration (matrix-client-hydrogen.conf). +matrix_nginx_proxy_proxy_hydrogen_additional_server_configuration_blocks: [] + +# A list of strings containing additional configuration blocks to add to Cinny's server configuration (matrix-client-cinny.conf). +matrix_nginx_proxy_proxy_cinny_additional_server_configuration_blocks: [] + +# A list of strings containing additional configuration blocks to add to buscarron's server configuration (matrix-bot-buscarron.conf). +matrix_nginx_proxy_proxy_buscarron_additional_server_configuration_blocks: [] + +# A list of strings containing additional configuration blocks to add to Dimension's server configuration (matrix-dimension.conf). +matrix_nginx_proxy_proxy_dimension_additional_server_configuration_blocks: [] + +# A list of strings containing additional configuration blocks to add to etherpad's server configuration (matrix-etherpad.conf). +matrix_nginx_proxy_proxy_etherpad_additional_server_configuration_blocks: [] + +# A list of strings containing additional configuration blocks to add to GoNEB's server configuration (matrix-bot-go-neb.conf). +matrix_nginx_proxy_proxy_bot_go_neb_additional_server_configuration_blocks: [] + +# A list of strings containing additional configuration blocks to add to Jitsi's server configuration (matrix-jitsi.conf). +matrix_nginx_proxy_proxy_jitsi_additional_server_configuration_blocks: [] + +# A list of strings containing additional configuration blocks to add to Grafana's server configuration (matrix-grafana.conf). +matrix_nginx_proxy_proxy_grafana_additional_server_configuration_blocks: [] + +# A list of strings containing additional configuration blocks to add to Sygnal's server configuration (matrix-sygnal.conf). +matrix_nginx_proxy_proxy_sygnal_additional_server_configuration_blocks: [] + +# A list of strings containing additional configuration blocks to add to ntfy's server configuration (matrix-ntfy.conf). +matrix_nginx_proxy_proxy_ntfy_additional_server_configuration_blocks: [] + +# A list of strings containing additional configuration blocks to add to the base domain server configuration (matrix-base-domain.conf). +matrix_nginx_proxy_proxy_domain_additional_server_configuration_blocks: [] + +# To increase request timeout in NGINX using proxy_read_timeout, proxy_connect_timeout, proxy_send_timeout, send_timeout directives +# Nginx Default: proxy_connect_timeout 60s; #Defines a timeout for establishing a connection with a proxied server +# Nginx Default: proxy_send_timeout 60s; #Sets a timeout for transmitting a request to the proxied server. +# Nginx Default: proxy_read_timeout 60s; #Defines a timeout for reading a response from the proxied server. +# Nginx Default: send_timeout 60s; #Sets a timeout for transmitting a response to the client. +# +# For more information visit: +# http://nginx.org/en/docs/http/ngx_http_proxy_module.html +# http://nginx.org/en/docs/http/ngx_http_core_module.html#send_timeout +# https://www.nginx.com/resources/wiki/start/topics/examples/fullexample2/ +# +# Here we are sticking with nginx default values change this value carefully. +matrix_nginx_proxy_connect_timeout: 60 +matrix_nginx_proxy_send_timeout: 60 +matrix_nginx_proxy_read_timeout: 60 +matrix_nginx_send_timeout: 60 + +# Controls whether to send a "Permissions-Policy interest-cohort=();" header along with all responses for all vhosts meant to be accessed by users. +# +# Learn more about what it is here: +# - https://www.eff.org/deeplinks/2021/03/googles-floc-terrible-idea +# - https://paramdeo.com/blog/opting-your-website-out-of-googles-floc-network +# - https://amifloced.org/ +# +# Of course, a better solution is to just stop using browsers (like Chrome), which participate in such tracking practices. +matrix_nginx_proxy_floc_optout_enabled: true + +# HSTS Preloading Enable +# +# In its strongest and recommended form, the [HSTS policy](https://www.chromium.org/hsts) includes all subdomains, and +# indicates a willingness to be “preloaded” into browsers: +# `Strict-Transport-Security: max-age=31536000; includeSubDomains; preload` +# For more information visit: +# - https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security +# - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security +# - https://hstspreload.org/#opt-in +matrix_nginx_proxy_hsts_preload_enabled: false + +# X-XSS-Protection Enable +# Stops pages from loading when they detect reflected cross-site scripting (XSS) attacks. +# Note: Not applicable for grafana +# +# Learn more about it is here: +# - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection +# - https://portswigger.net/web-security/cross-site-scripting/reflected +matrix_nginx_proxy_xss_protection: "1; mode=block" + +# Specifies the SSL configuration that should be used for the SSL protocols and ciphers +# This is based on the Mozilla Server Side TLS Recommended configurations. +# +# The posible values are: +# - "modern" - For Modern clients that support TLS 1.3, with no need for backwards compatibility +# - "intermediate" - Recommended configuration for a general-purpose server +# - "old" - Services accessed by very old clients or libraries, such as Internet Explorer 8 (Windows XP), Java 6, or OpenSSL 0.9.8 +# +# For more information visit: +# - https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations +# - https://ssl-config.mozilla.org/#server=nginx +matrix_nginx_proxy_ssl_preset: "intermediate" + +# Presets are taken from Mozilla's Server Side TLS Recommended configurations +# DO NOT modify these values and use `matrix_nginx_proxy_ssl_protocols`, `matrix_nginx_proxy_ssl_ciphers` and `matrix_nginx_proxy_ssl_ciphers` +# if you wish to use something more custom. +matrix_nginx_proxy_ssl_presets: + modern: + protocols: TLSv1.3 + ciphers: "" + prefer_server_ciphers: "off" + intermediate: + protocols: TLSv1.2 TLSv1.3 + ciphers: ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 + prefer_server_ciphers: "off" + old: + protocols: TLSv1 TLSv1.1 TLSv1.2 TLSv1.3 + ciphers: ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA + prefer_server_ciphers: "on" + + +# Specifies which *SSL protocols* to use when serving all the various vhosts. +matrix_nginx_proxy_ssl_protocols: "{{ matrix_nginx_proxy_ssl_presets[matrix_nginx_proxy_ssl_preset]['protocols'] }}" + +# Specifies whether to prefer *the client’s choice or the server’s choice* when negotiating ciphers. +matrix_nginx_proxy_ssl_prefer_server_ciphers: "{{ matrix_nginx_proxy_ssl_presets[matrix_nginx_proxy_ssl_preset]['prefer_server_ciphers'] }}" + +# Specifies which *SSL Cipher suites* to use when serving all the various vhosts. +# To see the full list for suportes ciphers run `openssl ciphers` on your server +matrix_nginx_proxy_ssl_ciphers: "{{ matrix_nginx_proxy_ssl_presets[matrix_nginx_proxy_ssl_preset]['ciphers'] }}" + +# Specifies what to use for the X-Forwarded-For variable. +# If you're fronting the nginx reverse-proxy with additional reverse-proxy servers, +# you may wish to set this to '$proxy_add_x_forwarded_for' instead. +matrix_nginx_proxy_x_forwarded_for: '$remote_addr' + +# Controls whether the self-check feature should validate SSL certificates. +matrix_nginx_proxy_self_check_validate_certificates: true + +# Controls whether redirects will be followed when checking the `/.well-known/matrix/client` resource. +# +# As per the spec (https://matrix.org/docs/spec/client_server/r0.6.0#well-known-uri), it shouldn't be, +# so we default to not following redirects as well. +matrix_nginx_proxy_self_check_well_known_matrix_client_follow_redirects: none + +# For OCSP purposes, we need to define a resolver at the `server{}` level or `http{}` level (we do the latter). +# +# Otherwise, we get warnings like this: +# > [warn] 22#22: no resolver defined to resolve r3.o.lencr.org while requesting certificate status, responder: r3.o.lencr.org, certificate: "/matrix/ssl/config/live/.../fullchain.pem" +# +# We point it to the internal Docker resolver, which likely delegates to nameservers defined in `/etc/resolv.conf`. +# +# When nginx proxy is disabled, our configuration is likely used by non-containerized nginx, so can't use the internal Docker resolver. +# Pointing `resolver` to some public DNS server might be an option, but for now we impose DNS servers on people. +# It might also be that no such warnings occur when not running in a container. +matrix_nginx_proxy_http_level_resolver: "{{ '127.0.0.11' if matrix_nginx_proxy_enabled else '' }}" + +# By default, this playbook automatically retrieves and auto-renews +# free SSL certificates from Let's Encrypt. +# +# The following retrieval methods are supported: +# - "lets-encrypt" - the playbook obtains free SSL certificates from Let's Encrypt +# - "self-signed" - the playbook generates and self-signs certificates +# - "manually-managed" - lets you manage certificates by yourself (manually; see below) +# - "none" - like "manually-managed", but doesn't care if you don't drop certificates in the location it expects +# +# If you decide to manage certificates by yourself (`matrix_ssl_retrieval_method: manually-managed`), +# you'd need to drop them into the directory specified by `matrix_ssl_config_dir_path` +# obeying the following hierarchy: +# - /live//fullchain.pem +# - /live//privkey.pem +# where refers to the domains that you need (usually `matrix_server_fqn_matrix` and `matrix_server_fqn_element`). +# +# The "none" type (`matrix_ssl_retrieval_method: none`), simply means that no certificate retrieval will happen. +# It's useful for when you've disabled the nginx proxy (`matrix_nginx_proxy_enabled: false`) +# and you'll be using another reverse-proxy server (like Apache) with your own certificates, managed by yourself. +# It's also useful if you're using `matrix_nginx_proxy_https_enabled: false` to make this nginx proxy serve +# plain HTTP traffic only (usually, on the loopback interface only) and you'd be terminating SSL using another reverse-proxy. +matrix_ssl_retrieval_method: "lets-encrypt" + +matrix_ssl_architecture: "amd64" + +# The full list of domains that this role will obtain certificates for. +# This variable is likely redefined outside of the role, to include the domains that are necessary (depending on the services that are enabled). +# To add additional domain names, consider using `matrix_ssl_additional_domains_to_obtain_certificates_for` instead. +matrix_ssl_domains_to_obtain_certificates_for: "{{ matrix_ssl_additional_domains_to_obtain_certificates_for }}" + +# A list of additional domain names to obtain certificates for. +matrix_ssl_additional_domains_to_obtain_certificates_for: [] + +# Controls whether to obtain production or staging certificates from Let's Encrypt. +# If you'd like to use another ACME Certificate Authority server (not Let's Encrypt), use `matrix_ssl_lets_encrypt_server` +matrix_ssl_lets_encrypt_staging: false + +# Controls from which Certificate Authority server to retrieve the SSL certificates (passed as a `--server` flag to Certbot). +# By default, we use the Let's Encrypt production environment (use `matrix_ssl_lets_encrypt_staging` for using the staging environment). +# Learn more here: https://eff-certbot.readthedocs.io/en/stable/using.html#changing-the-acme-server +matrix_ssl_lets_encrypt_server: '' + +matrix_ssl_lets_encrypt_certbot_docker_image: "{{ matrix_container_global_registry_prefix }}certbot/certbot:{{ matrix_ssl_architecture }}-v2.0.0" +matrix_ssl_lets_encrypt_certbot_docker_image_force_pull: "{{ matrix_ssl_lets_encrypt_certbot_docker_image.endswith(':latest') }}" +matrix_ssl_lets_encrypt_certbot_standalone_http_port: 2402 +matrix_ssl_lets_encrypt_support_email: ~ + +# Tells which interface and port the Let's Encrypt (certbot) container should try to bind to +# when it tries to obtain initial certificates in standalone mode. +# +# This should normally be a public interface and port. +# If you'd like to not bind on all IP addresses, specify one explicitly (e.g. `a.b.c.d:80`) +matrix_ssl_lets_encrypt_container_standalone_http_host_bind_port: '80' + +# Specify key type of the private key algorithm. +# Learn more here: https://eff-certbot.readthedocs.io/en/stable/using.html#rsa-and-ecdsa-keys +matrix_ssl_lets_encrypt_key_type: ecdsa + +matrix_ssl_base_path: "{{ matrix_base_data_path }}/ssl" +matrix_ssl_config_dir_path: "{{ matrix_ssl_base_path }}/config" +matrix_ssl_log_dir_path: "{{ matrix_ssl_base_path }}/log" +matrix_ssl_bin_dir_path: "{{ matrix_ssl_base_path }}/bin" + +# If you'd like to start some service before a certificate is obtained, specify it here. +# This could be something like `matrix-dynamic-dns`, etc. +matrix_ssl_pre_obtaining_required_service_name: ~ +matrix_ssl_pre_obtaining_required_service_start_wait_time_seconds: 60 + +# matrix_ssl_orphaned_renewal_configs_purging_enabled controls whether the playbook will delete Let's Encryption renewal configuration files (`/matrix/ssl/config/renewal/*.conf) +# for domains that are not part of the `matrix_ssl_domains_to_obtain_certificates_for` list. +# +# As the `matrix_ssl_domains_to_obtain_certificates_for` list changes over time, the playbook obtains certificates for various domains +# and sets up "renewal" configuration files to keep these certificates fresh. +# When a domain disappears from the `matrix_ssl_domains_to_obtain_certificates_for` list (because its associated service had gotten disabled), +# the certificate files and renewal configuration still remain in the filesystem and certbot may try to renewal the certificate for this domain. +# If there's no DNS record for this domain or it doesn't point to this server anymore, the `matrix-ssl-lets-encrypt-certificates-renew.service` systemd service +# won't be able to renew the certificate and will generate an error. +# +# With `matrix_ssl_orphaned_renewal_configs_purging_enabled` enabled, orphaned renewal configurations will be purged on each playbook run. +# Some other leftover files will still remain, but we don't bother purging them because they don't cause troubles. +matrix_ssl_orphaned_renewal_configs_purging_enabled: true + +# Nginx Optimize SSL Session +# +# ssl_session_cache: +# - Creating a cache of TLS connection parameters reduces the number of handshakes +# and thus can improve the performance of application. +# - Default session cache is not optimal as it can be used by only one worker process +# and can cause memory fragmentation. It is much better to use shared cache. +# - Learn More: https://nginx.org/en/docs/http/ngx_http_ssl_module.html +# +# ssl_session_timeout: +# - Nginx by default it is set to 5 minutes which is very low. +# should be like 4h or 1d but will require you to increase the size of cache. +# - Learn More: +# https://github.com/certbot/certbot/issues/6903 +# https://github.com/mozilla/server-side-tls/issues/198 +# +# ssl_session_tickets: +# - In case of session tickets, information about session is given to the client. +# Enabling this improve performance also make Perfect Forward Secrecy useless. +# - If you would instead like to use ssl_session_tickets by yourself, you can set +# matrix_nginx_proxy_ssl_session_tickets_off false. +# - Learn More: https://github.com/mozilla/server-side-tls/issues/135 +# +# Presets are taken from Mozilla's Server Side TLS Recommended configurations +matrix_nginx_proxy_ssl_session_cache: "shared:MozSSL:10m" +matrix_nginx_proxy_ssl_session_timeout: "1d" +matrix_nginx_proxy_ssl_session_tickets_off: true + +# OCSP Stapling eliminating the need for clients to contact the CA, with the aim of improving both security and performance. +# OCSP stapling can provide a performance boost of up to 30% +# nginx web server supports OCSP stapling since version 1.3.7. +# +# *warning* Nginx is lazy loading OCSP responses, which means that for the first few web requests it is unable to add the OCSP response. +# set matrix_nginx_proxy_ocsp_stapling_enabled false to disable OCSP Stapling +# +# Learn more about what it is here: +# - https://en.wikipedia.org/wiki/OCSP_stapling +# - https://blog.cloudflare.com/high-reliability-ocsp-stapling/ +# - https://blog.mozilla.org/security/2013/07/29/ocsp-stapling-in-firefox/ +matrix_nginx_proxy_ocsp_stapling_enabled: true + +# nginx status page configurations. +matrix_nginx_proxy_proxy_matrix_nginx_status_enabled: false +matrix_nginx_proxy_proxy_matrix_nginx_status_allowed_addresses: ['{{ ansible_default_ipv4.address }}'] + + +# The amount of worker processes and connections +# Consider increasing these when you are expecting high amounts of traffic +# http://nginx.org/en/docs/ngx_core_module.html#worker_connections +matrix_nginx_proxy_worker_processes: auto +matrix_nginx_proxy_worker_connections: 1024 + +# A mapping of JVB server ids to hostname/ipa addresses used to add additional jvb blocks +# to the Jitsi's server configuration (matrix-jitsi.conf) +# Note: avoid using the JVB server id "jvb-1" as this is reserved for the main host. +# Example: +# matrix_nginx_proxy_proxy_jitsi_additional_jvbs: +# jvb-2: 192.168.0.1 +# jvb-3: 192.168.0.2 +matrix_nginx_proxy_proxy_jitsi_additional_jvbs: {} diff --git a/roles/nginx-proxy/tasks/main.yml b/roles/nginx-proxy/tasks/main.yml new file mode 100644 index 0000000..39cec7e --- /dev/null +++ b/roles/nginx-proxy/tasks/main.yml @@ -0,0 +1,41 @@ +--- + +# Always validating the configuration, even if `matrix_nginx_proxy: false`. +# This role performs actions even if the role is disabled, so we need +# to ensure there's a valid configuration in any case. +- ansible.builtin.import_tasks: "{{ role_path }}/tasks/validate_config.yml" + when: run_setup | bool + tags: + - setup-all + - setup-nginx-proxy + - install-all + - install-nginx-proxy + +- ansible.builtin.import_tasks: "{{ role_path }}/tasks/ssl/main.yml" + when: run_setup | bool + tags: + - setup-all + - setup-nginx-proxy + - setup-ssl + - install-all + - install-nginx-proxy + - install-ssl + +- ansible.builtin.import_tasks: "{{ role_path }}/tasks/setup_nginx_proxy.yml" + when: run_setup | bool + tags: + - setup-all + - setup-nginx-proxy + - install-all + - install-nginx-proxy + +- block: + - ansible.builtin.include_tasks: "{{ role_path }}/tasks/self_check_well_known.yml" + tags: + - self-check + +- name: Mark matrix-nginx-proxy role as executed + ansible.builtin.set_fact: + matrix_nginx_proxy_role_executed: true + tags: + - always diff --git a/roles/nginx-proxy/tasks/nginx-proxy/setup_metrics_auth.yml b/roles/nginx-proxy/tasks/nginx-proxy/setup_metrics_auth.yml new file mode 100644 index 0000000..a72d26f --- /dev/null +++ b/roles/nginx-proxy/tasks/nginx-proxy/setup_metrics_auth.yml @@ -0,0 +1,60 @@ +--- + +# When we're dealing with raw htpasswd content, we just store it in the file directly. +- name: Ensure matrix-metrics-htpasswd is present when generated from raw content (protecting /metrics/* URIs) + ansible.builtin.copy: + content: "{{ matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_raw_content }}" + dest: "{{ matrix_nginx_proxy_data_path }}/matrix-metrics-htpasswd" + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + mode: 0600 + when: not matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_username + +# Alternatively, we need to use the `htpasswd` tool to generate the htpasswd file. +# There's an Ansible module that helps with that, but it requires passlib (a Python module) to be installed on the server. +# See: https://docs.ansible.com/ansible/2.3/htpasswd_module.html#requirements-on-host-that-executes-module +# We support various distros, with various versions of Python. Installing additional Python modules can be a hassle. +# As a workaround, we run `htpasswd` from an Apache container image. +- when: matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_username != '' + block: + - name: Ensure Apache Docker image is pulled for generating matrix-metrics-htpasswd from username/password (protecting /metrics/* URIs) + community.docker.docker_image: + name: "{{ matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_apache_container_image }}" + source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" + force_source: "{{ matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_apache_container_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_nginx_proxy_proxy_matrix_metrics_basic_auth_apache_container_force_pull }}" + register: result + retries: "{{ devture_playbook_help_container_retries_count }}" + delay: "{{ devture_playbook_help_container_retries_delay }}" + until: result is not failed + + # We store the password in a file and make the `htpasswd` tool read it from there, + # as opposed to passing it directly on stdin (which will expose it to other processes on the server). + - name: Store metrics password in a temporary file + ansible.builtin.copy: + content: "{{ matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_password }}" + dest: "/tmp/matrix-nginx-proxy-metrics-password" + mode: 0400 + owner: "{{ matrix_user_uid }}" + group: "{{ matrix_user_gid }}" + + - name: Generate matrix-metrics-htpasswd from username/password (protecting /metrics/* URIs) + ansible.builtin.command: + cmd: >- + {{ devture_systemd_docker_base_host_command_docker }} run + --rm + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} + --cap-drop=ALL + --network=none + --mount type=bind,src={{ matrix_nginx_proxy_data_path }},dst=/data + --mount type=bind,src=/tmp/matrix-nginx-proxy-metrics-password,dst=/password,ro + --entrypoint=/bin/sh + {{ matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_apache_container_image }} + -c + 'cat /password | htpasswd -i -c /data/matrix-metrics-htpasswd {{ matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_username }} && chmod 600 /data/matrix-metrics-htpasswd' + changed_when: true + + - name: Delete temporary metrics password file + ansible.builtin.file: + path: /tmp/matrix-nginx-proxy-metrics-password + state: absent diff --git a/roles/nginx-proxy/tasks/self_check_well_known.yml b/roles/nginx-proxy/tasks/self_check_well_known.yml new file mode 100644 index 0000000..e7ed549 --- /dev/null +++ b/roles/nginx-proxy/tasks/self_check_well_known.yml @@ -0,0 +1,30 @@ +--- + +- name: Determine well-known files to check (Matrix) + ansible.builtin.set_fact: + well_known_file_checks: + - path: /.well-known/matrix/client + purpose: Client Discovery + cors: true + follow_redirects: "{{ matrix_nginx_proxy_self_check_well_known_matrix_client_follow_redirects }}" + validate_certs: "{{ matrix_nginx_proxy_self_check_validate_certificates }}" + +- when: matrix_well_known_matrix_server_enabled | bool + block: + - ansible.builtin.set_fact: + well_known_file_check_matrix_server: + path: /.well-known/matrix/server + purpose: Server Discovery + cors: false + follow_redirects: safe + validate_certs: "{{ matrix_nginx_proxy_self_check_validate_certificates }}" + + - name: Determine domains that we require certificates for (ma1sd) + ansible.builtin.set_fact: + well_known_file_checks: "{{ well_known_file_checks + [well_known_file_check_matrix_server] }}" + +- name: Perform well-known checks + ansible.builtin.include_tasks: "{{ role_path }}/tasks/self_check_well_known_file.yml" + with_items: "{{ well_known_file_checks }}" + loop_control: + loop_var: well_known_file_check diff --git a/roles/nginx-proxy/tasks/self_check_well_known_file.yml b/roles/nginx-proxy/tasks/self_check_well_known_file.yml new file mode 100644 index 0000000..95a43de --- /dev/null +++ b/roles/nginx-proxy/tasks/self_check_well_known_file.yml @@ -0,0 +1,73 @@ +--- + +- ansible.builtin.set_fact: + well_known_url_matrix: "https://{{ matrix_server_fqn_matrix }}{{ well_known_file_check.path }}" + well_known_url_identity: "https://{{ matrix_domain }}{{ well_known_file_check.path }}" + +# These well-known files may be served without a `Content-Type: application/json` header, +# so we can't rely on the uri module's automatic parsing of JSON. +- name: Check .well-known on the matrix hostname + ansible.builtin.uri: + url: "{{ well_known_url_matrix }}" + follow_redirects: none + return_content: true + validate_certs: "{{ well_known_file_check.validate_certs }}" + headers: + Origin: example.com + check_mode: false + register: result_well_known_matrix + ignore_errors: true + +- name: Fail if .well-known not working on the matrix hostname + ansible.builtin.fail: + msg: "Failed checking that the well-known file for {{ well_known_file_check.purpose }} is configured at `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ well_known_url_matrix }}`). Is port 443 open in your firewall? Full error: {{ result_well_known_matrix }}" + when: "result_well_known_matrix.failed" + +- name: Parse JSON for well-known payload at the matrix hostname + ansible.builtin.set_fact: + well_known_matrix_payload: "{{ result_well_known_matrix.content | from_json }}" + +- name: Fail if .well-known not CORS-aware on the matrix hostname + ansible.builtin.fail: + msg: "The well-known file for {{ well_known_file_check.purpose }} on `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ well_known_url_matrix }}`) is not CORS-aware. The file needs to be served with an Access-Control-Allow-Origin header set." + when: "well_known_file_check.cors and 'access_control_allow_origin' not in result_well_known_matrix" + +- name: Report working .well-known on the matrix hostname + ansible.builtin.debug: + msg: "well-known for {{ well_known_file_check.purpose }} is configured correctly for `{{ matrix_server_fqn_matrix }}` (checked endpoint: `{{ well_known_url_matrix }}`)" + +- name: Check .well-known on the identity hostname + ansible.builtin.uri: + url: "{{ well_known_url_identity }}" + follow_redirects: "{{ well_known_file_check.follow_redirects }}" + return_content: true + validate_certs: "{{ well_known_file_check.validate_certs }}" + headers: + Origin: example.com + check_mode: false + register: result_well_known_identity + ignore_errors: true + +- name: Fail if .well-known not working on the identity hostname + ansible.builtin.fail: + msg: "Failed checking that the well-known file for {{ well_known_file_check.purpose }} is configured at `{{ matrix_domain }}` (checked endpoint: `{{ well_known_url_identity }}`). Is port 443 open in your firewall? Full error: {{ result_well_known_identity }}" + when: "result_well_known_identity.failed" + +- name: Parse JSON for well-known payload at the identity hostname + ansible.builtin.set_fact: + well_known_identity_payload: "{{ result_well_known_identity.content | from_json }}" + +- name: Fail if .well-known not CORS-aware on the identity hostname + ansible.builtin.fail: + msg: "The well-known file for {{ well_known_file_check.purpose }} on `{{ matrix_domain }}` (checked endpoint: `{{ well_known_url_identity }}`) is not CORS-aware. The file needs to be served with an Access-Control-Allow-Origin header set. See docs/configuring-well-known.md" + when: "well_known_file_check.cors and 'access_control_allow_origin' not in result_well_known_identity" + +# For people who manually copy the well-known file, try to detect if it's outdated +- name: Fail if well-known is different on matrix hostname and identity hostname + ansible.builtin.fail: + msg: "The well-known files for {{ well_known_file_check.purpose }} at `{{ matrix_server_fqn_matrix }}` and `{{ matrix_domain }}` are different. Perhaps you copied the file ({{ well_known_file_check.path }}) manually before and now it's outdated?" + when: "well_known_matrix_payload != well_known_identity_payload" + +- name: Report working .well-known on the identity hostname + ansible.builtin.debug: + msg: "well-known for {{ well_known_file_check.purpose }} ({{ well_known_file_check.path }}) is configured correctly for `{{ matrix_domain }}` (checked endpoint: `{{ well_known_url_identity }}`)" diff --git a/roles/nginx-proxy/tasks/setup_nginx_proxy.yml b/roles/nginx-proxy/tasks/setup_nginx_proxy.yml new file mode 100644 index 0000000..3115042 --- /dev/null +++ b/roles/nginx-proxy/tasks/setup_nginx_proxy.yml @@ -0,0 +1,372 @@ +--- + +# +# Generic tasks that we always want to happen, regardless +# if the user wants matrix-nginx-proxy or not. +# +# If the user would set up their own nginx proxy server, +# the config files from matrix-nginx-proxy can be reused. +# +# It doesn't hurt to put them in place, even if they turn out +# to be unnecessary. +# +- name: Ensure Matrix nginx-proxy paths exist + ansible.builtin.file: + path: "{{ item }}" + state: directory + mode: 0750 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + with_items: + - "{{ matrix_nginx_proxy_base_path }}" + - "{{ matrix_nginx_proxy_data_path }}" + - "{{ matrix_nginx_proxy_confd_path }}" + +- name: Ensure Matrix nginx-proxy configured (main config override) + ansible.builtin.template: + src: "{{ role_path }}/templates/nginx/nginx.conf.j2" + dest: "{{ matrix_nginx_proxy_base_path }}/nginx.conf" + mode: 0644 + when: matrix_nginx_proxy_enabled | bool + +- name: Setup metrics + ansible.builtin.include_tasks: "{{ role_path }}/tasks/nginx-proxy/setup_metrics_auth.yml" + when: matrix_nginx_proxy_proxy_matrix_metrics_enabled | bool and matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_enabled | bool + +- name: Ensure Matrix nginx-proxy configured (generic) + ansible.builtin.template: + src: "{{ role_path }}/templates/nginx/conf.d/nginx-http.conf.j2" + dest: "{{ matrix_nginx_proxy_confd_path }}/nginx-http.conf" + mode: 0644 + when: matrix_nginx_proxy_enabled | bool + +- name: Ensure Matrix nginx-proxy configuration for wildcard certifiate exists + ansible.builtin.template: + src: "{{ role_path }}/templates/nginx/conf.d/a-nginx-https-wildcard.conf.j2" + dest: "{{ matrix_nginx_proxy_confd_path }}/a-nginx-https-wildcard.conf" + mode: 0644 + when: matrix_wildcard_cerifiate_enabled | bool + +- name: Ensure Matrix nginx-proxy configuration for matrix-synapse exists + ansible.builtin.template: + src: "{{ role_path }}/templates/nginx/conf.d/matrix-synapse.conf.j2" + dest: "{{ matrix_nginx_proxy_confd_path }}/matrix-synapse.conf" + mode: 0644 + when: matrix_nginx_proxy_proxy_synapse_enabled | bool + +- name: Ensure Matrix nginx-proxy configuration for matrix-synapse deleted + ansible.builtin.file: + path: "{{ matrix_nginx_proxy_confd_path }}/matrix-synapse.conf" + state: absent + when: "not matrix_nginx_proxy_proxy_synapse_enabled | bool" + +- name: Ensure Matrix nginx-proxy configuration for matrix-dendrite exists + ansible.builtin.template: + src: "{{ role_path }}/templates/nginx/conf.d/matrix-dendrite.conf.j2" + dest: "{{ matrix_nginx_proxy_confd_path }}/matrix-dendrite.conf" + mode: 0644 + when: matrix_nginx_proxy_proxy_dendrite_enabled | bool + +- name: Ensure Matrix nginx-proxy configuration for matrix-dendrite deleted + ansible.builtin.file: + path: "{{ matrix_nginx_proxy_confd_path }}/matrix-dendrite.conf" + state: absent + when: "not matrix_nginx_proxy_proxy_dendrite_enabled | bool" + +- name: Ensure Matrix nginx-proxy configuration for matrix-conduit exists + ansible.builtin.template: + src: "{{ role_path }}/templates/nginx/conf.d/matrix-conduit.conf.j2" + dest: "{{ matrix_nginx_proxy_confd_path }}/matrix-conduit.conf" + mode: 0644 + when: matrix_nginx_proxy_proxy_conduit_enabled | bool + +- name: Ensure Matrix nginx-proxy configuration for matrix-conduit deleted + ansible.builtin.file: + path: "{{ matrix_nginx_proxy_confd_path }}/matrix-conduit.conf" + state: absent + when: "not matrix_nginx_proxy_proxy_conduit_enabled | bool" + +- name: Ensure Matrix nginx-proxy configuration for Element domain exists + ansible.builtin.template: + src: "{{ role_path }}/templates/nginx/conf.d/matrix-client-element.conf.j2" + dest: "{{ matrix_nginx_proxy_confd_path }}/matrix-client-element.conf" + mode: 0644 + when: matrix_nginx_proxy_proxy_element_enabled | bool + +- name: Ensure Matrix nginx-proxy configuration for riot domain exists + ansible.builtin.template: + src: "{{ role_path }}/templates/nginx/conf.d/matrix-riot-web.conf.j2" + dest: "{{ matrix_nginx_proxy_confd_path }}/matrix-riot-web.conf" + mode: 0644 + when: matrix_nginx_proxy_proxy_riot_compat_redirect_enabled | bool + +- name: Ensure Matrix nginx-proxy configuration for Hydrogen domain exists + ansible.builtin.template: + src: "{{ role_path }}/templates/nginx/conf.d/matrix-client-hydrogen.conf.j2" + dest: "{{ matrix_nginx_proxy_confd_path }}/matrix-client-hydrogen.conf" + mode: 0644 + when: matrix_nginx_proxy_proxy_hydrogen_enabled | bool + +- name: Ensure Matrix nginx-proxy configuration for Cinny domain exists + ansible.builtin.template: + src: "{{ role_path }}/templates/nginx/conf.d/matrix-client-cinny.conf.j2" + dest: "{{ matrix_nginx_proxy_confd_path }}/matrix-client-cinny.conf" + mode: 0644 + when: matrix_nginx_proxy_proxy_cinny_enabled | bool + +- name: Ensure Matrix nginx-proxy configuration for buscarron domain exists + ansible.builtin.template: + src: "{{ role_path }}/templates/nginx/conf.d/matrix-bot-buscarron.conf.j2" + dest: "{{ matrix_nginx_proxy_confd_path }}/matrix-bot-buscarron.conf" + mode: 0644 + when: matrix_nginx_proxy_proxy_buscarron_enabled | bool + +- name: Ensure Matrix nginx-proxy configuration for dimension domain exists + ansible.builtin.template: + src: "{{ role_path }}/templates/nginx/conf.d/matrix-dimension.conf.j2" + dest: "{{ matrix_nginx_proxy_confd_path }}/matrix-dimension.conf" + mode: 0644 + when: matrix_nginx_proxy_proxy_dimension_enabled | bool + +- name: Ensure Matrix nginx-proxy configuration for etherpad domain exists + ansible.builtin.template: + src: "{{ role_path }}/templates/nginx/conf.d/matrix-etherpad.conf.j2" + dest: "{{ matrix_nginx_proxy_confd_path }}/matrix-etherpad.conf" + mode: 0644 + when: matrix_nginx_proxy_proxy_etherpad_enabled | bool + +- name: Ensure Matrix nginx-proxy configuration for goneb domain exists + ansible.builtin.template: + src: "{{ role_path }}/templates/nginx/conf.d/matrix-bot-go-neb.conf.j2" + dest: "{{ matrix_nginx_proxy_confd_path }}/matrix-bot-go-neb.conf" + mode: 0644 + when: matrix_nginx_proxy_proxy_bot_go_neb_enabled | bool + +- name: Ensure Matrix nginx-proxy configuration for jitsi domain exists + ansible.builtin.template: + src: "{{ role_path }}/templates/nginx/conf.d/matrix-jitsi.conf.j2" + dest: "{{ matrix_nginx_proxy_confd_path }}/matrix-jitsi.conf" + mode: 0644 + when: matrix_nginx_proxy_proxy_jitsi_enabled | bool + +- name: Ensure Matrix nginx-proxy configuration for grafana domain exists + ansible.builtin.template: + src: "{{ role_path }}/templates/nginx/conf.d/matrix-grafana.conf.j2" + dest: "{{ matrix_nginx_proxy_confd_path }}/matrix-grafana.conf" + mode: 0644 + when: matrix_nginx_proxy_proxy_grafana_enabled | bool + +- name: Ensure Matrix nginx-proxy configuration for sygnal domain exists + ansible.builtin.template: + src: "{{ role_path }}/templates/nginx/conf.d/matrix-sygnal.conf.j2" + dest: "{{ matrix_nginx_proxy_confd_path }}/matrix-sygnal.conf" + mode: 0644 + when: matrix_nginx_proxy_proxy_sygnal_enabled | bool + +- name: Ensure Matrix nginx-proxy configuration for ntfy domain exists + ansible.builtin.template: + src: "{{ role_path }}/templates/nginx/conf.d/matrix-ntfy.conf.j2" + dest: "{{ matrix_nginx_proxy_confd_path }}/matrix-ntfy.conf" + mode: 0644 + when: matrix_nginx_proxy_proxy_ntfy_enabled | bool + +- name: Ensure Matrix nginx-proxy configuration for Matrix domain exists + ansible.builtin.template: + src: "{{ role_path }}/templates/nginx/conf.d/matrix-domain.conf.j2" + dest: "{{ matrix_nginx_proxy_confd_path }}/matrix-domain.conf" + mode: 0644 + +- name: Ensure Matrix nginx-proxy configuration for Keycloak domain exists + ansible.builtin.template: + src: "{{ role_path }}/templates/nginx/conf.d/keycloak-http.conf.j2" + dest: "{{ matrix_nginx_proxy_confd_path }}/keycloak-http.conf" + mode: 0644 + when: matrix_nginx_proxy_proxy_keycloak_enabled | bool + +- name: Ensure Matrix nginx-proxy configuration for Gitlab domain exists + ansible.builtin.template: + src: "{{ role_path }}/templates/nginx/conf.d/gitlab-http.conf.j2" + dest: "{{ matrix_nginx_proxy_confd_path }}/gitlab-http.conf" + mode: 0644 + when: matrix_nginx_proxy_proxy_gitlab_enabled | bool + + + +- name: Ensure Matrix nginx-proxy data directory for base domain exists + ansible.builtin.file: + path: "{{ matrix_nginx_proxy_data_path }}/matrix-domain" + state: directory + mode: 0750 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + when: matrix_nginx_proxy_base_domain_serving_enabled | bool and matrix_nginx_proxy_base_domain_create_directory | bool + +- name: Ensure Matrix nginx-proxy homepage for base domain exists + ansible.builtin.copy: + content: "{{ matrix_nginx_proxy_base_domain_homepage_template }}" + dest: "{{ matrix_nginx_proxy_data_path }}/matrix-domain/index.html" + mode: 0644 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + when: matrix_nginx_proxy_base_domain_serving_enabled | bool and matrix_nginx_proxy_base_domain_homepage_enabled | bool and matrix_nginx_proxy_base_domain_create_directory | bool + +- name: Ensure Matrix nginx-proxy configuration for base domain exists + ansible.builtin.template: + src: "{{ role_path }}/templates/nginx/conf.d/matrix-base-domain.conf.j2" + dest: "{{ matrix_nginx_proxy_confd_path }}/matrix-base-domain.conf" + mode: 0644 + when: matrix_nginx_proxy_base_domain_serving_enabled | bool + +# +# Tasks related to setting up matrix-nginx-proxy +# +- name: Ensure nginx Docker image is pulled + community.docker.docker_image: + name: "{{ matrix_nginx_proxy_docker_image }}" + source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" + force_source: "{{ matrix_nginx_proxy_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_nginx_proxy_docker_image_force_pull }}" + when: matrix_nginx_proxy_enabled | bool + register: result + retries: "{{ devture_playbook_help_container_retries_count }}" + delay: "{{ devture_playbook_help_container_retries_delay }}" + until: result is not failed + +- name: Ensure matrix-nginx-proxy.service installed + ansible.builtin.template: + src: "{{ role_path }}/templates/systemd/matrix-nginx-proxy.service.j2" + dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-nginx-proxy.service" + mode: 0644 + when: matrix_nginx_proxy_enabled | bool + + +# +# Tasks related to getting rid of matrix-nginx-proxy (if it was previously enabled) +# + +- name: Check existence of matrix-nginx-proxy service + ansible.builtin.stat: + path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-nginx-proxy.service" + register: matrix_nginx_proxy_service_stat + when: "not matrix_nginx_proxy_enabled | bool" + +- name: Ensure matrix-nginx-proxy is stopped + ansible.builtin.service: + name: matrix-nginx-proxy + state: stopped + enabled: false + daemon_reload: true + when: "not matrix_nginx_proxy_enabled | bool and matrix_nginx_proxy_service_stat.stat.exists" + +- name: Ensure matrix-nginx-proxy.service doesn't exist + ansible.builtin.file: + path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-nginx-proxy.service" + state: absent + when: "not matrix_nginx_proxy_enabled | bool and matrix_nginx_proxy_service_stat.stat.exists" + +- name: Ensure Matrix nginx-proxy configuration for matrix domain deleted + ansible.builtin.file: + path: "{{ matrix_nginx_proxy_confd_path }}/matrix-domain.conf" + state: absent + when: "not matrix_nginx_proxy_proxy_matrix_enabled | bool" + +- name: Ensure Matrix nginx-proxy configuration for riot domain deleted + ansible.builtin.file: + path: "{{ matrix_nginx_proxy_confd_path }}/matrix-riot-web.conf" + state: absent + when: "not matrix_nginx_proxy_proxy_riot_compat_redirect_enabled | bool" + +- name: Ensure Matrix nginx-proxy configuration for Hydrogen domain deleted + ansible.builtin.file: + path: "{{ matrix_nginx_proxy_confd_path }}/matrix-client-hydrogen.conf" + state: absent + when: "not matrix_nginx_proxy_proxy_hydrogen_enabled | bool" + +- name: Ensure Matrix nginx-proxy configuration for Cinny domain deleted + ansible.builtin.file: + path: "{{ matrix_nginx_proxy_confd_path }}/matrix-client-cinny.conf" + state: absent + when: "not matrix_nginx_proxy_proxy_cinny_enabled | bool" + +- name: Ensure Matrix nginx-proxy configuration for buscarron domain deleted + ansible.builtin.file: + path: "{{ matrix_nginx_proxy_confd_path }}/matrix-bot-buscarron.conf" + state: absent + when: "not matrix_nginx_proxy_proxy_buscarron_enabled | bool" + +- name: Ensure Matrix nginx-proxy configuration for dimension domain deleted + ansible.builtin.file: + path: "{{ matrix_nginx_proxy_confd_path }}/matrix-dimension.conf" + state: absent + when: "not matrix_nginx_proxy_proxy_dimension_enabled | bool" + +- name: Ensure Matrix nginx-proxy configuration for goneb domain deleted + ansible.builtin.file: + path: "{{ matrix_nginx_proxy_confd_path }}/matrix-bot-go-neb.conf" + state: absent + when: "not matrix_nginx_proxy_proxy_bot_go_neb_enabled | bool" + +- name: Ensure Matrix nginx-proxy configuration for jitsi domain deleted + ansible.builtin.file: + path: "{{ matrix_nginx_proxy_confd_path }}/matrix-jitsi.conf" + state: absent + when: "not matrix_nginx_proxy_proxy_jitsi_enabled | bool" + +- name: Ensure Matrix nginx-proxy configuration for grafana domain deleted + ansible.builtin.file: + path: "{{ matrix_nginx_proxy_confd_path }}/matrix-grafana.conf" + state: absent + when: "not matrix_nginx_proxy_proxy_grafana_enabled | bool" + +- name: Ensure Matrix nginx-proxy configuration for sygnal domain deleted + ansible.builtin.file: + path: "{{ matrix_nginx_proxy_confd_path }}/matrix-sygnal.conf" + state: absent + when: "not matrix_nginx_proxy_proxy_sygnal_enabled | bool" + +- name: Ensure Matrix nginx-proxy configuration for ntfy domain deleted + ansible.builtin.file: + path: "{{ matrix_nginx_proxy_confd_path }}/matrix-ntfy.conf" + state: absent + when: "not matrix_nginx_proxy_proxy_ntfy_enabled | bool" + +- name: Ensure Matrix nginx-proxy configuration for etherpad domain deleted + ansible.builtin.file: + path: "{{ matrix_nginx_proxy_confd_path }}/matrix-etherpad.conf" + state: absent + when: "not matrix_nginx_proxy_proxy_etherpad_enabled | bool" + +- name: Ensure Matrix nginx-proxy homepage for base domain deleted + ansible.builtin.file: + path: "{{ matrix_nginx_proxy_data_path }}/matrix-domain/index.html" + state: absent + when: "not matrix_nginx_proxy_base_domain_serving_enabled | bool" + +- name: Ensure Matrix nginx-proxy configuration for base domain deleted + ansible.builtin.file: + path: "{{ matrix_nginx_proxy_confd_path }}/matrix-base-domain.conf" + state: absent + when: "not matrix_nginx_proxy_base_domain_serving_enabled | bool" + +- name: Ensure Matrix nginx-proxy configuration for main config override deleted + ansible.builtin.file: + path: "{{ matrix_nginx_proxy_base_path }}/nginx.conf" + state: absent + when: "not matrix_nginx_proxy_enabled | bool" + +- name: Ensure Matrix nginx-proxy htpasswd is deleted (protecting /_synapse/metrics URI) + ansible.builtin.file: + path: "{{ matrix_nginx_proxy_data_path }}/matrix-synapse-metrics-htpasswd" + state: absent + +# This file is now generated by the matrix-synapse role and saved in the Synapse directory +- name: (Cleanup) Ensure old sample prometheus.yml for external scraping is deleted + ansible.builtin.file: + path: "{{ matrix_base_data_path }}/external_prometheus.yml.example" + state: absent + +- name: Ensure Matrix nginx-proxy htpasswd is deleted (protecting /metrics/* URIs) + ansible.builtin.file: + path: "{{ matrix_nginx_proxy_data_path }}/matrix-metrics-htpasswd" + state: absent + when: "not matrix_nginx_proxy_proxy_matrix_metrics_enabled | bool or not matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_enabled | bool" diff --git a/roles/nginx-proxy/tasks/setup_well_known.yml b/roles/nginx-proxy/tasks/setup_well_known.yml new file mode 100644 index 0000000..11e941b --- /dev/null +++ b/roles/nginx-proxy/tasks/setup_well_known.yml @@ -0,0 +1,25 @@ +--- +- ansible.builtin.set_fact: + matrix_well_known_file_path: "{{ matrix_static_files_base_path }}/.well-known/matrix/client" + +# We need others to be able to read these directories too, +# so that matrix-nginx-proxy's nginx user can access the files. +# +# For running with another webserver, we recommend being part of the `matrix` group. +- name: Ensure Matrix static-files path exists + ansible.builtin.file: + path: "{{ item }}" + state: directory + mode: 0755 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + with_items: + - "{{ matrix_static_files_base_path }}/.well-known/matrix" + +- name: Ensure Matrix /.well-known/matrix/client configured + ansible.builtin.template: + src: "{{ role_path }}/templates/well-known/matrix-client.j2" + dest: "{{ matrix_static_files_base_path }}/.well-known/matrix" + mode: 0644 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" diff --git a/roles/nginx-proxy/tasks/ssl/main.yml b/roles/nginx-proxy/tasks/ssl/main.yml new file mode 100644 index 0000000..6eff8cb --- /dev/null +++ b/roles/nginx-proxy/tasks/ssl/main.yml @@ -0,0 +1,37 @@ +--- + +- name: Fail if using unsupported SSL certificate retrieval method + ansible.builtin.fail: + msg: "The `matrix_ssl_retrieval_method` variable contains an unsupported value" + when: "matrix_ssl_retrieval_method not in ['lets-encrypt', 'self-signed', 'manually-managed', 'none']" + +- name: Fail if using unsupported private key type + ansible.builtin.fail: + msg: "The `matrix_ssl_lets_encrypt_key_type` variable contains an unsupported value" + when: "matrix_ssl_lets_encrypt_key_type not in ['rsa', 'ecdsa']" + + +# Common tasks, required by almost any method below. + +- name: Ensure SSL certificate paths exists + ansible.builtin.file: + path: "{{ item }}" + state: directory + mode: 0770 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + recurse: true + with_items: + - "{{ matrix_ssl_log_dir_path }}" + - "{{ matrix_ssl_config_dir_path }}" + - "{{ matrix_ssl_bin_dir_path }}" + when: "matrix_ssl_retrieval_method != 'none'" + + +# Method specific tasks follow + +- ansible.builtin.import_tasks: "{{ role_path }}/tasks/ssl/setup_ssl_lets_encrypt.yml" + +- ansible.builtin.import_tasks: "{{ role_path }}/tasks/ssl/setup_ssl_self_signed.yml" + +- ansible.builtin.import_tasks: "{{ role_path }}/tasks/ssl/setup_ssl_manually_managed.yml" diff --git a/roles/nginx-proxy/tasks/ssl/purge_ssl_lets_encrypt_orphaned_configs.yml b/roles/nginx-proxy/tasks/ssl/purge_ssl_lets_encrypt_orphaned_configs.yml new file mode 100644 index 0000000..51fd1f3 --- /dev/null +++ b/roles/nginx-proxy/tasks/ssl/purge_ssl_lets_encrypt_orphaned_configs.yml @@ -0,0 +1,27 @@ +--- + +- name: Check if a Let's Encrypt renewal configuration directory exists + ansible.builtin.stat: + path: "{{ matrix_ssl_config_dir_path }}/renewal" + register: matrix_ssl_config_renewal_directory_stat_result + +- when: matrix_ssl_config_renewal_directory_stat_result.stat.exists | bool + block: + - name: Determine current Let's Encrypt renewal configs + ansible.builtin.find: + path: "{{ matrix_ssl_config_dir_path }}/renewal" + patterns: ".*.conf$" + use_regex: true + register: matrix_ssl_current_renewal_config_files + + - name: Determine unnecessary Let's Encrypt renewal configs + ansible.builtin.set_fact: + matrix_ssl_current_renewal_config_files_to_purge: "{{ matrix_ssl_current_renewal_config_files_to_purge | default([]) + [item.path] }}" + with_items: "{{ matrix_ssl_current_renewal_config_files.files }}" + when: "item.path | basename | replace('.conf', '') not in matrix_ssl_domains_to_obtain_certificates_for" + + - name: Purge unneceessary Let's Encrypt renewal config files + ansible.builtin.file: + path: "{{ item }}" + state: absent + with_items: "{{ matrix_ssl_current_renewal_config_files_to_purge | default([]) }}" diff --git a/roles/nginx-proxy/tasks/ssl/setup_ssl_lets_encrypt.yml b/roles/nginx-proxy/tasks/ssl/setup_ssl_lets_encrypt.yml new file mode 100644 index 0000000..a1b14e3 --- /dev/null +++ b/roles/nginx-proxy/tasks/ssl/setup_ssl_lets_encrypt.yml @@ -0,0 +1,54 @@ +--- +# +# Tasks related to setting up Let's Encrypt's management of certificates +# + +- when: "matrix_ssl_retrieval_method == 'lets-encrypt'" + block: + - when: matrix_ssl_orphaned_renewal_configs_purging_enabled | bool + ansible.builtin.import_tasks: "{{ role_path }}/tasks/ssl/purge_ssl_lets_encrypt_orphaned_configs.yml" + + - name: Ensure certbot Docker image is pulled + community.docker.docker_image: + name: "{{ matrix_ssl_lets_encrypt_certbot_docker_image }}" + source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}" + force_source: "{{ matrix_ssl_lets_encrypt_certbot_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_ssl_lets_encrypt_certbot_docker_image_force_pull }}" + + - name: Obtain Let's Encrypt certificates + ansible.builtin.include_tasks: "{{ role_path }}/tasks/ssl/setup_ssl_lets_encrypt_obtain_for_domain.yml" + with_items: "{{ matrix_ssl_domains_to_obtain_certificates_for | unique }}" + loop_control: + loop_var: domain_name + + - name: Ensure Let's Encrypt SSL renewal script installed + ansible.builtin.template: + src: "{{ role_path }}/templates/bin/lets-encrypt-certificates-renew.j2" + dest: "{{ matrix_ssl_bin_dir_path }}/lets-encrypt-certificates-renew" + mode: 0755 + + - name: Ensure SSL renewal systemd units installed + ansible.builtin.template: + src: "{{ role_path }}/templates/systemd/{{ item.name }}.j2" + dest: "{{ devture_systemd_docker_base_systemd_path }}/{{ item.name }}" + mode: 0644 + when: "item.applicable | bool" + with_items: "{{ matrix_ssl_renewal_systemd_units_list }}" + +# +# Tasks related to getting rid of Let's Encrypt's management of certificates +# + +- when: "matrix_ssl_retrieval_method != 'lets-encrypt'" + block: + - name: Ensure matrix-ssl-lets-encrypt-renew cronjob removed + ansible.builtin.file: + path: "{{ devture_systemd_docker_base_systemd_path }}/{{ item.name }}" + state: absent + when: "not item.applicable | bool" + with_items: "{{ matrix_ssl_renewal_systemd_units_list }}" + + - name: Ensure Let's Encrypt SSL renewal script removed + ansible.builtin.file: + path: "{{ matrix_ssl_bin_dir_path }}/lets-encrypt-certificates-renew" + state: absent diff --git a/roles/nginx-proxy/tasks/ssl/setup_ssl_lets_encrypt_obtain_for_domain.yml b/roles/nginx-proxy/tasks/ssl/setup_ssl_lets_encrypt_obtain_for_domain.yml new file mode 100644 index 0000000..b10791a --- /dev/null +++ b/roles/nginx-proxy/tasks/ssl/setup_ssl_lets_encrypt_obtain_for_domain.yml @@ -0,0 +1,96 @@ +--- +- ansible.builtin.debug: + msg: "Dealing with SSL certificate retrieval for domain: {{ domain_name }}" + +- ansible.builtin.set_fact: + domain_name_certificate_path: "{{ matrix_ssl_config_dir_path }}/live/{{ domain_name }}/fullchain.pem" + +- name: Check if a certificate for the domain already exists + ansible.builtin.stat: + path: "{{ domain_name_certificate_path }}" + register: domain_name_certificate_path_stat + +- ansible.builtin.set_fact: + domain_name_needs_cert: "{{ not domain_name_certificate_path_stat.stat.exists }}" + +- when: "domain_name_needs_cert | bool and matrix_ssl_pre_obtaining_required_service_name != ''" + block: + - name: Ensure required service for obtaining is started + ansible.builtin.service: + name: "{{ matrix_ssl_pre_obtaining_required_service_name }}" + state: started + register: matrix_ssl_pre_obtaining_required_service_start_result + + - name: Wait some time, so that the required service for obtaining can start + ansible.builtin.wait_for: + timeout: "{{ matrix_ssl_pre_obtaining_required_service_start_wait_time_seconds }}" + when: "matrix_ssl_pre_obtaining_required_service_start_result.changed | bool" + +# This will fail if there is something running on port 80 (like matrix-nginx-proxy). +# We suppress the error, as we'll try another method below. +- name: Attempt initial SSL certificate retrieval with standalone authenticator (directly) + ansible.builtin.shell: >- + {{ devture_systemd_docker_base_host_command_docker }} run + --rm + --name=matrix-certbot + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} + --cap-drop=ALL + -p {{ matrix_ssl_lets_encrypt_container_standalone_http_host_bind_port }}:8080 + --mount type=bind,src={{ matrix_ssl_config_dir_path }},dst=/etc/letsencrypt + --mount type=bind,src={{ matrix_ssl_log_dir_path }},dst=/var/log/letsencrypt + {{ matrix_ssl_lets_encrypt_certbot_docker_image }} + certonly + --non-interactive + --work-dir=/tmp + --http-01-port 8080 + {% if matrix_ssl_lets_encrypt_server %}--server={{ matrix_ssl_lets_encrypt_server|quote }}{% endif %} + {% if matrix_ssl_lets_encrypt_staging %}--staging{% endif %} + --key-type {{ matrix_ssl_lets_encrypt_key_type }} + --standalone + --preferred-challenges http + --agree-tos + --email={{ matrix_ssl_lets_encrypt_support_email }} + -d {{ domain_name }} + when: domain_name_needs_cert | bool + register: result_certbot_direct + ignore_errors: true + +# If matrix-nginx-proxy is configured from a previous run of this playbook, +# and it's running now, it may be able to proxy requests to `matrix_ssl_lets_encrypt_certbot_standalone_http_port`. +- name: Attempt initial SSL certificate retrieval with standalone authenticator (via proxy) + ansible.builtin.shell: >- + {{ devture_systemd_docker_base_host_command_docker }} run + --rm + --name=matrix-certbot + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} + --cap-drop=ALL + -p 127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}:8080 + --network={{ matrix_docker_network }} + --mount type=bind,src={{ matrix_ssl_config_dir_path }},dst=/etc/letsencrypt + --mount type=bind,src={{ matrix_ssl_log_dir_path }},dst=/var/log/letsencrypt + {{ matrix_ssl_lets_encrypt_certbot_docker_image }} + certonly + --non-interactive + --work-dir=/tmp + --http-01-port 8080 + {% if matrix_ssl_lets_encrypt_server %}--server={{ matrix_ssl_lets_encrypt_server|quote }}{% endif %} + {% if matrix_ssl_lets_encrypt_staging %}--staging{% endif %} + --key-type {{ matrix_ssl_lets_encrypt_key_type }} + --standalone + --preferred-challenges http + --agree-tos + --email={{ matrix_ssl_lets_encrypt_support_email }} + -d {{ domain_name }} + when: "domain_name_needs_cert and result_certbot_direct.failed" + register: result_certbot_proxy + ignore_errors: true + +- name: Fail if all SSL certificate retrieval attempts failed + ansible.builtin.fail: + msg: | + Failed to obtain a certificate directly (by listening on port 80) + and also failed to obtain by relying on the server at port 80 to proxy the request. + See above for details. + You may wish to set up proxying of /.well-known/acme-challenge to {{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }} or, + more easily, stop the server on port 80 while this playbook runs. + when: "domain_name_needs_cert and result_certbot_direct.failed and result_certbot_proxy.failed" diff --git a/roles/nginx-proxy/tasks/ssl/setup_ssl_manually_managed.yml b/roles/nginx-proxy/tasks/ssl/setup_ssl_manually_managed.yml new file mode 100644 index 0000000..fe0a3ff --- /dev/null +++ b/roles/nginx-proxy/tasks/ssl/setup_ssl_manually_managed.yml @@ -0,0 +1,11 @@ +--- + +#- name: Ensure certificates is sended to ngnix proxy configuration files. + + +- name: Verify certificates + ansible.builtin.include_tasks: "{{ role_path }}/tasks/ssl/setup_ssl_manually_managed_verify_for_domain.yml" + with_items: "{{ matrix_ssl_domains_to_obtain_certificates_for | unique }}" + loop_control: + loop_var: domain_name + when: "matrix_ssl_retrieval_method == 'manually-managed' and matrix_wildcard_cerifiate_enabled is not true" diff --git a/roles/nginx-proxy/tasks/ssl/setup_ssl_manually_managed_verify_for_domain.yml b/roles/nginx-proxy/tasks/ssl/setup_ssl_manually_managed_verify_for_domain.yml new file mode 100644 index 0000000..ab0ffa2 --- /dev/null +++ b/roles/nginx-proxy/tasks/ssl/setup_ssl_manually_managed_verify_for_domain.yml @@ -0,0 +1,23 @@ +--- + +- ansible.builtin.set_fact: + matrix_ssl_certificate_verification_cert_path: "{{ matrix_ssl_config_dir_path }}/live/{{ domain_name }}/fullchain.pem" + matrix_ssl_certificate_verification_cert_key_path: "{{ matrix_ssl_config_dir_path }}/live/{{ domain_name }}/privkey.pem" + +- name: Check if SSL certificate file exists + ansible.builtin.stat: + path: "{{ matrix_ssl_certificate_verification_cert_path }}" + register: matrix_ssl_certificate_verification_cert_path_stat_result + +- ansible.builtin.fail: + msg: "Failed finding a certificate file (for domain `{{ domain_name }}`) at `{{ matrix_ssl_certificate_verification_cert_path }}`" + when: "not matrix_ssl_certificate_verification_cert_path_stat_result.stat.exists" + +- name: Check if SSL certificate key file exists + ansible.builtin.stat: + path: "{{ matrix_ssl_certificate_verification_cert_key_path }}" + register: matrix_ssl_certificate_verification_cert_key_path_stat_result + +- ansible.builtin.fail: + msg: "Failed finding a certificate key file (for domain `{{ domain_name }}`) at `{{ matrix_ssl_certificate_verification_cert_key_path }}`" + when: "not matrix_ssl_certificate_verification_cert_key_path_stat_result.stat.exists" diff --git a/roles/nginx-proxy/tasks/ssl/setup_ssl_self_signed.yml b/roles/nginx-proxy/tasks/ssl/setup_ssl_self_signed.yml new file mode 100644 index 0000000..7fc71ab --- /dev/null +++ b/roles/nginx-proxy/tasks/ssl/setup_ssl_self_signed.yml @@ -0,0 +1,13 @@ +--- + +- ansible.builtin.include_role: + name: matrix/matrix-base + tasks_from: ensure_openssl_installed + when: "matrix_ssl_retrieval_method == 'self-signed'" + +- name: Generate self-signed certificates + ansible.builtin.include_tasks: "{{ role_path }}/tasks/ssl/setup_ssl_self_signed_obtain_for_domain.yml" + with_items: "{{ matrix_ssl_domains_to_obtain_certificates_for | unique }}" + loop_control: + loop_var: domain_name + when: "matrix_ssl_retrieval_method == 'self-signed'" diff --git a/roles/nginx-proxy/tasks/ssl/setup_ssl_self_signed_obtain_for_domain.yml b/roles/nginx-proxy/tasks/ssl/setup_ssl_self_signed_obtain_for_domain.yml new file mode 100644 index 0000000..d0b254a --- /dev/null +++ b/roles/nginx-proxy/tasks/ssl/setup_ssl_self_signed_obtain_for_domain.yml @@ -0,0 +1,49 @@ +--- + +- ansible.builtin.set_fact: + matrix_ssl_certificate_csr_path: "{{ matrix_ssl_config_dir_path }}/live/{{ domain_name }}/csr.csr" + matrix_ssl_certificate_cert_path: "{{ matrix_ssl_config_dir_path }}/live/{{ domain_name }}/fullchain.pem" + matrix_ssl_certificate_cert_key_path: "{{ matrix_ssl_config_dir_path }}/live/{{ domain_name }}/privkey.pem" + +- name: Check if SSL certificate file exists + ansible.builtin.stat: + path: "{{ matrix_ssl_certificate_cert_path }}" + register: matrix_ssl_certificate_cert_path_stat_result + +# In order to do any sort of generation (below), we need to ensure the directory exists first +- name: Ensure SSL certificate directory exists + ansible.builtin.file: + path: "{{ matrix_ssl_certificate_csr_path | dirname }}" + state: directory + mode: 0750 + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + when: "not matrix_ssl_certificate_cert_path_stat_result.stat.exists" + +# The proper way to do this is by using a sequence of +# `openssl_privatekey`, `openssl_csr` and `openssl_certificate`. +# +# Unfortunately, `openssl_csr` and `openssl_certificate` require `PyOpenSSL>=0.15` to work, +# which is not available on CentOS 7 (at least). +# +# We'll do it in a more manual way. +- name: Generate SSL certificate + ansible.builtin.command: | + openssl req -x509 \ + -sha256 \ + -newkey rsa:4096 \ + -nodes \ + -subj "/CN={{ domain_name }}" \ + -keyout {{ matrix_ssl_certificate_cert_key_path }} \ + -out {{ matrix_ssl_certificate_cert_path }} \ + -days 3650 + when: "not matrix_ssl_certificate_cert_path_stat_result.stat.exists" + +- name: Adjust SSL certificate file ownership + ansible.builtin.file: + path: "{{ item }}" + owner: "{{ matrix_user_username }}" + group: "{{ matrix_user_groupname }}" + with_items: + - "{{ matrix_ssl_certificate_cert_key_path }}" + - "{{ matrix_ssl_certificate_cert_path }}" diff --git a/roles/nginx-proxy/tasks/validate_config.yml b/roles/nginx-proxy/tasks/validate_config.yml new file mode 100644 index 0000000..f7d18c9 --- /dev/null +++ b/roles/nginx-proxy/tasks/validate_config.yml @@ -0,0 +1,74 @@ +--- + +- name: (Deprecation) Catch and report renamed settings + ansible.builtin.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: + - {'old': 'matrix_nginx_proxy_matrix_client_api_addr_with_proxy_container', 'new': 'matrix_nginx_proxy_proxy_matrix_client_api_addr_with_container'} + - {'old': 'matrix_nginx_proxy_matrix_client_api_addr_sans_proxy_container', 'new': 'matrix_nginx_proxy_proxy_matrix_client_api_addr_sans_container'} + # People who configured this to disable Riot, would now wish to be disabling Element. + # We now also have `matrix_nginx_proxy_proxy_riot_compat_redirect_`, but that's something else and is disabled by default. + - {'old': 'matrix_nginx_proxy_proxy_riot_enabled', 'new': 'matrix_nginx_proxy_proxy_element_enabled'} + - {'old': 'matrix_ssl_lets_encrypt_renew_cron_time_definition', 'new': ''} + - {'old': 'matrix_nginx_proxy_reload_cron_time_definition', 'new': ''} + +- name: Fail on unknown matrix_ssl_retrieval_method + ansible.builtin.fail: + msg: >- + `matrix_ssl_retrieval_method` needs to be set to a known value. + when: "matrix_ssl_retrieval_method not in ['lets-encrypt', 'self-signed', 'manually-managed', 'none']" + +- name: Fail on unknown matrix_nginx_proxy_ssl_config + ansible.builtin.fail: + msg: >- + `matrix_nginx_proxy_ssl_preset` needs to be set to a known value. + when: "matrix_nginx_proxy_ssl_preset not in ['modern', 'intermediate', 'old']" + +- name: Fail if Basic Auth enabled for metrics, but no credentials supplied + ansible.builtin.fail: + msg: | + Enabling Basic Auth for metrics (`matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_enabled`) requires: + - either a username/password (provided in `matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_username` and `matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_password`) + - or raw htpasswd content (provided in `matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_raw_content`) + when: "matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_enabled | bool and (matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_raw_content == '' and (matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_username == '' or matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_password == ''))" + +- when: "matrix_ssl_retrieval_method == 'lets-encrypt'" + block: + - name: (Deprecation) Catch and report renamed settings + ansible.builtin.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 }}`). + with_items: + - {'old': 'host_specific_matrix_ssl_support_email', 'new': 'matrix_ssl_lets_encrypt_support_email'} + - {'old': 'host_specific_matrix_ssl_lets_encrypt_support_email', 'new': 'matrix_ssl_lets_encrypt_support_email'} + - {'old': 'matrix_nginx_proxy_proxy_synapse_workers_enabled_list', 'new': ''} + when: "item.old in vars" + + - name: Fail if required variables are undefined + ansible.builtin.fail: + msg: "The `{{ item }}` variable must be defined and have a non-null value" + with_items: + - "matrix_ssl_lets_encrypt_support_email" + - "matrix_nginx_proxy_proxy_synapse_federation_api_addr_sans_container" + - "matrix_nginx_proxy_proxy_synapse_federation_api_addr_with_container" + - "matrix_nginx_proxy_proxy_synapse_client_api_addr_with_container" + - "matrix_nginx_proxy_proxy_synapse_client_api_addr_sans_container" + when: "vars[item] == '' or vars[item] is none" + +- name: (Deprecation) Catch and report old metrics usage + ansible.builtin.fail: + msg: >- + Your configuration contains a variable (`{{ item }}`), which refers to the old metrics collection system for Synapse, + which exposed metrics on `https://matrix.DOMAIN/_synapse/metrics` and `https://matrix.DOMAIN/_synapse-worker-TYPE-ID/metrics`. + + We now recommend exposing Synapse metrics in another way, from another URL. + Refer to the changelog for more details: https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/CHANGELOG.md#2022-06-22 + with_items: + - matrix_nginx_proxy_proxy_synapse_metrics + - matrix_nginx_proxy_proxy_synapse_metrics_basic_auth_enabled + - matrix_nginx_proxy_proxy_synapse_metrics_basic_auth_key + when: "item in vars" diff --git a/roles/nginx-proxy/templates/bin/lets-encrypt-certificates-renew.j2 b/roles/nginx-proxy/templates/bin/lets-encrypt-certificates-renew.j2 new file mode 100644 index 0000000..8911362 --- /dev/null +++ b/roles/nginx-proxy/templates/bin/lets-encrypt-certificates-renew.j2 @@ -0,0 +1,32 @@ +#jinja2: lstrip_blocks: "True" +#!/bin/bash + +# For renewal to work, matrix-nginx-proxy (or another webserver, if matrix-nginx-proxy is disabled) +# need to forward requests for `/.well-known/acme-challenge` to the certbot container. +# +# This can happen inside the container network by proxying to `http://matrix-certbot:8080` +# or outside (on the host) by proxying to `http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}`. + +docker run \ + --rm \ + --name=matrix-certbot \ + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ + --network="{{ matrix_docker_network }}" \ + -p 127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}:8080 \ + --mount type=bind,src={{ matrix_ssl_config_dir_path }},dst=/etc/letsencrypt \ + --mount type=bind,src={{ matrix_ssl_log_dir_path }},dst=/var/log/letsencrypt \ + {{ matrix_ssl_lets_encrypt_certbot_docker_image }} \ + renew \ + --non-interactive \ + --work-dir=/tmp \ + --http-01-port 8080 \ + {% if matrix_ssl_lets_encrypt_staging %} + --staging \ + {% endif %} + --key-type {{ matrix_ssl_lets_encrypt_key_type }} \ + --standalone \ + --preferred-challenges http \ + --agree-tos \ + --email={{ matrix_ssl_lets_encrypt_support_email }} \ + --no-random-sleep-on-renew diff --git a/roles/nginx-proxy/templates/nginx/conf.d/a-nginx-https-wildcard.conf.j2 b/roles/nginx-proxy/templates/nginx/conf.d/a-nginx-https-wildcard.conf.j2 new file mode 100644 index 0000000..6548044 --- /dev/null +++ b/roles/nginx-proxy/templates/nginx/conf.d/a-nginx-https-wildcard.conf.j2 @@ -0,0 +1,79 @@ + +{# {% if matrix_wildcard_cerifiate_enabled %} #} +server { + listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + + server_name _.{{ matrix_domain }}; + + server_tokens off; + root /dev/null; + + proxy_buffers 8 16k; + proxy_buffer_size 32k; + + ssl_certificate {{ matrix_ssl_config_dir_path }}/live/_.{{ matrix_domain }}/fullchain.pem; + ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/_.{{ matrix_domain }}/privkey.pem; + + ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; + {% if matrix_nginx_proxy_ssl_ciphers != "" %} + ssl_ciphers {{ matrix_nginx_proxy_ssl_ciphers }}; + {% endif %} + ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/_.{{ matrix_domain }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + +} + + +server { + + {% if matrix_nginx_proxy_https_enabled %} + listen {{ matrix_nginx_proxy_proxy_matrix_federation_port }} ssl http2; + listen [::]:{{ matrix_nginx_proxy_proxy_matrix_federation_port }} ssl http2; + {% else %} + listen {{ matrix_nginx_proxy_proxy_matrix_federation_port }}; + {% endif %} + + server_name _.{{ matrix_domain }}; + server_tokens off; + + root /dev/null; + + gzip on; + gzip_types text/plain application/json; + + {% if matrix_nginx_proxy_https_enabled %} + ssl_certificate {{ matrix_ssl_config_dir_path }}/live/_.{{ matrix_domain }}/fullchain.pem; + ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/_.{{ matrix_domain }}/privkey.pem; + + ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; + {% if matrix_nginx_proxy_ssl_ciphers != '' %} + ssl_ciphers {{ matrix_nginx_proxy_ssl_ciphers }}; + {% endif %} + ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/_.{{ matrix_domain }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + {% endif %} + +} diff --git a/roles/nginx-proxy/templates/nginx/conf.d/gitlab-http.conf.j2 b/roles/nginx-proxy/templates/nginx/conf.d/gitlab-http.conf.j2 new file mode 100644 index 0000000..4efd7ef --- /dev/null +++ b/roles/nginx-proxy/templates/nginx/conf.d/gitlab-http.conf.j2 @@ -0,0 +1,125 @@ +#jinja2: lstrip_blocks: "True" + +{% macro render_vhost_directives() %} + gzip on; + gzip_types text/plain application/json application/javascript text/css image/x-icon font/ttf image/gif; + + {% if matrix_nginx_proxy_hsts_preload_enabled %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; + {% else %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + {% endif %} + add_header X-Content-Type-Options nosniff; + add_header X-XSS-Protection "{{ matrix_nginx_proxy_xss_protection }}"; + add_header X-Frame-Options SAMEORIGIN; + add_header Content-Security-Policy "frame-ancestors 'self'"; + + {% if matrix_nginx_proxy_floc_optout_enabled %} + add_header Permissions-Policy interest-cohort=() always; + {% endif %} + + + {% for configuration_block in matrix_nginx_proxy_proxy_element_additional_server_configuration_blocks %} + {{- configuration_block }} + {% endfor %} + + location / { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + {# resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; #} + set $backend "{{hostvars[groups['gitlab_servers'][0]]['service_ip_address']}}:{{gitlab_http_service_port}}"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:8765; + {% endif %} + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For {{ matrix_nginx_proxy_x_forwarded_for }}; + #proxy_set_header X-Forwarded-For $proxy_protocol_addr; # To forward the original client's IP address + proxy_set_header X-Forwarded-Proto $scheme; # to forward the original protocol (HTTP or HTTPS) + + } + +{% endmacro %} + +server { + listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + listen [::]:{{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + + + server_name {{ matrix_nginx_proxy_proxy_gitlab_hostname }}; + + server_tokens off; + root /dev/null; + + {% if matrix_nginx_proxy_https_enabled %} + location /.well-known/acme-challenge { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-certbot:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; + {% endif %} + } + + location / { + return 301 https://$http_host$request_uri; + } + {% else %} + {{ render_vhost_directives() }} + {% endif %} +} + +{% if matrix_nginx_proxy_https_enabled %} +server { + + server_name {{ matrix_nginx_proxy_proxy_gitlab_hostname }}; + proxy_buffers 8 16k; + proxy_buffer_size 32k; + + + {% if matrix_wildcard_cerifiate_enabled %} + listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} http2; + listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} http2; + + {% else %} + + listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + + server_tokens off; + root /dev/null; + + proxy_buffers 8 16k; + proxy_buffer_size 32k; + + ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_gitlab_hostname }}/fullchain.pem; + ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_gitlab_hostname }}/privkey.pem; + + ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; + {% if matrix_nginx_proxy_ssl_ciphers != "" %} + ssl_ciphers {{ matrix_nginx_proxy_ssl_ciphers }}; + {% endif %} + ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_gitlab_hostname }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + + {% endif %} + + {{ render_vhost_directives() }} +} +{% endif %} diff --git a/roles/nginx-proxy/templates/nginx/conf.d/keycloak-http.conf.j2 b/roles/nginx-proxy/templates/nginx/conf.d/keycloak-http.conf.j2 new file mode 100644 index 0000000..c16655b --- /dev/null +++ b/roles/nginx-proxy/templates/nginx/conf.d/keycloak-http.conf.j2 @@ -0,0 +1,125 @@ +#jinja2: lstrip_blocks: "True" + +{% macro render_vhost_directives() %} + gzip on; + gzip_types text/plain application/json application/javascript text/css image/x-icon font/ttf image/gif; + + {% if matrix_nginx_proxy_hsts_preload_enabled %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; + {% else %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + {% endif %} + add_header X-Content-Type-Options nosniff; + add_header X-XSS-Protection "{{ matrix_nginx_proxy_xss_protection }}"; + add_header X-Frame-Options SAMEORIGIN; + add_header Content-Security-Policy "frame-ancestors 'self'"; + + {% if matrix_nginx_proxy_floc_optout_enabled %} + add_header Permissions-Policy interest-cohort=() always; + {% endif %} + + + {% for configuration_block in matrix_nginx_proxy_proxy_element_additional_server_configuration_blocks %} + {{- configuration_block }} + {% endfor %} + + location / { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + {# resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; #} + set $backend "{{hostvars[groups['keycloak_servers'][0]]['service_ip_address']}}:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:8765; + {% endif %} + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For {{ matrix_nginx_proxy_x_forwarded_for }}; + #proxy_set_header X-Forwarded-For $proxy_protocol_addr; # To forward the original client's IP address + proxy_set_header X-Forwarded-Proto $scheme; # to forward the original protocol (HTTP or HTTPS) + + } + +{% endmacro %} + +server { + listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + listen [::]:{{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + + + server_name {{ matrix_nginx_proxy_proxy_keycloak_hostname }}; + + server_tokens off; + root /dev/null; + + {% if matrix_nginx_proxy_https_enabled %} + location /.well-known/acme-challenge { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-certbot:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; + {% endif %} + } + + location / { + return 301 https://$http_host$request_uri; + } + {% else %} + {{ render_vhost_directives() }} + {% endif %} +} + +{% if matrix_nginx_proxy_https_enabled %} +server { + + server_name {{ matrix_nginx_proxy_proxy_keycloak_hostname }}; + proxy_buffers 8 16k; + proxy_buffer_size 32k; + + + {% if matrix_wildcard_cerifiate_enabled %} + listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} http2; + listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} http2; + + {% else %} + + listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + + server_tokens off; + root /dev/null; + + proxy_buffers 8 16k; + proxy_buffer_size 32k; + + ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_keycloak_hostname }}/fullchain.pem; + ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_keycloak_hostname }}/privkey.pem; + + ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; + {% if matrix_nginx_proxy_ssl_ciphers != "" %} + ssl_ciphers {{ matrix_nginx_proxy_ssl_ciphers }}; + {% endif %} + ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_keycloak_hostname }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + + {% endif %} + + {{ render_vhost_directives() }} +} +{% endif %} diff --git a/roles/nginx-proxy/templates/nginx/conf.d/matrix-base-domain.conf.j2 b/roles/nginx-proxy/templates/nginx/conf.d/matrix-base-domain.conf.j2 new file mode 100644 index 0000000..44978dc --- /dev/null +++ b/roles/nginx-proxy/templates/nginx/conf.d/matrix-base-domain.conf.j2 @@ -0,0 +1,96 @@ +#jinja2: lstrip_blocks: "True" + +{% macro render_vhost_directives() %} + root {{ matrix_nginx_proxy_data_path_in_container if matrix_nginx_proxy_enabled else matrix_nginx_proxy_data_path }}{{ matrix_nginx_proxy_data_path_extension }}; + + gzip on; + gzip_types text/plain application/json; + + {% if matrix_nginx_proxy_floc_optout_enabled %} + add_header Permissions-Policy interest-cohort=() always; + {% endif %} + + {% if matrix_nginx_proxy_hsts_preload_enabled %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; + {% else %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + {% endif %} + + add_header X-XSS-Protection "{{ matrix_nginx_proxy_xss_protection }}"; + + {% for configuration_block in matrix_nginx_proxy_proxy_domain_additional_server_configuration_blocks %} + {{- configuration_block }} + {% endfor %} + + location /.well-known/matrix { + root {{ matrix_static_files_base_path }}; + {# + A somewhat long expires value is used to prevent outages + in case this is unreachable due to network failure. + #} + expires 4h; + default_type application/json; + add_header Access-Control-Allow-Origin *; + } +{% endmacro %} + +server { + listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + listen [::]:{{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + + server_name {{ matrix_nginx_proxy_base_domain_hostname }}; + server_tokens off; + + {% if matrix_nginx_proxy_https_enabled %} + location /.well-known/acme-challenge { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-certbot:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; + {% endif %} + } + + location / { + return 301 https://$http_host$request_uri; + } + {% else %} + {{ render_vhost_directives() }} + {% endif %} +} + +{% if matrix_nginx_proxy_https_enabled %} +server { + listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + + server_name {{ matrix_nginx_proxy_base_domain_hostname }}; + server_tokens off; + + ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_base_domain_hostname }}/fullchain.pem; + ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_base_domain_hostname }}/privkey.pem; + + ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; + {% if matrix_nginx_proxy_ssl_ciphers != '' %} + ssl_ciphers {{ matrix_nginx_proxy_ssl_ciphers }}; + {% endif %} + ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_base_domain_hostname }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + + {{ render_vhost_directives() }} +} +{% endif %} diff --git a/roles/nginx-proxy/templates/nginx/conf.d/matrix-bot-buscarron.conf.j2 b/roles/nginx-proxy/templates/nginx/conf.d/matrix-bot-buscarron.conf.j2 new file mode 100644 index 0000000..4f0fd4a --- /dev/null +++ b/roles/nginx-proxy/templates/nginx/conf.d/matrix-bot-buscarron.conf.j2 @@ -0,0 +1,104 @@ +#jinja2: lstrip_blocks: "True" + +{% macro render_vhost_directives() %} + gzip on; + gzip_types text/plain application/json application/javascript text/css image/x-icon font/ttf image/gif; + + {% if matrix_nginx_proxy_hsts_preload_enabled %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; + {% else %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + {% endif %} + add_header X-XSS-Protection "{{ matrix_nginx_proxy_xss_protection }}"; + add_header X-Content-Type-Options nosniff; + add_header X-Frame-Options SAMEORIGIN; + add_header Content-Security-Policy "frame-ancestors 'none'"; + {% if matrix_nginx_proxy_floc_optout_enabled %} + add_header Permissions-Policy interest-cohort=() always; + {% endif %} + + {% for configuration_block in matrix_nginx_proxy_proxy_buscarron_additional_server_configuration_blocks %} + {{- configuration_block }} + {% endfor %} + + location / { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-bot-buscarron:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:8080; + {% endif %} + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For {{ matrix_nginx_proxy_x_forwarded_for }}; + } +{% endmacro %} + +server { + listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + listen [::]:{{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + + + server_name {{ matrix_nginx_proxy_proxy_buscarron_hostname }}; + + server_tokens off; + root /dev/null; + + {% if matrix_nginx_proxy_https_enabled %} + location /.well-known/acme-challenge { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-certbot:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; + {% endif %} + } + + location / { + return 301 https://$http_host$request_uri; + } + {% else %} + {{ render_vhost_directives() }} + {% endif %} +} + +{% if matrix_nginx_proxy_https_enabled %} +server { + listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + + server_name {{ matrix_nginx_proxy_proxy_buscarron_hostname }}; + + server_tokens off; + root /dev/null; + + ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_buscarron_hostname }}/fullchain.pem; + ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_buscarron_hostname }}/privkey.pem; + + ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; + {% if matrix_nginx_proxy_ssl_ciphers != "" %} + ssl_ciphers {{ matrix_nginx_proxy_ssl_ciphers }}; + {% endif %} + ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_buscarron_hostname }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + + {{ render_vhost_directives() }} +} +{% endif %} diff --git a/roles/nginx-proxy/templates/nginx/conf.d/matrix-bot-go-neb.conf.j2 b/roles/nginx-proxy/templates/nginx/conf.d/matrix-bot-go-neb.conf.j2 new file mode 100644 index 0000000..a62ddfc --- /dev/null +++ b/roles/nginx-proxy/templates/nginx/conf.d/matrix-bot-go-neb.conf.j2 @@ -0,0 +1,97 @@ +#jinja2: lstrip_blocks: "True" + +{% macro render_vhost_directives() %} + gzip on; + gzip_types text/plain application/json application/javascript text/css image/x-icon font/ttf image/gif; + {% if matrix_nginx_proxy_hsts_preload_enabled %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; + {% else %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + {% endif %} + add_header X-XSS-Protection "{{ matrix_nginx_proxy_xss_protection }}"; + add_header X-Content-Type-Options nosniff; + +{% for configuration_block in matrix_nginx_proxy_proxy_bot_go_neb_additional_server_configuration_blocks %} + {{- configuration_block }} +{% endfor %} + + location / { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-bot-go-neb:4050"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:4050; + {% endif %} + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For {{ matrix_nginx_proxy_x_forwarded_for }}; + } +{% endmacro %} + +server { + listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + listen [::]:{{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + + server_name {{ matrix_nginx_proxy_proxy_bot_go_neb_hostname }}; + + server_tokens off; + root /dev/null; + + {% if matrix_nginx_proxy_https_enabled %} + location /.well-known/acme-challenge { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-certbot:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; + {% endif %} + } + + location / { + return 301 https://$http_host$request_uri; + } + {% else %} + {{ render_vhost_directives() }} + {% endif %} +} + +{% if matrix_nginx_proxy_https_enabled %} +server { + listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + + server_name {{ matrix_nginx_proxy_proxy_bot_go_neb_hostname }}; + + server_tokens off; + root /dev/null; + + ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_bot_go_neb_hostname }}/fullchain.pem; + ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_bot_go_neb_hostname }}/privkey.pem; + + ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; + {% if matrix_nginx_proxy_ssl_ciphers != '' %} + ssl_ciphers {{ matrix_nginx_proxy_ssl_ciphers }}; + {% endif %} + ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_bot_go_neb_hostname }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + + {{ render_vhost_directives() }} +} +{% endif %} diff --git a/roles/nginx-proxy/templates/nginx/conf.d/matrix-client-cinny.conf.j2 b/roles/nginx-proxy/templates/nginx/conf.d/matrix-client-cinny.conf.j2 new file mode 100644 index 0000000..2ec6eb1 --- /dev/null +++ b/roles/nginx-proxy/templates/nginx/conf.d/matrix-client-cinny.conf.j2 @@ -0,0 +1,104 @@ +#jinja2: lstrip_blocks: "True" + +{% macro render_vhost_directives() %} + gzip on; + gzip_types text/plain application/json application/javascript text/css image/x-icon font/ttf image/gif; + + {% if matrix_nginx_proxy_hsts_preload_enabled %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; + {% else %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + {% endif %} + add_header X-XSS-Protection "{{ matrix_nginx_proxy_xss_protection }}"; + add_header X-Content-Type-Options nosniff; + add_header X-Frame-Options SAMEORIGIN; + add_header Content-Security-Policy "frame-ancestors 'none'"; + {% if matrix_nginx_proxy_floc_optout_enabled %} + add_header Permissions-Policy interest-cohort=() always; + {% endif %} + + {% for configuration_block in matrix_nginx_proxy_proxy_cinny_additional_server_configuration_blocks %} + {{- configuration_block }} + {% endfor %} + + location / { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-client-cinny:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:8080; + {% endif %} + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For {{ matrix_nginx_proxy_x_forwarded_for }}; + } +{% endmacro %} + +server { + listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + listen [::]:{{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + + + server_name {{ matrix_nginx_proxy_proxy_cinny_hostname }}; + + server_tokens off; + root /dev/null; + + {% if matrix_nginx_proxy_https_enabled %} + location /.well-known/acme-challenge { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-certbot:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; + {% endif %} + } + + location / { + return 301 https://$http_host$request_uri; + } + {% else %} + {{ render_vhost_directives() }} + {% endif %} +} + +{% if matrix_nginx_proxy_https_enabled %} +server { + listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + + server_name {{ matrix_nginx_proxy_proxy_cinny_hostname }}; + + server_tokens off; + root /dev/null; + + ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_cinny_hostname }}/fullchain.pem; + ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_cinny_hostname }}/privkey.pem; + + ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; + {% if matrix_nginx_proxy_ssl_ciphers != "" %} + ssl_ciphers {{ matrix_nginx_proxy_ssl_ciphers }}; + {% endif %} + ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_cinny_hostname }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + + {{ render_vhost_directives() }} +} +{% endif %} diff --git a/roles/nginx-proxy/templates/nginx/conf.d/matrix-client-element.conf.j2 b/roles/nginx-proxy/templates/nginx/conf.d/matrix-client-element.conf.j2 new file mode 100644 index 0000000..fd9fd73 --- /dev/null +++ b/roles/nginx-proxy/templates/nginx/conf.d/matrix-client-element.conf.j2 @@ -0,0 +1,116 @@ +#jinja2: lstrip_blocks: "True" + +{% macro render_vhost_directives() %} + gzip on; + gzip_types text/plain application/json application/javascript text/css image/x-icon font/ttf image/gif; + + {% if matrix_nginx_proxy_hsts_preload_enabled %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; + {% else %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + {% endif %} + add_header X-Content-Type-Options nosniff; + add_header X-XSS-Protection "{{ matrix_nginx_proxy_xss_protection }}"; + add_header X-Frame-Options SAMEORIGIN; + add_header Content-Security-Policy "frame-ancestors 'self'"; + + {% if matrix_nginx_proxy_floc_optout_enabled %} + add_header Permissions-Policy interest-cohort=() always; + {% endif %} + + + {% for configuration_block in matrix_nginx_proxy_proxy_element_additional_server_configuration_blocks %} + {{- configuration_block }} + {% endfor %} + + location / { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-client-element:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:8765; + {% endif %} + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For {{ matrix_nginx_proxy_x_forwarded_for }}; + } +{% endmacro %} + +server { + listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + listen [::]:{{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + + + server_name {{ matrix_nginx_proxy_proxy_element_hostname }}; + + server_tokens off; + root /dev/null; + + {% if matrix_nginx_proxy_https_enabled %} + location /.well-known/acme-challenge { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-certbot:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; + {% endif %} + } + + location / { + return 301 https://$http_host$request_uri; + } + {% else %} + {{ render_vhost_directives() }} + {% endif %} +} + +{% if matrix_nginx_proxy_https_enabled %} +server { + + server_name {{ matrix_nginx_proxy_proxy_element_hostname }}; + + {% if matrix_wildcard_cerifiate_enabled %} + listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} http2; + listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} http2; + + {% else %} + + listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + + + server_tokens off; + root /dev/null; + + ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_element_hostname }}/fullchain.pem; + ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_element_hostname }}/privkey.pem; + + ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; + {% if matrix_nginx_proxy_ssl_ciphers != "" %} + ssl_ciphers {{ matrix_nginx_proxy_ssl_ciphers }}; + {% endif %} + ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_element_hostname }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + + {% endif %} + + {{ render_vhost_directives() }} +} +{% endif %} diff --git a/roles/nginx-proxy/templates/nginx/conf.d/matrix-client-hydrogen.conf.j2 b/roles/nginx-proxy/templates/nginx/conf.d/matrix-client-hydrogen.conf.j2 new file mode 100644 index 0000000..7a2e9df --- /dev/null +++ b/roles/nginx-proxy/templates/nginx/conf.d/matrix-client-hydrogen.conf.j2 @@ -0,0 +1,104 @@ +#jinja2: lstrip_blocks: "True" + +{% macro render_vhost_directives() %} + gzip on; + gzip_types text/plain application/json application/javascript text/css image/x-icon font/ttf image/gif; + + {% if matrix_nginx_proxy_hsts_preload_enabled %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; + {% else %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + {% endif %} + add_header X-XSS-Protection "{{ matrix_nginx_proxy_xss_protection }}"; + add_header X-Content-Type-Options nosniff; + add_header X-Frame-Options SAMEORIGIN; + add_header Content-Security-Policy "frame-ancestors 'none'"; + {% if matrix_nginx_proxy_floc_optout_enabled %} + add_header Permissions-Policy interest-cohort=() always; + {% endif %} + + {% for configuration_block in matrix_nginx_proxy_proxy_hydrogen_additional_server_configuration_blocks %} + {{- configuration_block }} + {% endfor %} + + location / { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-client-hydrogen:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:8768; + {% endif %} + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For {{ matrix_nginx_proxy_x_forwarded_for }}; + } +{% endmacro %} + +server { + listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + listen [::]:{{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + + + server_name {{ matrix_nginx_proxy_proxy_hydrogen_hostname }}; + + server_tokens off; + root /dev/null; + + {% if matrix_nginx_proxy_https_enabled %} + location /.well-known/acme-challenge { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-certbot:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; + {% endif %} + } + + location / { + return 301 https://$http_host$request_uri; + } + {% else %} + {{ render_vhost_directives() }} + {% endif %} +} + +{% if matrix_nginx_proxy_https_enabled %} +server { + listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + + server_name {{ matrix_nginx_proxy_proxy_hydrogen_hostname }}; + + server_tokens off; + root /dev/null; + + ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_hydrogen_hostname }}/fullchain.pem; + ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_hydrogen_hostname }}/privkey.pem; + + ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; + {% if matrix_nginx_proxy_ssl_ciphers != "" %} + ssl_ciphers {{ matrix_nginx_proxy_ssl_ciphers }}; + {% endif %} + ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_hydrogen_hostname }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + + {{ render_vhost_directives() }} +} +{% endif %} diff --git a/roles/nginx-proxy/templates/nginx/conf.d/matrix-conduit.conf.j2 b/roles/nginx-proxy/templates/nginx/conf.d/matrix-conduit.conf.j2 new file mode 100644 index 0000000..6e7aca7 --- /dev/null +++ b/roles/nginx-proxy/templates/nginx/conf.d/matrix-conduit.conf.j2 @@ -0,0 +1,77 @@ +#jinja2: lstrip_blocks: "True" + +server { + listen 12080; + server_name {{ matrix_nginx_proxy_proxy_conduit_hostname }}; + + server_tokens off; + root /dev/null; + + gzip on; + gzip_types text/plain application/json; + + {% for configuration_block in matrix_nginx_proxy_proxy_conduit_additional_server_configuration_blocks %} + {{- configuration_block }} + {% endfor %} + + {% if matrix_nginx_proxy_proxy_conduit_block_federation_api_on_client_port %} + location /_matrix/federation { + {% if matrix_nginx_proxy_proxy_conduit_federation_api_enabled %} + return 404 'The Federation API is served at https://{{ matrix_server_fqn_matrix }}:{{ matrix_federation_public_port }}'; + {% else %} + return 404 'This Matrix server is running with federation disabled'; + {% endif %} + } + {% endif %} + + {# Everything else just goes to the API server ##} + location / { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "{{ matrix_nginx_proxy_proxy_conduit_client_api_addr_with_container }}"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://{{ matrix_nginx_proxy_proxy_conduit_client_api_addr_sans_container }}; + {% endif %} + + proxy_set_header Host $host; + + client_body_buffer_size 25M; + client_max_body_size {{ matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb }}M; + proxy_max_temp_file_size 0; + } +} + +{% if matrix_nginx_proxy_proxy_conduit_federation_api_enabled %} +server { + listen 12088; + + server_name {{ matrix_nginx_proxy_proxy_conduit_hostname }}; + server_tokens off; + + root /dev/null; + + gzip on; + gzip_types text/plain application/json; + + location / { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "{{ matrix_nginx_proxy_proxy_conduit_federation_api_addr_with_container }}"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://{{ matrix_nginx_proxy_proxy_conduit_federation_api_addr_sans_container }}; + {% endif %} + + proxy_set_header Host $host; + + client_body_buffer_size 25M; + client_max_body_size {{ matrix_nginx_proxy_proxy_matrix_federation_api_client_max_body_size_mb }}M; + proxy_max_temp_file_size 0; + } +} +{% endif %} diff --git a/roles/nginx-proxy/templates/nginx/conf.d/matrix-dendrite.conf.j2 b/roles/nginx-proxy/templates/nginx/conf.d/matrix-dendrite.conf.j2 new file mode 100644 index 0000000..10eccf3 --- /dev/null +++ b/roles/nginx-proxy/templates/nginx/conf.d/matrix-dendrite.conf.j2 @@ -0,0 +1,77 @@ +#jinja2: lstrip_blocks: "True" + +server { + listen 12080; + server_name {{ matrix_nginx_proxy_proxy_dendrite_hostname }}; + + server_tokens off; + root /dev/null; + + gzip on; + gzip_types text/plain application/json; + + {% for configuration_block in matrix_nginx_proxy_proxy_dendrite_additional_server_configuration_blocks %} + {{- configuration_block }} + {% endfor %} + + {% if matrix_nginx_proxy_proxy_dendrite_block_federation_api_on_client_port %} + location /_matrix/federation { + {% if matrix_nginx_proxy_proxy_dendrite_federation_api_enabled %} + return 404 'The Federation API is served at https://{{ matrix_server_fqn_matrix }}:{{ matrix_federation_public_port }}'; + {% else %} + return 404 'This Matrix server is running with federation disabled'; + {% endif %} + } + {% endif %} + + {# Everything else just goes to the API server ##} + location / { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "{{ matrix_nginx_proxy_proxy_dendrite_client_api_addr_with_container }}"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://{{ matrix_nginx_proxy_proxy_dendrite_client_api_addr_sans_container }}; + {% endif %} + + proxy_set_header Host $host; + + client_body_buffer_size 25M; + client_max_body_size {{ matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb }}M; + proxy_max_temp_file_size 0; + } +} + +{% if matrix_nginx_proxy_proxy_dendrite_federation_api_enabled %} +server { + listen 12088; + + server_name {{ matrix_nginx_proxy_proxy_dendrite_hostname }}; + server_tokens off; + + root /dev/null; + + gzip on; + gzip_types text/plain application/json; + + location / { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "{{ matrix_nginx_proxy_proxy_dendrite_federation_api_addr_with_container }}"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://{{ matrix_nginx_proxy_proxy_dendrite_federation_api_addr_sans_container }}; + {% endif %} + + proxy_set_header Host $host; + + client_body_buffer_size 25M; + client_max_body_size {{ matrix_nginx_proxy_proxy_matrix_federation_api_client_max_body_size_mb }}M; + proxy_max_temp_file_size 0; + } +} +{% endif %} diff --git a/roles/nginx-proxy/templates/nginx/conf.d/matrix-dimension.conf.j2 b/roles/nginx-proxy/templates/nginx/conf.d/matrix-dimension.conf.j2 new file mode 100644 index 0000000..730fc4c --- /dev/null +++ b/roles/nginx-proxy/templates/nginx/conf.d/matrix-dimension.conf.j2 @@ -0,0 +1,100 @@ +#jinja2: lstrip_blocks: "True" + +{% macro render_vhost_directives() %} + gzip on; + gzip_types text/plain application/json application/javascript text/css image/x-icon font/ttf image/gif; + {% if matrix_nginx_proxy_hsts_preload_enabled %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; + {% else %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + {% endif %} + add_header X-XSS-Protection "{{ matrix_nginx_proxy_xss_protection }}"; + add_header X-Content-Type-Options nosniff; + {% if matrix_nginx_proxy_floc_optout_enabled %} + add_header Permissions-Policy interest-cohort=() always; + {% endif %} + +{% for configuration_block in matrix_nginx_proxy_proxy_dimension_additional_server_configuration_blocks %} + {{- configuration_block }} +{% endfor %} + + location / { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-dimension:8184"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:8184; + {% endif %} + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For {{ matrix_nginx_proxy_x_forwarded_for }}; + } +{% endmacro %} + +server { + listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + listen [::]:{{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + + server_name {{ matrix_nginx_proxy_proxy_dimension_hostname }}; + + server_tokens off; + root /dev/null; + + {% if matrix_nginx_proxy_https_enabled %} + location /.well-known/acme-challenge { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-certbot:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; + {% endif %} + } + + location / { + return 301 https://$http_host$request_uri; + } + {% else %} + {{ render_vhost_directives() }} + {% endif %} +} + +{% if matrix_nginx_proxy_https_enabled %} +server { + listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + + server_name {{ matrix_nginx_proxy_proxy_dimension_hostname }}; + + server_tokens off; + root /dev/null; + + ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_dimension_hostname }}/fullchain.pem; + ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_dimension_hostname }}/privkey.pem; + + ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; + {% if matrix_nginx_proxy_ssl_ciphers != '' %} + ssl_ciphers {{ matrix_nginx_proxy_ssl_ciphers }}; + {% endif %} + ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_dimension_hostname }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + + {{ render_vhost_directives() }} +} +{% endif %} diff --git a/roles/nginx-proxy/templates/nginx/conf.d/matrix-domain.conf.j2 b/roles/nginx-proxy/templates/nginx/conf.d/matrix-domain.conf.j2 new file mode 100644 index 0000000..71909af --- /dev/null +++ b/roles/nginx-proxy/templates/nginx/conf.d/matrix-domain.conf.j2 @@ -0,0 +1,323 @@ +#jinja2: lstrip_blocks: "True" +{% macro render_nginx_status_location_block(addresses) %} + {# Empty first line to make indentation prettier. #} + + location /nginx_status { + stub_status on; + access_log off; + {% for address in addresses %} + allow {{ address }}; + {% endfor %} + deny all; + } +{% endmacro %} + + +{% macro render_vhost_directives() %} + gzip on; + gzip_types text/plain application/json; + + {% if matrix_nginx_proxy_floc_optout_enabled %} + add_header Permissions-Policy interest-cohort=() always; + {% endif %} + + {% if matrix_nginx_proxy_hsts_preload_enabled %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; + {% else %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + {% endif %} + + add_header X-XSS-Protection "{{ matrix_nginx_proxy_xss_protection }}"; + + location /.well-known/matrix { + root {{ matrix_static_files_base_path }}; + {# + A somewhat long expires value is used to prevent outages + in case this is unreachable due to network failure or + due to the base domain's server completely dying. + #} + expires 4h; + default_type application/json; + add_header Access-Control-Allow-Origin *; + } + + {% if matrix_nginx_proxy_proxy_matrix_nginx_status_enabled %} + {{ render_nginx_status_location_block(matrix_nginx_proxy_proxy_matrix_nginx_status_allowed_addresses) }} + {% endif %} + + {% if matrix_nginx_proxy_proxy_matrix_metrics_enabled %} + location /metrics { + {% if matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_enabled %} + auth_basic "protected"; + auth_basic_user_file {{ matrix_nginx_proxy_proxy_matrix_metrics_basic_auth_path }}; + {% endif %} + + {% for configuration_block in matrix_nginx_proxy_proxy_matrix_metrics_additional_location_configuration_blocks %} + {{- configuration_block }} + {% endfor %} + } + {% endif %} + + {% if matrix_nginx_proxy_proxy_matrix_corporal_api_enabled %} + location ^~ /_matrix/corporal { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "{{ matrix_nginx_proxy_proxy_matrix_corporal_api_addr_with_container }}"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://{{ matrix_nginx_proxy_proxy_matrix_corporal_api_addr_sans_container }}; + {% endif %} + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For {{ matrix_nginx_proxy_x_forwarded_for }}; + proxy_set_header X-Forwarded-Proto {{ matrix_nginx_proxy_x_forwarded_proto_value }}; + } + {% endif %} + + {% if matrix_nginx_proxy_proxy_matrix_identity_api_enabled %} + location ^~ /_matrix/identity { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "{{ matrix_nginx_proxy_proxy_matrix_identity_api_addr_with_container }}"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://{{ matrix_nginx_proxy_proxy_matrix_identity_api_addr_sans_container }}; + {% endif %} + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For {{ matrix_nginx_proxy_x_forwarded_for }}; + proxy_set_header X-Forwarded-Proto {{ matrix_nginx_proxy_x_forwarded_proto_value }}; + } + {% endif %} + + {% if matrix_nginx_proxy_proxy_matrix_user_directory_search_enabled %} + location ^~ /_matrix/client/r0/user_directory/search { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "{{ matrix_nginx_proxy_proxy_matrix_user_directory_search_addr_with_container }}"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://{{ matrix_nginx_proxy_proxy_matrix_user_directory_search_addr_sans_container }}; + {% endif %} + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For {{ matrix_nginx_proxy_x_forwarded_for }}; + } + {% endif %} + + {% if matrix_nginx_proxy_proxy_matrix_3pid_registration_enabled %} + location ~ ^/_matrix/client/r0/register/(email|msisdn)/requestToken$ { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "{{ matrix_nginx_proxy_proxy_matrix_3pid_registration_addr_with_container }}"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://{{ matrix_nginx_proxy_proxy_matrix_3pid_registration_addr_sans_container }}; + {% endif %} + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For {{ matrix_nginx_proxy_x_forwarded_for }}; + proxy_set_header X-Forwarded-Proto {{ matrix_nginx_proxy_x_forwarded_proto_value }}; + } + {% endif %} + + {% for configuration_block in matrix_nginx_proxy_proxy_matrix_additional_server_configuration_blocks %} + {{- configuration_block }} + {% endfor %} + + {# + This handles the Matrix Client API only. + The Matrix Federation API is handled by a separate vhost. + #} + location ~* ^({{ matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_prefix_regexes|join('|') }}) { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "{{ matrix_nginx_proxy_proxy_matrix_client_api_addr_with_container }}"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://{{ matrix_nginx_proxy_proxy_matrix_client_api_addr_sans_container }}; + {% endif %} + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For {{ matrix_nginx_proxy_x_forwarded_for }}; + proxy_set_header X-Forwarded-Proto {{ matrix_nginx_proxy_x_forwarded_proto_value }}; + + client_body_buffer_size 25M; + client_max_body_size {{ matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb }}M; + proxy_max_temp_file_size 0; + } + + {# + We only handle the root URI for this redirect or homepage serving. + Unhandled URIs (mostly by `matrix_nginx_proxy_proxy_matrix_client_api_forwarded_location_prefix_regexes` above) should result in a 404, + instead of causing a redirect. + See: https://github.com/spantaleev/matrix-docker-ansible-deploy/issues/1058 + #} + location ~* ^/$ { + {% if matrix_nginx_proxy_proxy_matrix_client_redirect_root_uri_to_domain %} + return 302 {{ matrix_nginx_proxy_x_forwarded_proto_value }}://{{ matrix_nginx_proxy_proxy_matrix_client_redirect_root_uri_to_domain }}$request_uri; + {% else %} + rewrite ^/$ /_matrix/static/ last; + {% endif %} + } +{% endmacro %} + +server { + listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + listen [::]:{{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + + server_name {{ matrix_nginx_proxy_proxy_matrix_hostname }}; + + server_tokens off; + root /dev/null; + + {% if matrix_nginx_proxy_https_enabled %} + location /.well-known/acme-challenge { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-certbot:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; + {% endif %} + } + + {% if matrix_nginx_proxy_proxy_matrix_nginx_status_enabled %} + {{ render_nginx_status_location_block(matrix_nginx_proxy_proxy_matrix_nginx_status_allowed_addresses) }} + {% endif %} + + location / { + return 301 https://$http_host$request_uri; + } + {% else %} + {{ render_vhost_directives() }} + {% endif %} +} + +{% if matrix_nginx_proxy_https_enabled %} +server { + + server_name {{ matrix_nginx_proxy_proxy_matrix_hostname }}; + + {% if matrix_wildcard_cerifiate_enabled %} + listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} http2; + listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} http2; + + {% else %} + listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + + + server_tokens off; + root /dev/null; + + ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_matrix_hostname }}/fullchain.pem; + ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_matrix_hostname }}/privkey.pem; + + ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; + {% if matrix_nginx_proxy_ssl_ciphers != '' %} + ssl_ciphers {{ matrix_nginx_proxy_ssl_ciphers }}; + {% endif %} + ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_matrix_hostname }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + {% endif %} + {{ render_vhost_directives() }} +} +{% endif %} + +{% if matrix_nginx_proxy_proxy_matrix_federation_api_enabled %} +{# + This federation vhost is a little special. + It serves federation over HTTP or HTTPS, depending on `matrix_nginx_proxy_https_enabled`. +#} +server { + + server_name {{ matrix_nginx_proxy_proxy_matrix_federation_hostname }}; + + {% if matrix_wildcard_cerifiate_enabled %} + listen {{ matrix_nginx_proxy_proxy_matrix_federation_port }} http2; + listen [::]:{{ matrix_nginx_proxy_proxy_matrix_federation_port }} http2; + {% else %} + {% if matrix_nginx_proxy_https_enabled %} + listen {{ matrix_nginx_proxy_proxy_matrix_federation_port }} ssl http2; + listen [::]:{{ matrix_nginx_proxy_proxy_matrix_federation_port }} ssl http2; + {% else %} + listen {{ matrix_nginx_proxy_proxy_matrix_federation_port }}; + {% endif %} + + + server_tokens off; + + root /dev/null; + + gzip on; + gzip_types text/plain application/json; + + {% if matrix_nginx_proxy_https_enabled %} + ssl_certificate {{ matrix_nginx_proxy_proxy_matrix_federation_api_ssl_certificate }}; + ssl_certificate_key {{ matrix_nginx_proxy_proxy_matrix_federation_api_ssl_certificate_key }}; + + ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; + {% if matrix_nginx_proxy_ssl_ciphers != '' %} + ssl_ciphers {{ matrix_nginx_proxy_ssl_ciphers }}; + {% endif %} + ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_nginx_proxy_proxy_matrix_federation_api_ssl_trusted_certificate }}; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + {% endif %} + {% endif %} + + location / { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "{{ matrix_nginx_proxy_proxy_matrix_federation_api_addr_with_container }}"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://{{ matrix_nginx_proxy_proxy_matrix_federation_api_addr_sans_container }}; + {% endif %} + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For {{ matrix_nginx_proxy_x_forwarded_for }}; + proxy_set_header X-Forwarded-Proto {{ matrix_nginx_proxy_x_forwarded_proto_value }}; + + client_body_buffer_size 25M; + client_max_body_size {{ matrix_nginx_proxy_proxy_matrix_federation_api_client_max_body_size_mb }}M; + proxy_max_temp_file_size 0; + } +} +{% endif %} diff --git a/roles/nginx-proxy/templates/nginx/conf.d/matrix-etherpad.conf.j2 b/roles/nginx-proxy/templates/nginx/conf.d/matrix-etherpad.conf.j2 new file mode 100644 index 0000000..8cad9ee --- /dev/null +++ b/roles/nginx-proxy/templates/nginx/conf.d/matrix-etherpad.conf.j2 @@ -0,0 +1,108 @@ +#jinja2: lstrip_blocks: "True" + +{% macro render_vhost_directives() %} + gzip on; + gzip_types text/plain application/json application/javascript text/css image/x-icon font/ttf image/gif; + {% if matrix_nginx_proxy_hsts_preload_enabled %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; + {% else %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + {% endif %} + add_header X-XSS-Protection "{{ matrix_nginx_proxy_xss_protection }}"; + add_header X-Content-Type-Options nosniff; + {% if matrix_nginx_proxy_floc_optout_enabled %} + add_header Permissions-Policy interest-cohort=() always; + {% endif %} + +{% for configuration_block in matrix_nginx_proxy_proxy_etherpad_additional_server_configuration_blocks %} + {{- configuration_block }} +{% endfor %} + + location / { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-etherpad:9001"; + proxy_pass http://$backend; + {# These are proxy directives needed specifically by Etherpad #} + proxy_buffering off; + proxy_http_version 1.1; {# recommended with keepalive connections #} + proxy_pass_header Server; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-Proto {{ matrix_nginx_proxy_x_forwarded_proto_value }}; {# for EP to set secure cookie flag when https is used #} + {# WebSocket proxying - from http://nginx.org/en/docs/http/websocket.html #} + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + {% else %} + {# Generic configuration for use outside of our container setup #} + # A good guide for setting up your Etherpad behind nginx: + # https://docs.gandi.net/en/cloud/tutorials/etherpad_lite.html + proxy_pass http://127.0.0.1:9001/; + {% endif %} + } +{% endmacro %} + +server { + listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + listen [::]:{{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + + server_name {{ matrix_nginx_proxy_proxy_etherpad_hostname }}; + + server_tokens off; + root /dev/null; + + {% if matrix_nginx_proxy_https_enabled %} + location /.well-known/acme-challenge { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-certbot:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; + {% endif %} + } + + location / { + return 301 https://$http_host$request_uri; + } + {% else %} + {{ render_vhost_directives() }} + {% endif %} +} + +{% if matrix_nginx_proxy_https_enabled %} +server { + listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + + server_name {{ matrix_nginx_proxy_proxy_etherpad_hostname }}; + + server_tokens off; + root /dev/null; + + ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_etherpad_hostname }}/fullchain.pem; + ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_etherpad_hostname }}/privkey.pem; + + ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; + {% if matrix_nginx_proxy_ssl_ciphers != '' %} + ssl_ciphers {{ matrix_nginx_proxy_ssl_ciphers }}; + {% endif %} + ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_etherpad_hostname }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + + {{ render_vhost_directives() }} +} +{% endif %} diff --git a/roles/nginx-proxy/templates/nginx/conf.d/matrix-grafana.conf.j2 b/roles/nginx-proxy/templates/nginx/conf.d/matrix-grafana.conf.j2 new file mode 100644 index 0000000..0941804 --- /dev/null +++ b/roles/nginx-proxy/templates/nginx/conf.d/matrix-grafana.conf.j2 @@ -0,0 +1,108 @@ +#jinja2: lstrip_blocks: "True" + +{% macro render_vhost_directives() %} + gzip on; + gzip_types text/plain application/json application/javascript text/css image/x-icon font/ttf image/gif; + + {% if matrix_nginx_proxy_hsts_preload_enabled %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; + {% else %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + {% endif %} + # duplicate X-Content-Type-Options & X-Frame-Options header + # Enabled by grafana by default + # add_header X-Content-Type-Options nosniff; + # add_header X-Frame-Options SAMEORIGIN; + add_header Referrer-Policy "strict-origin-when-cross-origin"; + + {% if matrix_nginx_proxy_floc_optout_enabled %} + add_header Permissions-Policy interest-cohort=() always; + {% endif %} + + proxy_cookie_path / "/; HTTPOnly; Secure"; + + {% for configuration_block in matrix_nginx_proxy_proxy_grafana_additional_server_configuration_blocks %} + {{- configuration_block }} + {% endfor %} + + location / { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-grafana:3000"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:3000; + {% endif %} + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For {{ matrix_nginx_proxy_x_forwarded_for }}; + } +{% endmacro %} + +server { + listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + listen [::]:{{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + + + server_name {{ matrix_nginx_proxy_proxy_grafana_hostname }}; + + server_tokens off; + root /dev/null; + + {% if matrix_nginx_proxy_https_enabled %} + location /.well-known/acme-challenge { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-certbot:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; + {% endif %} + } + + location / { + return 301 https://$http_host$request_uri; + } + {% else %} + {{ render_vhost_directives() }} + {% endif %} +} + +{% if matrix_nginx_proxy_https_enabled %} +server { + listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + + server_name {{ matrix_nginx_proxy_proxy_grafana_hostname }}; + + server_tokens off; + root /dev/null; + + ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_grafana_hostname }}/fullchain.pem; + ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_grafana_hostname }}/privkey.pem; + + ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; + {% if matrix_nginx_proxy_ssl_ciphers != "" %} + ssl_ciphers {{ matrix_nginx_proxy_ssl_ciphers }}; + {% endif %} + ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_grafana_hostname }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + + {{ render_vhost_directives() }} +} +{% endif %} diff --git a/roles/nginx-proxy/templates/nginx/conf.d/matrix-jitsi.conf.j2 b/roles/nginx-proxy/templates/nginx/conf.d/matrix-jitsi.conf.j2 new file mode 100644 index 0000000..4d5a4ce --- /dev/null +++ b/roles/nginx-proxy/templates/nginx/conf.d/matrix-jitsi.conf.j2 @@ -0,0 +1,158 @@ +#jinja2: lstrip_blocks: "True" + +{% macro render_vhost_directives() %} + gzip on; + gzip_types text/plain application/json application/javascript text/css image/x-icon font/ttf image/gif; + {% if matrix_nginx_proxy_hsts_preload_enabled %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; + {% else %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + {% endif %} + add_header X-XSS-Protection "{{ matrix_nginx_proxy_xss_protection }}"; + add_header X-Content-Type-Options nosniff; + {% if matrix_nginx_proxy_floc_optout_enabled %} + add_header Permissions-Policy interest-cohort=() always; + {% endif %} + +{% for configuration_block in matrix_nginx_proxy_proxy_jitsi_additional_server_configuration_blocks %} + {{- configuration_block }} +{% endfor %} + + location / { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-jitsi-web:80"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:13080; + {% endif %} + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For {{ matrix_nginx_proxy_x_forwarded_for }}; + } + + # colibri (JVB) websockets + location ~ ^/colibri-ws/jvb-1/(.*) { + {% if matrix_nginx_proxy_enabled %} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-jitsi-jvb:9090"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:13090; + {% endif %} + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For {{ matrix_nginx_proxy_x_forwarded_for }}; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + proxy_http_version 1.1; + + tcp_nodelay on; + } + {% for id, ip_address in matrix_nginx_proxy_proxy_jitsi_additional_jvbs.items() %} + # colibri (JVB) websockets for additional JVBs + location ~ ^/colibri-ws/{{ id | regex_escape }}/(.*) { + proxy_pass http://{{ ip_address }}:9090/colibri-ws/{{ id }}/$1$is_args$args; + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For {{ matrix_nginx_proxy_x_forwarded_for }}; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + proxy_http_version 1.1; + + tcp_nodelay on; + } + {% endfor %} + + + # XMPP websocket + location = /xmpp-websocket { + {% if matrix_nginx_proxy_enabled %} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend {{ matrix_jitsi_xmpp_bosh_url_base }}; + proxy_pass $backend/xmpp-websocket; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:5280; + {% endif %} + proxy_set_header Host $host; + + proxy_http_version 1.1; + proxy_read_timeout 900s; + proxy_set_header Connection "upgrade"; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header X-Forwarded-For {{ matrix_nginx_proxy_x_forwarded_for }}; + proxy_set_header X-Forwarded-Proto {{ matrix_nginx_proxy_x_forwarded_proto_value }}; + tcp_nodelay on; + } +{% endmacro %} + +server { + listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + listen [::]:{{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + + server_name {{ matrix_nginx_proxy_proxy_jitsi_hostname }}; + + server_tokens off; + root /dev/null; + + {% if matrix_nginx_proxy_https_enabled %} + location /.well-known/acme-challenge { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-certbot:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; + {% endif %} + } + + location / { + return 301 https://$http_host$request_uri; + } + {% else %} + {{ render_vhost_directives() }} + {% endif %} +} + +{% if matrix_nginx_proxy_https_enabled %} +server { + listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + + server_name {{ matrix_nginx_proxy_proxy_jitsi_hostname }}; + + server_tokens off; + root /dev/null; + + ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_jitsi_hostname }}/fullchain.pem; + ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_jitsi_hostname }}/privkey.pem; + + ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; + {% if matrix_nginx_proxy_ssl_ciphers != '' %} + ssl_ciphers {{ matrix_nginx_proxy_ssl_ciphers }}; + {% endif %} + ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_jitsi_hostname }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + + {{ render_vhost_directives() }} +} +{% endif %} diff --git a/roles/nginx-proxy/templates/nginx/conf.d/matrix-ntfy.conf.j2 b/roles/nginx-proxy/templates/nginx/conf.d/matrix-ntfy.conf.j2 new file mode 100644 index 0000000..fbae47e --- /dev/null +++ b/roles/nginx-proxy/templates/nginx/conf.d/matrix-ntfy.conf.j2 @@ -0,0 +1,102 @@ +#jinja2: lstrip_blocks: "True" + +{% macro render_vhost_directives() %} + gzip on; + gzip_types text/plain application/json application/javascript text/css image/x-icon font/ttf image/gif; + + {% if matrix_nginx_proxy_hsts_preload_enabled %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; + {% else %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + {% endif %} + add_header X-XSS-Protection "{{ matrix_nginx_proxy_xss_protection }}"; + add_header X-Content-Type-Options nosniff; + add_header X-Frame-Options DENY; + +{% for configuration_block in matrix_nginx_proxy_proxy_ntfy_additional_server_configuration_blocks %} + {{- configuration_block }} +{% endfor %} + + location / { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-ntfy:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:2586; + {% endif %} + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For {{ matrix_nginx_proxy_x_forwarded_for }}; + proxy_set_header X-Forwarded-Proto {{ matrix_nginx_proxy_x_forwarded_proto_value }}; + } +{% endmacro %} + +server { + listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + listen [::]:{{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + + server_name {{ matrix_nginx_proxy_proxy_ntfy_hostname }}; + + server_tokens off; + root /dev/null; + + {% if matrix_nginx_proxy_https_enabled %} + location /.well-known/acme-challenge { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-certbot:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; + {% endif %} + } + + location / { + return 301 https://$http_host$request_uri; + } + {% else %} + {{ render_vhost_directives() }} + {% endif %} +} + +{% if matrix_nginx_proxy_https_enabled %} +server { + listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + + server_name {{ matrix_nginx_proxy_proxy_ntfy_hostname }}; + + server_tokens off; + root /dev/null; + + ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_ntfy_hostname }}/fullchain.pem; + ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_ntfy_hostname }}/privkey.pem; + + ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; + {% if matrix_nginx_proxy_ssl_ciphers != '' %} + ssl_ciphers {{ matrix_nginx_proxy_ssl_ciphers }}; + {% endif %} + ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_ntfy_hostname }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + + {{ render_vhost_directives() }} +} +{% endif %} diff --git a/roles/nginx-proxy/templates/nginx/conf.d/matrix-riot-web.conf.j2 b/roles/nginx-proxy/templates/nginx/conf.d/matrix-riot-web.conf.j2 new file mode 100644 index 0000000..9902691 --- /dev/null +++ b/roles/nginx-proxy/templates/nginx/conf.d/matrix-riot-web.conf.j2 @@ -0,0 +1,89 @@ +#jinja2: lstrip_blocks: "True" + +{% macro render_vhost_directives() %} + {% if matrix_nginx_proxy_floc_optout_enabled %} + add_header Permissions-Policy interest-cohort=() always; + {% endif %} + + {% if matrix_nginx_proxy_hsts_preload_enabled %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; + {% else %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + {% endif %} + + add_header X-XSS-Protection "{{ matrix_nginx_proxy_xss_protection }}"; + + {% for configuration_block in matrix_nginx_proxy_proxy_riot_additional_server_configuration_blocks %} + {{- configuration_block }} + {% endfor %} + + location / { + return 301 https://{{ matrix_nginx_proxy_proxy_element_hostname }}$request_uri; + } +{% endmacro %} + +server { + listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + listen [::]:{{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + + + server_name {{ matrix_nginx_proxy_proxy_riot_compat_redirect_hostname }}; + + server_tokens off; + root /dev/null; + + {% if matrix_nginx_proxy_https_enabled %} + location /.well-known/acme-challenge { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-certbot:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; + {% endif %} + } + + location / { + return 301 https://$http_host$request_uri; + } + {% else %} + {{ render_vhost_directives() }} + {% endif %} +} + +{% if matrix_nginx_proxy_https_enabled %} +server { + listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + + server_name {{ matrix_nginx_proxy_proxy_riot_compat_redirect_hostname }}; + + server_tokens off; + root /dev/null; + + ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_riot_compat_redirect_hostname }}/fullchain.pem; + ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_riot_compat_redirect_hostname }}/privkey.pem; + + ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; + {% if matrix_nginx_proxy_ssl_ciphers != '' %} + ssl_ciphers {{ matrix_nginx_proxy_ssl_ciphers }}; + {% endif %} + ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_riot_compat_redirect_hostname }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + + {{ render_vhost_directives() }} +} +{% endif %} diff --git a/roles/nginx-proxy/templates/nginx/conf.d/matrix-sygnal.conf.j2 b/roles/nginx-proxy/templates/nginx/conf.d/matrix-sygnal.conf.j2 new file mode 100644 index 0000000..e3c6a46 --- /dev/null +++ b/roles/nginx-proxy/templates/nginx/conf.d/matrix-sygnal.conf.j2 @@ -0,0 +1,99 @@ +#jinja2: lstrip_blocks: "True" + +{% macro render_vhost_directives() %} + gzip on; + gzip_types text/plain application/json application/javascript text/css image/x-icon font/ttf image/gif; + {% if matrix_nginx_proxy_hsts_preload_enabled %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; + {% else %} + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + {% endif %} + add_header X-XSS-Protection "{{ matrix_nginx_proxy_xss_protection }}"; + add_header X-Content-Type-Options nosniff; + add_header X-Frame-Options DENY; + +{% for configuration_block in matrix_nginx_proxy_proxy_sygnal_additional_server_configuration_blocks %} + {{- configuration_block }} +{% endfor %} + + location / { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-sygnal:6000"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:6000; + {% endif %} + + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For {{ matrix_nginx_proxy_x_forwarded_for }}; + proxy_set_header X-Forwarded-Proto {{ matrix_nginx_proxy_x_forwarded_proto_value }}; + } +{% endmacro %} + +server { + listen {{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + listen [::]:{{ 8080 if matrix_nginx_proxy_enabled else 80 }}; + + server_name {{ matrix_nginx_proxy_proxy_sygnal_hostname }}; + + server_tokens off; + root /dev/null; + + {% if matrix_nginx_proxy_https_enabled %} + location /.well-known/acme-challenge { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "matrix-certbot:8080"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://127.0.0.1:{{ matrix_ssl_lets_encrypt_certbot_standalone_http_port }}; + {% endif %} + } + + location / { + return 301 https://$http_host$request_uri; + } + {% else %} + {{ render_vhost_directives() }} + {% endif %} +} + +{% if matrix_nginx_proxy_https_enabled %} +server { + listen {{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + listen [::]:{{ 8443 if matrix_nginx_proxy_enabled else 443 }} ssl http2; + + server_name {{ matrix_nginx_proxy_proxy_sygnal_hostname }}; + + server_tokens off; + root /dev/null; + + ssl_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_sygnal_hostname }}/fullchain.pem; + ssl_certificate_key {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_sygnal_hostname }}/privkey.pem; + + ssl_protocols {{ matrix_nginx_proxy_ssl_protocols }}; + {% if matrix_nginx_proxy_ssl_ciphers != '' %} + ssl_ciphers {{ matrix_nginx_proxy_ssl_ciphers }}; + {% endif %} + ssl_prefer_server_ciphers {{ matrix_nginx_proxy_ssl_prefer_server_ciphers }}; + + {% if matrix_nginx_proxy_ocsp_stapling_enabled %} + ssl_stapling on; + ssl_stapling_verify on; + ssl_trusted_certificate {{ matrix_ssl_config_dir_path }}/live/{{ matrix_nginx_proxy_proxy_sygnal_hostname }}/chain.pem; + {% endif %} + + {% if matrix_nginx_proxy_ssl_session_tickets_off %} + ssl_session_tickets off; + {% endif %} + ssl_session_cache {{ matrix_nginx_proxy_ssl_session_cache }}; + ssl_session_timeout {{ matrix_nginx_proxy_ssl_session_timeout }}; + + {{ render_vhost_directives() }} +} +{% endif %} diff --git a/roles/nginx-proxy/templates/nginx/conf.d/matrix-synapse.conf.j2 b/roles/nginx-proxy/templates/nginx/conf.d/matrix-synapse.conf.j2 new file mode 100644 index 0000000..4d121e7 --- /dev/null +++ b/roles/nginx-proxy/templates/nginx/conf.d/matrix-synapse.conf.j2 @@ -0,0 +1,71 @@ +#jinja2: lstrip_blocks: "True" + +server { + listen 12080; + {% if matrix_nginx_proxy_enabled %} + server_name {{ matrix_nginx_proxy_proxy_synapse_hostname }}; + {% endif %} + + server_tokens off; + root /dev/null; + + gzip on; + gzip_types text/plain application/json; + + {% for configuration_block in matrix_nginx_proxy_proxy_synapse_additional_server_configuration_blocks %} + {{- configuration_block }} + {% endfor %} + + {# Everything else just goes to the API server ##} + location / { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "{{ matrix_nginx_proxy_proxy_synapse_client_api_addr_with_container }}"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://{{ matrix_nginx_proxy_proxy_synapse_client_api_addr_sans_container }}; + {% endif %} + + proxy_set_header Host $host; + + client_body_buffer_size 25M; + client_max_body_size {{ matrix_nginx_proxy_proxy_matrix_client_api_client_max_body_size_mb }}M; + proxy_max_temp_file_size 0; + } +} + +{% if matrix_nginx_proxy_proxy_synapse_federation_api_enabled %} +server { + listen 12088; + {% if matrix_nginx_proxy_enabled %} + server_name {{ matrix_nginx_proxy_proxy_synapse_hostname }}; + {% endif %} + + server_tokens off; + + root /dev/null; + + gzip on; + gzip_types text/plain application/json; + + location / { + {% if matrix_nginx_proxy_enabled %} + {# Use the embedded DNS resolver in Docker containers to discover the service #} + resolver {{ matrix_nginx_proxy_http_level_resolver }} valid=5s; + set $backend "{{ matrix_nginx_proxy_proxy_synapse_federation_api_addr_with_container }}"; + proxy_pass http://$backend; + {% else %} + {# Generic configuration for use outside of our container setup #} + proxy_pass http://{{ matrix_nginx_proxy_proxy_synapse_federation_api_addr_sans_container }}; + {% endif %} + + proxy_set_header Host $host; + + client_body_buffer_size 25M; + client_max_body_size {{ matrix_nginx_proxy_proxy_matrix_federation_api_client_max_body_size_mb }}M; + proxy_max_temp_file_size 0; + } +} +{% endif %} diff --git a/roles/nginx-proxy/templates/nginx/conf.d/nginx-http.conf.j2 b/roles/nginx-proxy/templates/nginx/conf.d/nginx-http.conf.j2 new file mode 100644 index 0000000..beea6af --- /dev/null +++ b/roles/nginx-proxy/templates/nginx/conf.d/nginx-http.conf.j2 @@ -0,0 +1,14 @@ +#jinja2: lstrip_blocks: "True" +# The default is aligned to the CPU's cache size, +# which can sometimes be too low to handle our 2 vhosts (Synapse and Element). +# +# Thus, we ensure a larger bucket size value is used. +server_names_hash_bucket_size 64; + +{% if matrix_nginx_proxy_http_level_resolver %} + resolver {{ matrix_nginx_proxy_http_level_resolver }}; +{% endif %} + +{% for configuration_block in matrix_nginx_proxy_proxy_http_additional_server_configuration_blocks %} + {{- configuration_block }} +{% endfor %} diff --git a/roles/nginx-proxy/templates/nginx/nginx.conf.j2 b/roles/nginx-proxy/templates/nginx/nginx.conf.j2 new file mode 100644 index 0000000..6b56878 --- /dev/null +++ b/roles/nginx-proxy/templates/nginx/nginx.conf.j2 @@ -0,0 +1,77 @@ +#jinja2: lstrip_blocks: "True" +# This is a custom nginx configuration file that we use in the container (instead of the default one), +# because it allows us to run nginx with a non-root user. +# +# For this to work, the default vhost file (`/etc/nginx/conf.d/default.conf`) also needs to be removed. +# +# The following changes have been done compared to a default nginx configuration file: +# - various temp paths are changed to `/tmp`, so that a non-root user can write to them +# - the `user` directive was removed, as we don't want nginx to switch users + +worker_processes {{ matrix_nginx_proxy_worker_processes }}; +error_log /var/log/nginx/error.log warn; +pid /tmp/nginx.pid; +{% for configuration_block in matrix_nginx_proxy_proxy_additional_configuration_blocks %} + {{- configuration_block }} +{% endfor %} + +events { + worker_connections {{ matrix_nginx_proxy_worker_connections }}; +{% for configuration_block in matrix_nginx_proxy_proxy_event_additional_configuration_blocks %} + {{- configuration_block }} +{% endfor %} +} + + +http { + proxy_temp_path /tmp/proxy_temp; + client_body_temp_path /tmp/client_temp; + fastcgi_temp_path /tmp/fastcgi_temp; + uwsgi_temp_path /tmp/uwsgi_temp; + scgi_temp_path /tmp/scgi_temp; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + {% if matrix_nginx_proxy_access_log_enabled %} + access_log /var/log/nginx/access.log main; + {% endif %} + + {% if matrix_nginx_proxy_access_log_syslog_integration_enabled %} + log_format prometheus_fmt 'matrix-nginx-proxy $server_name - $upstream_addr - $remote_addr - $remote_user [$time_local] ' + '$host "$request" ' + '$status "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log syslog:server={{ matrix_nginx_proxy_access_log_syslog_integration_server_port }},tag=matrix_nginx_proxy prometheus_fmt; + {% endif %} + + {% if not matrix_nginx_proxy_access_log_enabled and not matrix_nginx_proxy_access_log_syslog_integration_enabled %} + access_log off; + {% endif %} + + proxy_connect_timeout {{ matrix_nginx_proxy_connect_timeout }}; + proxy_send_timeout {{ matrix_nginx_proxy_send_timeout }}; + proxy_read_timeout {{ matrix_nginx_proxy_read_timeout }}; + send_timeout {{ matrix_nginx_send_timeout }}; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + server_tokens off; + + #gzip on; + {# Map directive needed for proxied WebSocket upgrades #} + map $http_upgrade $connection_upgrade { + default upgrade; + '' close; + } + + include /etc/nginx/conf.d/*.conf; +} diff --git a/roles/nginx-proxy/templates/systemd/matrix-nginx-proxy.service.j2 b/roles/nginx-proxy/templates/systemd/matrix-nginx-proxy.service.j2 new file mode 100644 index 0000000..0a7e905 --- /dev/null +++ b/roles/nginx-proxy/templates/systemd/matrix-nginx-proxy.service.j2 @@ -0,0 +1,62 @@ +#jinja2: lstrip_blocks: "True" +[Unit] +Description=Matrix nginx-proxy server +{% for service in matrix_nginx_proxy_systemd_required_services_list %} +Requires={{ service }} +After={{ service }} +{% endfor %} +{% for service in matrix_nginx_proxy_systemd_wanted_services_list %} +Wants={{ service }} +{% endfor %} +DefaultDependencies=no + +[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 }} kill matrix-nginx-proxy 2>/dev/null || true' +ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-nginx-proxy 2>/dev/null || true' + +ExecStart={{ devture_systemd_docker_base_host_command_docker }} run --rm --name matrix-nginx-proxy \ + --log-driver=none \ + --user={{ matrix_user_uid }}:{{ matrix_user_gid }} \ + --cap-drop=ALL \ + --read-only \ + --tmpfs=/tmp:rw,noexec,nosuid,size={{ matrix_nginx_proxy_tmp_directory_size_mb }}m \ + --network={{ matrix_docker_network }} \ + {% if matrix_nginx_proxy_container_http_host_bind_port %} + -p {{ matrix_nginx_proxy_container_http_host_bind_port }}:8080 \ + {% endif %} + {% if matrix_nginx_proxy_https_enabled and matrix_nginx_proxy_container_https_host_bind_port %} + -p {{ matrix_nginx_proxy_container_https_host_bind_port }}:8443 \ + {% endif %} + {% if matrix_nginx_proxy_proxy_matrix_federation_api_enabled and matrix_nginx_proxy_container_federation_host_bind_port %} + -p {{ matrix_nginx_proxy_container_federation_host_bind_port }}:{{ matrix_nginx_proxy_proxy_matrix_federation_port }} \ + {% endif %} + --mount type=bind,src={{ matrix_nginx_proxy_base_path }}/nginx.conf,dst=/etc/nginx/nginx.conf,ro \ + --mount type=bind,src={{ matrix_nginx_proxy_data_path }},dst={{ matrix_nginx_proxy_data_path_in_container }},ro \ + --mount type=bind,src={{ matrix_nginx_proxy_confd_path }},dst=/etc/nginx/conf.d,ro \ + {% if matrix_ssl_retrieval_method != 'none' %} + --mount type=bind,src={{ matrix_ssl_config_dir_path }},dst={{ matrix_ssl_config_dir_path }},ro \ + {% endif %} + --mount type=bind,src={{ matrix_static_files_base_path }},dst={{ matrix_static_files_base_path }},ro \ + {% for volume in matrix_nginx_proxy_container_additional_volumes %} + -v {{ volume.src }}:{{ volume.dst }}:{{ volume.options }} \ + {% endfor %} + {% for arg in matrix_nginx_proxy_container_extra_arguments %} + {{ arg }} \ + {% endfor %} + {{ matrix_nginx_proxy_docker_image }} + +{% for network in matrix_nginx_proxy_container_additional_networks %} +ExecStartPost={{ devture_systemd_docker_base_host_command_sh }} -c 'container_name=matrix-nginx-proxy; network_name={{ network }}; attempt=0; while [ $attempt -le 29 ]; do attempt=$(( $attempt + 1 )); if [ "`{{ devture_systemd_docker_base_host_command_docker }} inspect -f {{ '{{.State.Running}}' }} $container_name 2> /dev/null`" = "true" ]; then break; fi; sleep 1; done; {{ devture_systemd_docker_base_host_command_docker }} network connect $network_name $container_name' +{% endfor %} + +ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} kill matrix-nginx-proxy 2>/dev/null || true' +ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-nginx-proxy 2>/dev/null || true' +ExecReload={{ devture_systemd_docker_base_host_command_docker }} exec matrix-nginx-proxy /usr/sbin/nginx -s reload +Restart=always +RestartSec=30 +SyslogIdentifier=matrix-nginx-proxy + +[Install] +WantedBy=multi-user.target diff --git a/roles/nginx-proxy/templates/systemd/matrix-ssl-lets-encrypt-certificates-renew.service.j2 b/roles/nginx-proxy/templates/systemd/matrix-ssl-lets-encrypt-certificates-renew.service.j2 new file mode 100644 index 0000000..b2f07ac --- /dev/null +++ b/roles/nginx-proxy/templates/systemd/matrix-ssl-lets-encrypt-certificates-renew.service.j2 @@ -0,0 +1,7 @@ +[Unit] +Description=Renews Let's Encrypt SSL certificates + +[Service] +Type=oneshot +Environment="HOME={{ devture_systemd_docker_base_systemd_unit_home_path }}" +ExecStart={{ matrix_ssl_bin_dir_path }}/lets-encrypt-certificates-renew diff --git a/roles/nginx-proxy/templates/systemd/matrix-ssl-lets-encrypt-certificates-renew.timer.j2 b/roles/nginx-proxy/templates/systemd/matrix-ssl-lets-encrypt-certificates-renew.timer.j2 new file mode 100644 index 0000000..b1e1c21 --- /dev/null +++ b/roles/nginx-proxy/templates/systemd/matrix-ssl-lets-encrypt-certificates-renew.timer.j2 @@ -0,0 +1,10 @@ +[Unit] +Description=Renews Let's Encrypt SSL certificates periodically + +[Timer] +Unit=matrix-ssl-lets-encrypt-certificates-renew.service +OnCalendar=*-*-* 04:00:00 +RandomizedDelaySec=2h + +[Install] +WantedBy=timers.target diff --git a/roles/nginx-proxy/templates/systemd/matrix-ssl-nginx-proxy-reload.service.j2 b/roles/nginx-proxy/templates/systemd/matrix-ssl-nginx-proxy-reload.service.j2 new file mode 100644 index 0000000..025c5e2 --- /dev/null +++ b/roles/nginx-proxy/templates/systemd/matrix-ssl-nginx-proxy-reload.service.j2 @@ -0,0 +1,6 @@ +[Unit] +Description=Reloads matrix-nginx-proxy so that new SSL certificates can kick in + +[Service] +Type=oneshot +ExecStart={{ devture_systemd_docker_base_host_command_systemctl }} reload matrix-nginx-proxy.service diff --git a/roles/nginx-proxy/templates/systemd/matrix-ssl-nginx-proxy-reload.timer.j2 b/roles/nginx-proxy/templates/systemd/matrix-ssl-nginx-proxy-reload.timer.j2 new file mode 100644 index 0000000..09cb6da --- /dev/null +++ b/roles/nginx-proxy/templates/systemd/matrix-ssl-nginx-proxy-reload.timer.j2 @@ -0,0 +1,10 @@ +[Unit] +Description=Reloads matrix-nginx-proxy periodically so that new SSL certificates can kick in + +[Timer] +Unit=matrix-ssl-nginx-proxy-reload.service +OnCalendar=*-*-* 06:30:00 +RandomizedDelaySec=1h + +[Install] +WantedBy=timers.target diff --git a/roles/nginx-proxy/vars/main.yml b/roles/nginx-proxy/vars/main.yml new file mode 100644 index 0000000..34abf19 --- /dev/null +++ b/roles/nginx-proxy/vars/main.yml @@ -0,0 +1,26 @@ +--- + +# Tells whether this role had executed or not. Toggled to `true` during runtime. +matrix_nginx_proxy_role_executed: false + +matrix_ssl_renewal_systemd_units_list: + - name: matrix-ssl-lets-encrypt-certificates-renew.service + applicable: "{{ matrix_ssl_retrieval_method == 'lets-encrypt' }}" + enableable: false + priority: 5000 + groups: ['matrix', 'nginx', 'ssl', 'reverse-proxies'] + - name: matrix-ssl-lets-encrypt-certificates-renew.timer + applicable: "{{ matrix_ssl_retrieval_method == 'lets-encrypt' }}" + enableable: true + priority: 5000 + groups: ['matrix', 'nginx', 'ssl', 'reverse-proxies'] + - name: matrix-ssl-nginx-proxy-reload.service + applicable: "{{ matrix_ssl_retrieval_method == 'lets-encrypt' and matrix_nginx_proxy_enabled | bool }}" + enableable: false + priority: 5000 + groups: ['matrix', 'nginx', 'ssl', 'reverse-proxies'] + - name: matrix-ssl-nginx-proxy-reload.timer + applicable: "{{ matrix_ssl_retrieval_method == 'lets-encrypt' and matrix_nginx_proxy_enabled | bool }}" + enableable: true + priority: 5000 + groups: ['matrix', 'nginx', 'ssl', 'reverse-proxies'] diff --git a/setup.yml b/setup.yml new file mode 100644 index 0000000..56c050e --- /dev/null +++ b/setup.yml @@ -0,0 +1,193 @@ +--- +- name: "Set up a All servers" + hosts: "{{ target_all if target_all is defined else 'all' }}" + become: true + + roles: + # Most of the roles below are not distributed with the playbook, but downloaded separately using `ansible-galaxy` via the `make roles` command (see `Makefile`). + - role: galaxy/com.devture.ansible.role.playbook_help + + - role: galaxy/com.devture.ansible.role.systemd_docker_base + + - role: matrix/matrix_playbook_migration + + - when: matrix_playbook_docker_installation_enabled | bool + role: galaxy/geerlingguy.docker + vars: + docker_install_compose: false + tags: + - setup-docker + - setup-all + - when: matrix_playbook_docker_installation_enabled | bool + role: base/docker + tags: + - setup-docker + - setup-all + + - when: devture_docker_sdk_for_python_installation_enabled | bool + role: galaxy/com.devture.ansible.role.docker_sdk_for_python + tags: + - setup-docker + - setup-all + + - when: devture_timesync_installation_enabled | bool + role: galaxy/com.devture.ansible.role.timesync + tags: + - setup-timesync + - setup-all + +- name: "Set up a Keycloak servers common" + hosts: "{{ target_keycloak if target_keycloak is defined else 'keycloak_servers' }}" + become: true + tasks: + - ansible.builtin.include_tasks: "roles/matrix/matrix-base/tasks/setup_matrix_user.yml" + tags: + - setup-all + - install-all + + +- name: "Set up a Keycloak servers" + hosts: "{{ target_keycloak if target_keycloak is defined else 'keycloak_servers' }}" + become: true + roles: + - keycloak/keycloak_base + - role: galaxy/com.devture.ansible.role.playbook_help + - role: galaxy/com.devture.ansible.role.systemd_docker_base + - matrix/matrix-backup-borg + + tags: + - setup-all + - install-all + + +- name: "Set up a Matrix server" + hosts: "{{ target if target is defined else 'matrix_servers' }}" + become: true + roles: + # Most of the roles below are not distributed with the playbook, but downloaded separately using `ansible-galaxy` via the `make roles` command (see `Makefile`). + - role: galaxy/com.devture.ansible.role.playbook_help + + - role: galaxy/com.devture.ansible.role.systemd_docker_base + + - role: matrix/matrix_playbook_migration + + + - matrix/matrix-base + - matrix/matrix-dynamic-dns + - matrix/matrix-mailer + + - role: galaxy/com.devture.ansible.role.postgres + + - matrix/matrix-redis + - matrix/matrix-corporal + - matrix/matrix-bridge-appservice-discord + - matrix/matrix-bridge-appservice-slack + - matrix/matrix-bridge-appservice-webhooks + - matrix/matrix-bridge-appservice-irc + - matrix/matrix-bridge-appservice-kakaotalk + - matrix/matrix-bridge-beeper-linkedin + - matrix/matrix-bridge-go-skype-bridge + - matrix/matrix-bridge-mautrix-facebook + - matrix/matrix-bridge-mautrix-twitter + - matrix/matrix-bridge-mautrix-hangouts + - matrix/matrix-bridge-mautrix-googlechat + - matrix/matrix-bridge-mautrix-instagram + - matrix/matrix-bridge-mautrix-signal + - matrix/matrix-bridge-mautrix-telegram + - matrix/matrix-bridge-mautrix-whatsapp + - matrix/matrix-bridge-mautrix-discord + - matrix/matrix-bridge-mx-puppet-discord + - matrix/matrix-bridge-mx-puppet-groupme + - matrix/matrix-bridge-mx-puppet-steam + - matrix/matrix-bridge-mx-puppet-slack + - matrix/matrix-bridge-mx-puppet-twitter + - matrix/matrix-bridge-mx-puppet-instagram + - matrix/matrix-bridge-sms + - matrix/matrix-bridge-heisenbridge + - matrix/matrix-bridge-hookshot + - matrix/matrix-bot-matrix-reminder-bot + - matrix/matrix-bot-matrix-registration-bot + - matrix/matrix-bot-maubot + - matrix/matrix-bot-buscarron + - matrix/matrix-bot-honoroit + - matrix/matrix-bot-postmoogle + - matrix/matrix-bot-go-neb + - matrix/matrix-bot-mjolnir + - matrix/matrix-cactus-comments + - matrix/matrix-synapse + - matrix/matrix-synapse-reverse-proxy-companion + - matrix/matrix-dendrite + - matrix/matrix-conduit + - matrix/matrix-synapse-admin + - matrix/matrix-prometheus-node-exporter + - matrix/matrix-prometheus-postgres-exporter + - matrix/matrix-prometheus-nginxlog-exporter + - matrix/matrix-prometheus + - matrix/matrix-grafana + - matrix/matrix-registration + - matrix/matrix-client-element + - matrix/matrix-client-hydrogen + - matrix/matrix-client-cinny + - matrix/matrix-jitsi + - matrix/matrix-ldap-registration-proxy + - matrix/matrix-ma1sd + - matrix/matrix-dimension + - matrix/matrix-etherpad + - matrix/matrix-email2matrix + - matrix/matrix-sygnal + - matrix/matrix-ntfy + - nginx-proxy + - matrix/matrix-coturn + - matrix/matrix-aux + + - role: galaxy/com.devture.ansible.role.postgres_backup + + - matrix/matrix-backup-borg + + - matrix/matrix-user-creator + - matrix/matrix-common-after + + - when: devture_systemd_service_manager_enabled | bool + role: galaxy/com.devture.ansible.role.systemd_service_manager + vars: + devture_systemd_service_manager_services_list: | + {{ + ([{'name': 'matrix-nginx-proxy.service', 'priority': 1000, 'groups': ['matrix', 'nginx', 'reverse-proxies']}] if matrix_nginx_proxy_enabled else []) + }} + + - role: keycloak/keycloak_custom + + + - when: devture_systemd_service_manager_enabled | bool + vars: + devture_systemd_service_manager_services_list: "{{ devture_systemd_service_manager_services_list_auto + devture_systemd_service_manager_services_list_additional }}" + role: galaxy/com.devture.ansible.role.systemd_service_manager + + # This is pretty much last, because we want it to better serve as a "last known good configuration". + # See: https://github.com/spantaleev/matrix-docker-ansible-deploy/pull/2217#issuecomment-1301487601 + - when: devture_playbook_state_preserver_enabled | bool + role: galaxy/com.devture.ansible.role.playbook_state_preserver + tags: + - setup-all + - install-all + + - role: galaxy/com.devture.ansible.role.playbook_runtime_messages + + +- name: "Set up a HA Gitlab Sheared Storage servers" + hosts: + - "{{ target_drbd_primary if target_drbd_primary is defined else 'drbd_primary' }}" + - "{{ target_gitlab if target_gitlab is defined else 'drbd_secondary' }}" + become: true + debugger: on_failed + roles: + - gitlab/gitlab_drbd_storage + + +- name: "Set up a HA Gitlab servers " + hosts: + - "{{ target_gitlab if target_gitlab is defined else 'gitlab_servers' }}" + become: true + debugger: on_failed + roles: + - gitlab/gitlab_main