diff --git a/cluster/prod/app/garage/deploy/garage.hcl b/cluster/prod/app/garage/deploy/garage.hcl index 8d4ee6a..bbaaec1 100644 --- a/cluster/prod/app/garage/deploy/garage.hcl +++ b/cluster/prod/app/garage/deploy/garage.hcl @@ -8,6 +8,11 @@ job "garage" { value = "amd64" } + update { + max_parallel = 1 + min_healthy_time = "60s" + } + group "garage" { network { port "s3" { static = 3900 } @@ -45,7 +50,7 @@ job "garage" { } resources { - memory = 1500 + memory = 1000 cpu = 1000 } diff --git a/cluster/prod/app/matrix/build/docker-compose.yml b/cluster/prod/app/matrix/build/docker-compose.yml new file mode 100644 index 0000000..de56bdc --- /dev/null +++ b/cluster/prod/app/matrix/build/docker-compose.yml @@ -0,0 +1,23 @@ +version: '3.4' +services: + # Instant Messaging + riot: + build: + context: ./riotweb + args: + # https://github.com/vector-im/riot-web/releases + VERSION: 1.11.3 + image: superboum/amd64_riotweb:v31 + + synapse: + build: + context: ./matrix-synapse + args: + # https://github.com/matrix-org/synapse/releases + VERSION: 1.65.0 + # https://github.com/matrix-org/synapse-s3-storage-provider/commits/main + # Update with the latest commit on main each time you update the synapse version + # otherwise synapse may fail to launch due to incompatibility issues + # see this issue for an example: https://github.com/matrix-org/synapse-s3-storage-provider/issues/64 + S3_VERSION: ffd3fa477321608e57d27644197e721965e0e858 + image: superboum/amd64_synapse:v54 diff --git a/cluster/prod/app/matrix/build/matrix-synapse/Dockerfile b/cluster/prod/app/matrix/build/matrix-synapse/Dockerfile new file mode 100644 index 0000000..d410779 --- /dev/null +++ b/cluster/prod/app/matrix/build/matrix-synapse/Dockerfile @@ -0,0 +1,52 @@ +FROM amd64/debian:buster as builder + +ARG VERSION +ARG S3_VERSION +RUN apt-get update && \ + apt-get -qq -y full-upgrade && \ + apt-get install -y \ + python3 \ + python3-pip \ + python3-dev \ + python3-setuptools \ + libffi-dev \ + build-essential \ + libssl-dev \ + libjpeg-dev \ + libjpeg62-turbo-dev \ + libxml2-dev \ + zlib1g-dev \ + # postgresql-dev \ + libpq-dev \ + virtualenv \ + libxslt1-dev \ + git && \ + virtualenv /root/matrix-env -p /usr/bin/python3 && \ + . /root/matrix-env/bin/activate && \ + pip3 install \ + https://github.com/matrix-org/synapse/archive/v${VERSION}.tar.gz#egg=matrix-synapse[matrix-synapse-ldap3,postgres,resources.consent,saml2,url_preview] && \ + pip3 install \ + git+https://github.com/matrix-org/synapse-s3-storage-provider.git@${S3_VERSION} + +FROM amd64/debian:buster + +RUN apt-get update && \ + apt-get -qq -y full-upgrade && \ + apt-get install -y \ + python3 \ + python3-distutils \ + libffi6 \ + libjpeg62-turbo \ + libssl1.1 \ + libxslt1.1 \ + libpq5 \ + zlib1g \ + libjemalloc2 \ + ca-certificates + +ENV LD_PRELOAD /usr/lib/x86_64-linux-gnu/libjemalloc.so.2 +COPY --from=builder /root/matrix-env /root/matrix-env +COPY matrix-s3-async /usr/local/bin/matrix-s3-async +COPY entrypoint.sh /usr/local/bin/entrypoint + +ENTRYPOINT ["/usr/local/bin/entrypoint"] diff --git a/cluster/prod/app/matrix/build/matrix-synapse/entrypoint.sh b/cluster/prod/app/matrix/build/matrix-synapse/entrypoint.sh new file mode 100755 index 0000000..b93a702 --- /dev/null +++ b/cluster/prod/app/matrix/build/matrix-synapse/entrypoint.sh @@ -0,0 +1,3 @@ +#!/bin/sh +. /root/matrix-env/bin/activate +exec "$@" diff --git a/cluster/prod/app/matrix/build/matrix-synapse/matrix-s3-async b/cluster/prod/app/matrix/build/matrix-synapse/matrix-s3-async new file mode 100755 index 0000000..e435144 --- /dev/null +++ b/cluster/prod/app/matrix/build/matrix-synapse/matrix-s3-async @@ -0,0 +1,16 @@ +#!/bin/bash + +cat > database.yaml < + +# Used to enable access token expiration. +expire_access_token: False + +## Signing Keys ## + +# Path to the signing key to sign messages with +signing_key_path: "/etc/matrix-synapse/homeserver.signing.key" + +# The keys that the server used to sign messages with but won't use +# to sign new messages. E.g. it has lost its private key +old_signing_keys: {} +# "ed25519:auto": +# # Base64 encoded public key +# key: "The public part of your old signing key." +# # Millisecond POSIX timestamp when the key expired. +# expired_ts: 123456789123 + +# How long key response published by this server is valid for. +# Used to set the valid_until_ts in /key/v2 APIs. +# Determines how quickly servers will query to check which keys +# are still valid. +key_refresh_interval: "1d" # 1 Day. + +# The trusted servers to download signing keys from. +perspectives: + servers: + "matrix.org": + verify_keys: + "ed25519:auto": + key: "Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw" + + + +# Enable SAML2 for registration and login. Uses pysaml2 +# config_path: Path to the sp_conf.py configuration file +# idp_redirect_url: Identity provider URL which will redirect +# the user back to /login/saml2 with proper info. +# See pysaml2 docs for format of config. +#saml2_config: +# enabled: true +# config_path: "/home/erikj/git/synapse/sp_conf.py" +# idp_redirect_url: "http://test/idp" + + + +# Enable CAS for registration and login. +#cas_config: +# enabled: true +# server_url: "https://cas-server.com" +# service_url: "https://homesever.domain.com:8448" +# #required_attributes: +# # name: value + + +# The JWT needs to contain a globally unique "sub" (subject) claim. +# +# jwt_config: +# enabled: true +# secret: "a secret" +# algorithm: "HS256" + +password_providers: + - module: "ldap_auth_provider.LdapAuthProvider" + config: + enabled: true + uri: "ldap://bottin2.service.2.cluster.deuxfleurs.fr:389" + start_tls: false + bind_dn: '{{ key "secrets/chat/synapse/ldap_binddn" | trimSpace }}' + bind_password: '{{ key "secrets/chat/synapse/ldap_bindpw" | trimSpace }}' + base: "ou=users,dc=deuxfleurs,dc=fr" + attributes: + uid: "cn" + name: "displayName" + mail: "mail" + +# Enable password for login. +password_config: + enabled: true + +# Enable sending emails for notification events +#email: +# enable_notifs: false +# smtp_host: "localhost" +# smtp_port: 25 +# notif_from: "Your Friendly %(app)s Home Server " +# app_name: Matrix +# template_dir: res/templates +# notif_template_html: notif_mail.html +# notif_template_text: notif_mail.txt +# notif_for_new_users: True + +# Key that had to be added after some synapse updates to please matrix developers... +report_stats: false +suppress_key_server_warning: true +enable_group_creation: true + +#experimental_features: +# spaces_enabled: true + +presence: + enabled: false +limit_remote_rooms: + enabled: true + complexity: 3.0 + complexity_error: "Ce salon de discussion a trop d'activité, le serveur n'est pas assez puissant pour le rejoindre. N'hésitez pas à remonter l'information à l'équipe technique, nous pourrons ajuster la limitation au besoin." + admins_can_join: false +retention: + enabled: true + # no default policy for now, this is intended. + # DO NOT ADD ONE BECAUSE THIS IS DANGEROUS AND WILL DELETE CONTENT WE WANT TO KEEP! + purge_jobs: + - interval: 1d + diff --git a/cluster/prod/app/matrix/config/synapse/log.yaml b/cluster/prod/app/matrix/config/synapse/log.yaml new file mode 100644 index 0000000..eb69d8f --- /dev/null +++ b/cluster/prod/app/matrix/config/synapse/log.yaml @@ -0,0 +1,41 @@ + +version: 1 + +formatters: + precise: + format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s- %(message)s' + +filters: + context: + (): synapse.util.logcontext.LoggingContextFilter + request: "" + +handlers: + file: + class: logging.handlers.RotatingFileHandler + formatter: precise + filename: /var/log/matrix-synapse/homeserver.log + maxBytes: 10485760 + backupCount: 3 + filters: [context] + level: WARN + console: + class: logging.StreamHandler + formatter: precise + level: WARN + +loggers: + synapse: + level: INFO + + synapse.storage.SQL: + level: INFO + + ldap3: + level: DEBUG + ldap_auth_provider: + level: DEBUG + +root: + level: INFO + handlers: [file, console] diff --git a/cluster/prod/app/matrix/deploy/im.hcl b/cluster/prod/app/matrix/deploy/im.hcl new file mode 100644 index 0000000..0e219dd --- /dev/null +++ b/cluster/prod/app/matrix/deploy/im.hcl @@ -0,0 +1,200 @@ +job "matrix" { + datacenters = ["orion"] + type = "service" + priority = 60 + + group "matrix" { + count = 1 + + network { + port "api_port" { static = 8008 } + } + + task "synapse" { + driver = "docker" + + config { + image = "superboum/amd64_synapse:v54" + network_mode = "host" + readonly_rootfs = true + ports = [ "api_port" ] + command = "python" + args = [ + "-m", "synapse.app.homeserver", + "-n", + "-c", "/etc/matrix-synapse/homeserver.yaml" + ] + volumes = [ + "secrets/conf:/etc/matrix-synapse", + "/tmp/synapse-media:/var/lib/matrix-synapse/media", + "/tmp/synapse-uploads:/var/lib/matrix-synapse/uploads", + "/tmp/synapse-logs:/var/log/matrix-synapse", + "/tmp/synapse:/tmp" + ] + } + + template { + data = file("../config/synapse/homeserver.yaml") + destination = "secrets/conf/homeserver.yaml" + } + + template { + data = file("../config/synapse/log.yaml") + destination = "secrets/conf/log.yaml" + } + + template { + data = file("../config/synapse/conf.d/server_name.yaml") + destination = "secrets/conf/server_name.yaml" + } + + template { + data = file("../config/synapse/conf.d/report_stats.yaml") + destination = "secrets/conf/report_stats.yaml" + } + + # --- secrets --- + template { + data = "{{ key \"secrets/chat/synapse/homeserver.tls.crt\" }}" + destination = "secrets/conf/homeserver.tls.crt" + } + + template { + data = "{{ key \"secrets/chat/synapse/homeserver.tls.dh\" }}" + destination = "secrets/conf/homeserver.tls.dh" + } + + template { + data = "{{ key \"secrets/chat/synapse/homeserver.tls.key\" }}" + destination = "secrets/conf/homeserver.tls.key" + } + + template { + data = "{{ key \"secrets/chat/synapse/homeserver.signing.key\" }}" + destination = "secrets/conf/homeserver.signing.key" + } + + env { + SYNAPSE_CACHE_FACTOR = 1 + } + + resources { + cpu = 1000 + memory = 1000 + } + + service { + name = "synapse" + port = "api_port" + address_mode = "host" + tags = [ + "matrix", + "tricot im.deuxfleurs.fr/_matrix 100", + "tricot im.deuxfleurs.fr:443/_matrix 100", + "tricot im.deuxfleurs.fr/_synapse 100", + "tricot-add-header Access-Control-Allow-Origin *", + ] + check { + type = "tcp" + port = "api_port" + interval = "60s" + timeout = "5s" + check_restart { + limit = 3 + grace = "90s" + ignore_warnings = false + } + } + } + } + + + task "media-async-upload" { + driver = "docker" + + config { + image = "superboum/amd64_synapse:v54" + readonly_rootfs = true + command = "/usr/local/bin/matrix-s3-async" + work_dir = "/tmp" + volumes = [ + "/tmp/synapse-media:/var/lib/matrix-synapse/media", + "/tmp/synapse-uploads:/var/lib/matrix-synapse/uploads", + "/tmp/synapse:/tmp" + ] + } + + resources { + cpu = 100 + memory = 100 + } + + template { + data = <