From 0c9178f243e6b3aea718d654a131fc5cde8b7446 Mon Sep 17 00:00:00 2001
From: Adar Nimrod <nimrod@shore.co.il>
Date: Sat, 16 Dec 2023 11:15:08 +0200
Subject: [PATCH] Matrix: Compose setup.

---
 .gitlab-ci.yml                            |  26 ++++
 .pre-commit-config.yaml                   |   4 +-
 Compose/matrix/.env                       |   1 +
 Compose/matrix/README.md                  |   4 +
 Compose/matrix/docker-compose.yaml        |  50 ++++++++
 Compose/matrix/synapse/.dockerignore      |   1 +
 Compose/matrix/synapse/Dockerfile         |   6 +
 Compose/matrix/synapse/README.md          |   4 +
 Compose/matrix/synapse/entrypoint_wrapper |  19 +++
 Compose/matrix/synapse/homeserver.yaml    | 140 ++++++++++++++++++++++
 10 files changed, 254 insertions(+), 1 deletion(-)
 create mode 100644 Compose/matrix/.env
 create mode 100644 Compose/matrix/README.md
 create mode 100644 Compose/matrix/docker-compose.yaml
 create mode 100644 Compose/matrix/synapse/.dockerignore
 create mode 100644 Compose/matrix/synapse/Dockerfile
 create mode 100644 Compose/matrix/synapse/README.md
 create mode 100755 Compose/matrix/synapse/entrypoint_wrapper
 create mode 100644 Compose/matrix/synapse/homeserver.yaml

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 2a6a021..5d3c14c 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -101,3 +101,29 @@ web-proxy host01 run:
     WORKDIR: Compose/web-proxy/host01
   when: manual
   rules: *compose-rules
+
+# Matrix Compose deployment.
+
+matrix-build:
+  extends: .compose-build
+  tags: &matrix-tags [host01.shore.co.il]
+  variables: &matrix-vars
+    WORKDIR: Compose/matrix
+
+matrix-pull:
+  extends: .compose-pull
+  tags: *matrix-tags
+  variables: *matrix-vars
+
+matrix-run:
+  extends: .compose-run
+  tags: *matrix-tags
+  variables: *matrix-vars
+  needs:
+    - job: matrix-build
+    - job: matrix-pull
+  after_script:
+    # yamllint disable rule:line-length
+    - docker-compose exec synapse sh -c "while [ ! -f /conf/homeserver.yaml ]; do echo Waiting for the config file.; sleep 1; done"
+    - docker-compose exec synapse update_synapse_database --run-background-updates --database-config /conf/homeserver.yaml
+    # yamllint enable rule:line-length
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index c234cb7..4bad376 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -12,7 +12,8 @@ repos:
       - id: check-toml
       - id: check-xml
       - id: check-yaml
-        exclude: ^Ansible/roles/(wap|router)/vars/main\.yaml$
+        # yamllint disable-line rule:line-length
+        exclude: ^Ansible/roles/(wap|router)/vars/main\.yaml$|^Compose/matrix/synapse/homeserver\.yaml$
       - id: detect-private-key
       - id: end-of-file-fixer
       - id: trailing-whitespace
@@ -50,6 +51,7 @@ repos:
     rev: v1.26.3
     hooks:
       - id: yamllint
+        exclude: ^Compose/matrix/synapse/homeserver\.yaml$$
 
   - repo: https://github.com/executablebooks/mdformat.git
     rev: 0.7.10
diff --git a/Compose/matrix/.env b/Compose/matrix/.env
new file mode 100644
index 0000000..9b5468b
--- /dev/null
+++ b/Compose/matrix/.env
@@ -0,0 +1 @@
+COMPOSE_PROJECT_NAME=matrix
diff --git a/Compose/matrix/README.md b/Compose/matrix/README.md
new file mode 100644
index 0000000..7805c7c
--- /dev/null
+++ b/Compose/matrix/README.md
@@ -0,0 +1,4 @@
+# Matrix
+
+Deploy a Matrix homeserver using
+[Synapse](https://element-hq.github.io/synapse/latest/).
diff --git a/Compose/matrix/docker-compose.yaml b/Compose/matrix/docker-compose.yaml
new file mode 100644
index 0000000..c955fde
--- /dev/null
+++ b/Compose/matrix/docker-compose.yaml
@@ -0,0 +1,50 @@
+---
+version: '3.5'
+
+services:
+  postgres:
+    environment:
+      POSTGRES_DB: &postgres_db synapse
+      POSTGRES_INITDB_ARGS: --encoding=UTF-8 --lc-collate=C --lc-ctype=C
+      POSTGRES_PASSWORD: &postgres_password "${SYNAPSE_DB_PASS}"
+      POSTGRES_USER: &postgres_user synapse
+    image: registry.shore.co.il/postgres
+    restart: always
+    volumes:
+      - postgres:/var/lib/postgresql/data
+
+  synapse:
+    build:
+      context: synapse/
+    depends_on:
+      - postgres
+    environment:
+      LDAP_URI: ldap://ldap:389
+      POSTGRES_DB: *postgres_db
+      POSTGRES_HOST: postgres
+      POSTGRES_PASSWORD: *postgres_password
+      POSTGRES_USER: *postgres_user
+      SYNAPSE_SERVER_NAME: shore.co.il
+      SIGNING_KEY: "${SYNAPSE_SIGNING_KEY}"
+      SYNAPSE_ADMIN_CONTACT: "mailto:postmaster@shore.co.il"
+      SYNAPSE_LOG_LEVEL: WARNING
+      SYNAPSE_MACAROON_SECRET_KEY: "${SYNAPSE_MACAROON_SECRET_KEY}"
+      # yamllint disable-line rule:line-length
+      SYNAPSE_REGISTRATION_SHARED_SECRET: "${SYNAPSE_REGISTRATION_SHARED_SECRET}"
+      SYNAPSE_SMTP_HOST: smtp
+    restart: always
+    volumes:
+      - data:/data
+      - _run_slapd:/run/slapd
+
+volumes:
+  data:
+  postgres:
+  _run_slapd:
+    external: true
+    name: run_slapd
+
+networks:
+  default:
+    name: shore
+    external: true
diff --git a/Compose/matrix/synapse/.dockerignore b/Compose/matrix/synapse/.dockerignore
new file mode 100644
index 0000000..dd44972
--- /dev/null
+++ b/Compose/matrix/synapse/.dockerignore
@@ -0,0 +1 @@
+*.md
diff --git a/Compose/matrix/synapse/Dockerfile b/Compose/matrix/synapse/Dockerfile
new file mode 100644
index 0000000..f0cd569
--- /dev/null
+++ b/Compose/matrix/synapse/Dockerfile
@@ -0,0 +1,6 @@
+FROM docker.io/matrixdotorg/synapse:v1.98.0
+ENV SYNAPSE_CONFIG_DIR=/conf
+ENV SYNAPSE_REPORT_STATS=yes
+COPY --chown=root:root entrypoint_wrapper /
+COPY --chown=root:root homeserver.yaml /conf/
+ENTRYPOINT ["/entrypoint_wrapper"]
diff --git a/Compose/matrix/synapse/README.md b/Compose/matrix/synapse/README.md
new file mode 100644
index 0000000..fe8760a
--- /dev/null
+++ b/Compose/matrix/synapse/README.md
@@ -0,0 +1,4 @@
+# Synapse
+
+The Synapse Matrix homeserver. Tweaked to generate the configuration and
+secret files from environment variables.
diff --git a/Compose/matrix/synapse/entrypoint_wrapper b/Compose/matrix/synapse/entrypoint_wrapper
new file mode 100755
index 0000000..7c5c146
--- /dev/null
+++ b/Compose/matrix/synapse/entrypoint_wrapper
@@ -0,0 +1,19 @@
+#!/bin/sh
+set -eux
+
+# We wrap the default entrypoint script and generate the configuration file and
+# other secret files from environment variables, but only if we're running the
+# homeserver.
+if [ "$#" -eq 0 ] || [ "$1" = run ]
+then
+    if [ -n "${SIGNING_KEY:-}" ]
+    then
+        echo "$SIGNING_KEY" > "/conf/${SYNAPSE_SERVER_NAME}.signing.key"
+        chmod 644 "/conf/${SYNAPSE_SERVER_NAME}.signing.key"
+    fi
+    /start.py migrate_config
+    cat /conf/homeserver.yaml
+    python3 -m synapse.config -c /conf/homeserver.yaml
+fi
+
+exec /start.py "$@"
diff --git a/Compose/matrix/synapse/homeserver.yaml b/Compose/matrix/synapse/homeserver.yaml
new file mode 100644
index 0000000..247c028
--- /dev/null
+++ b/Compose/matrix/synapse/homeserver.yaml
@@ -0,0 +1,140 @@
+# vim:ft=yaml
+---
+# For more information on how to configure Synapse, including a complete accounting of
+# each option, go to
+# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html
+# For the original version of this file go to
+# https://github.com/element-hq/synapse/blob/master/docker/conf/homeserver.yaml
+
+server_name: "{{ SYNAPSE_SERVER_NAME }}"
+pid_file: /homeserver.pid
+web_client: false
+soft_file_limit: 0
+log_config: "{{ SYNAPSE_LOG_CONFIG }}"
+admin_contact: "{{ SYNAPSE_ADMIN_CONTACT }}"
+registration_shared_secret: "{{ SYNAPSE_REGISTRATION_SHARED_SECRET }}"
+enable_registration: false
+
+## Ports ##
+
+listeners:
+  - port: {{ SYNAPSE_HTTP_PORT or 8008 }}
+    tls: false
+    bind_addresses: ['::']
+    type: http
+    x_forwarded: true
+    resources:
+      - names: [client]
+        compress: true
+      - names: [federation]
+        compress: false
+
+## Database ##
+
+database:
+  name: "psycopg2"
+  args:
+    user: '{{ POSTGRES_USER or "synapse" }}'
+    password: '{{ POSTGRES_PASSWORD }}'
+    database: '{{ POSTGRES_DB or "synapse" }}'
+    host: '{{ POSTGRES_HOST or "db" }}'
+    port: '{{ POSTGRES_PORT or "5432" }}'
+    cp_min: {{ POSTGRES_CP_MIN or 5 }}
+    cp_max: {{ POSTGRES_CP_MAX or 10 }}
+
+## email ##
+
+email:
+  notif_from: "Your Friendly %(app)s homeserver <noreply@{{ SYNAPSE_SERVER_NAME }}>"
+  smtp_host: "{{ SYNAPSE_SMTP_HOST }}"
+  smtp_pass: "{{ SYNAPSE_SMTP_PASS }}"
+  smtp_port: "{{ SYNAPSE_SMTP_PORT }}"
+  smtp_user: "{{ SYNAPSE_SMTP_USER }}"
+
+## Performance ##
+
+event_cache_size: '{{ SYNAPSE_EVENT_CACHE_SIZE or "10K" }}'
+
+## Ratelimiting ##
+
+rc_messages_per_second: 0.2
+rc_message_burst_count: 10.0
+federation_rc_window_size: 1000
+federation_rc_sleep_limit: 10
+federation_rc_sleep_delay: 500
+federation_rc_reject_limit: 50
+federation_rc_concurrent: 3
+
+## Files ##
+
+media_store_path: "/data/media"
+max_upload_size: '{{ SYNAPSE_MAX_UPLOAD_SIZE or "50M" }}'
+max_image_pixels: "32M"
+dynamic_thumbnails: false
+
+# List of thumbnail to precalculate when an image is uploaded.
+thumbnail_sizes:
+- width: 32
+  height: 32
+  method: crop
+- width: 96
+  height: 96
+  method: crop
+- width: 320
+  height: 240
+  method: scale
+- width: 640
+  height: 480
+  method: scale
+- width: 800
+  height: 600
+  method: scale
+
+url_preview_enabled: false
+max_spider_size: "10M"
+
+
+## Metrics ###
+
+enable_metrics: '{{ SYNAPSE_REPORT_STATS.lower() == "yes" }}'
+report_stats: '{{ SYNAPSE_REPORT_STATS.lower() == "yes" }}'
+
+## API Configuration ##
+
+{% if SYNAPSE_APPSERVICES %}
+app_service_config_files:
+{% for appservice in SYNAPSE_APPSERVICES %}
+    - "{{ appservice }}"
+{% endfor %}
+{% endif %}
+
+macaroon_secret_key: "{{ SYNAPSE_MACAROON_SECRET_KEY }}"
+expire_access_token: false
+
+## Signing Keys ##
+
+signing_key_path: "/conf/{{ SYNAPSE_SERVER_NAME }}.signing.key"
+old_signing_keys: {}
+key_refresh_interval: "1d" # 1 Day.
+
+# The trusted servers to download signing keys from.
+suppress_key_server_warning: true
+trusted_key_servers:
+  - server_name: matrix.org
+    verify_keys:
+      "ed25519:auto": "Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw"  # pragma: allowlist secret
+
+password_config:
+   enabled: true
+
+modules:
+  - module: "ldap_auth_provider.LdapAuthProviderModule"
+    config:
+      enabled: true
+      uri: '{{ LDAP_URI or "ldapi:///run/slapd/ldapi" }}'
+      start_tls: {{ LDAP_TLS or False }}
+      base: '{{ LDAP_BASE_DN or "ou=People,dc=shore,dc=co,dc=il" }}'
+      attributes:
+        uid: "cn"
+        mail: "mail"
+        name: "givenName"
-- 
GitLab