Compare commits

...

64 Commits

Author SHA1 Message Date
3f488167bc chore: publish 7.1.0+v1.149.1 release 2026-05-11 13:19:17 +02:00
c71dc162cb readd cleanup trap to mas migration script 2026-04-09 11:51:39 +02:00
625b0381f8 readd cleanup trap to mas migration script 2026-04-09 11:48:25 +02:00
7492e8bd4e add mas healthcheck 2026-04-09 10:54:51 +02:00
60bd8b1b49 provide readme for mas setup and migration 2026-04-08 14:06:10 +02:00
6f47fca73b add script to perform mas migration compatibility check 2026-04-08 13:18:28 +02:00
dd92cd4bd7 add config for upstream oidc provider for mas 2026-04-08 13:02:22 +02:00
cf30cebf8e add function to init mas database 2026-04-07 16:20:34 +02:00
5481b7e31c add initial mas setup 2026-04-07 14:59:19 +02:00
8a7978b388 add docs for breaking share secret authenticator 2026-03-31 15:17:29 +02:00
d0d5cfb1bc chore: publish 7.0.2+v1.149.1 release 2026-03-31 14:55:43 +02:00
3d13505330 bumb python version for shared secret authenticator 2026-03-31 14:53:32 +02:00
68fd515297 chore: publish 7.0.1+v1.149.1 release 2026-03-30 13:04:48 +02:00
01e3feb1cf fix: healthchecks and restart_policy for web container 2026-03-30 13:02:27 +02:00
c51120c41a chore: publish 7.0.0+v1.149.1 release 2026-03-25 01:20:30 +01:00
b81fecdd23 chore: replace depricated traefik.docker.* with traefik.swarm.* 2026-03-17 17:26:54 +01:00
18b658c452 chore: publish 6.8.3+v1.139.2 release 2026-03-05 14:49:59 +01:00
553fee0e9d feat: compress db dumps 2026-03-05 14:49:11 +01:00
val
61f357b49e new patch version of recipe 2026-01-15 16:58:40 +01:00
val
0e55594727 Merge pull request 'revert to recipe state of v6.8.0' (#55) from revert-changes into main
Reviewed-on: https://git.coopcloud.tech/coop-cloud/matrix-synapse/pulls/55
2026-01-15 15:48:56 +00:00
val
460f5a969c revert to recipe state of v6.8.0 2026-01-15 11:13:51 +01:00
8640abbe79 increase healthcheck retries 2025-12-23 13:26:48 +01:00
val
3e0c9063c4 Merge branch '6.8.1fix' 2025-10-29 13:55:54 +01:00
val
db6440b317 fixed MAX_UPLOAD_SIZE and AUTO_JOIN_ROOM_LIST config 2025-10-29 13:49:02 +01:00
24f7e0cb35 chore: publish 6.8.1+v1.139.2 release 2025-10-28 17:17:22 +01:00
6d1397562b Merge pull request 'added env to configure several auto_join_rooms' (#52) from auto_join_room_list into main
Reviewed-on: https://git.coopcloud.tech/coop-cloud/matrix-synapse/pulls/52
2025-10-28 16:14:38 +00:00
e0c0861c16 Merge branch 'main' into auto_join_room_list 2025-10-28 16:14:13 +00:00
41fdcafaa0 added env to configure several auto_join_rooms 2025-10-28 17:12:33 +01:00
730dbc4569 Merge pull request 'Expose max_upload_size as a configurable option' (#51) from cas_expose_maxupload into main
Reviewed-on: https://git.coopcloud.tech/coop-cloud/matrix-synapse/pulls/51
Reviewed-by: decentral1se <decentral1se@noreply.git.coopcloud.tech>
2025-10-17 17:05:30 +00:00
809055dadb chore: publish 6.8.0+v1.139.2 release 2025-10-08 16:43:20 +02:00
7703bbbce7 Bump config versions 2025-10-03 11:20:39 -07:00
e3df032bda Expose max_upload_size as a configurable option 2025-10-02 11:40:51 -07:00
0cf9d0a244 chore: publish 6.7.1+v1.133.0 release 2025-09-07 11:49:20 +02:00
86a44afd19 fix nginx 2025-09-07 11:27:17 +02:00
cf47a9c1b0 chore: publish 6.7.0+v1.133.0 release 2025-07-07 16:11:13 +02:00
val
aaa59a7718 chore: publish 6.6.3+v1.124.0 release 2025-06-12 22:28:18 +02:00
val
e072cf0766 Merge pull request 'old-signing-key - anyone an idea how to escape so it's only one env var?' (#50) from old-signing-key into main
Reviewed-on: https://git.coopcloud.tech/coop-cloud/matrix-synapse/pulls/50
Reviewed-by: 3wordchant <3wordchant@noreply.git.coopcloud.tech>
2025-06-12 20:23:56 +00:00
val
22cc356a56 Merge branch 'main' into old-signing-key 2025-06-12 20:23:13 +00:00
160b0eb2cf fix: remove full env name "ADMIN_INTERFACE_ENABLED" from comment to
allow autouncomment
2025-06-11 14:48:43 +02:00
val
af7f7eca2f typos 2025-06-10 18:47:38 +02:00
val
5808fef48d add env 2025-06-08 12:20:46 +02:00
a8483dccf9 chore: publish 6.6.2+v1.124.0 release 2025-06-05 11:04:16 +02:00
8e82c16e3d Merge pull request 'added-env-vars' (#49) from added-env-vars into main
Reviewed-on: https://git.coopcloud.tech/coop-cloud/matrix-synapse/pulls/49
2025-06-05 08:58:39 +00:00
dafb17aace added some privacy related optional env-vars 2025-06-04 18:12:01 +02:00
237e2c832b user directory env vars 2025-06-04 16:59:58 +02:00
bf4de0df97 Set healthcheck interval higher for slow systems 2025-05-15 11:06:21 +02:00
61222baaa0 chore: publish 6.6.1+v1.124.0 release 2025-05-14 17:01:58 +02:00
32721ace23 Merge pull request 'Add REGISTRATION_REQUIRES_TOKEN to matrix config' (#46) from FunPecan/matrix-synapse:add-registration-token into main
Reviewed-on: https://git.coopcloud.tech/coop-cloud/matrix-synapse/pulls/46
Reviewed-by: decentral1se <decentral1se@noreply.git.coopcloud.tech>
2025-04-15 21:47:06 +00:00
5a7b7f04ed Bump homeserver version 2025-04-15 08:45:05 -07:00
8809f25ab1 Add regsitration token 2025-04-14 16:49:58 -07:00
0645a9f487 chore: publish 6.6.0+v1.124.0 release 2025-02-11 19:02:04 +01:00
a1d7fdad2d bump python version in shared_secret_authenticator module 2025-02-11 19:01:59 +01:00
a90ccaa65b add synapse-admin 2025-01-28 17:42:07 +01:00
7c0e822940 fix bridge token extraction 2025-01-17 20:13:09 +01:00
d6178fd380 improve set_bridge_tokens 2025-01-17 17:45:18 +01:00
2a18291f48 add script to setup bridge tokens 2025-01-17 15:43:47 +01:00
943ed58db4 new version of signal bridge conf 2025-01-16 15:53:46 +01:00
09b60947ee Merge pull request 'updated signal bridge to 0.7.5 and added env var for default encry bridge2server' (#44) from addtional-env-vars into main
Reviewed-on: https://git.coopcloud.tech/coop-cloud/matrix-synapse/pulls/44
Reviewed-by: decentral1se <decentral1se@noreply.git.coopcloud.tech>
2025-01-16 14:00:16 +00:00
bff6fe9b09 updated signal bridge to 0.7.5 and added env var for default encry bridge2server 2025-01-16 14:15:04 +01:00
6f4efd64e8 Update .drone.yml 2025-01-08 10:09:13 -08:00
202af642cf chore: publish 6.5.0+v1.117.0 release 2024-10-29 15:34:42 +01:00
29f31e0a7b fix drone runner 2024-10-24 14:41:32 +02:00
5c6985596e update backupbot label 2024-10-24 14:30:32 +02:00
3wc
dfe893160f chore: publish 6.4.0+v1.116.0 release 2024-10-02 15:14:01 -04:00
25 changed files with 1060 additions and 386 deletions

View File

@ -17,17 +17,21 @@ steps:
DOMAIN: matrix-synapse.swarm-test.autonomic.zone DOMAIN: matrix-synapse.swarm-test.autonomic.zone
STACK_NAME: matrix-synapse STACK_NAME: matrix-synapse
LETS_ENCRYPT_ENV: production LETS_ENCRYPT_ENV: production
DISCORD_BRIDGE_YAML_VERSION: v1 DISCORD_BRIDGE_YAML_VERSION: v2
ENTRYPOINT_CONF_VERSION: v1 ENTRYPOINT_CONF_VERSION: v3
HOMESERVER_YAML_VERSION: v17 HOMESERVER_YAML_VERSION: v29
LOG_CONFIG_VERSION: v1 LOG_CONFIG_VERSION: v2
SHARED_SECRET_AUTH_VERSION: v1 SHARED_SECRET_AUTH_VERSION: v2
SIGNAL_BRIDGE_YAML_VERSION: v1 SIGNAL_BRIDGE_YAML_VERSION: v5
TELEGRAM_BRIDGE_YAML_VERSION: v1 TELEGRAM_BRIDGE_YAML_VERSION: v6
PG_BACKUP_VERSION: v1
WK_CLIENT_VERSION: v1
WK_SERVER_VERSION: v1
NGINX_CONFIG_VERSION: v8
SECRET_DB_PASSWORD_VERSION: v1 SECRET_DB_PASSWORD_VERSION: v1
SECRET_FORM_SECRET_VERSION: v1 SECRET_FORM_SECRET_VERSION: v1
SECRET_MACAROON_SECRET_KEY_VERSION: v1 SECRET_MACAROON_VERSION: v1
SECRET_REGISTRATION_SHARED_SECRET_VERSION: v1 SECRET_REGISTRATION_VERSION: v1
trigger: trigger:
branch: branch:
- main - main
@ -43,7 +47,7 @@ steps:
from_secret: drone_abra-bot_token from_secret: drone_abra-bot_token
fork: true fork: true
repositories: repositories:
- coop-cloud/auto-recipes-catalogue-json - toolshed/auto-recipes-catalogue-json
trigger: trigger:
event: tag event: tag

View File

@ -6,6 +6,7 @@ ENABLE_AUTO_UPDATE=true
LETS_ENCRYPT_ENV=production LETS_ENCRYPT_ENV=production
COMPOSE_FILE="compose.yml" COMPOSE_FILE="compose.yml"
# POST_DEPLOY_CMDS="db set_admin" # POST_DEPLOY_CMDS="db set_admin"
ENABLE_BACKUPS=true
## Admin details ## Admin details
@ -18,6 +19,82 @@ SECRET_FORM_SECRET_VERSION=v1
SECRET_MACAROON_VERSION=v1 SECRET_MACAROON_VERSION=v1
SECRET_REGISTRATION_VERSION=v1 SECRET_REGISTRATION_VERSION=v1
## Authentication
# All login / SSO / MAS-related toggles in one place.
### Local password & registration (Synapse native)
# With MAS_ENABLED=1 you must set PASSWORD_LOGIN_ENABLED=false — Synapse forbids legacy password DB alongside matrix_authentication_service.
PASSWORD_LOGIN_ENABLED=true
ENABLE_REGISTRATION=false
# Token based registration. Enable ADMIN_INTERFACE (below) to use the admin interface to generate tokens.
#REGISTRATION_REQUIRES_TOKEN=true
### OIDC via Keycloak-shaped API (e.g. Authentik)
#COMPOSE_FILE="$COMPOSE_FILE:compose.keycloak.yml"
#KEYCLOAK_ENABLED=1
#KEYCLOAK_ID=keycloak
#KEYCLOAK_NAME=
#KEYCLOAK_URL=
#KEYCLOAK_CLIENT_ID=
#KEYCLOAK_CLIENT_DOMAIN=
#KEYCLOAK_ALLOW_EXISTING_USERS=false
#SECRET_KEYCLOAK_CLIENT_SECRET_VERSION=v1
### Second OIDC provider (compose.keycloak2.yml)
#COMPOSE_FILE="$COMPOSE_FILE:compose.keycloak2.yml"
#KEYCLOAK2_ENABLED=1
#KEYCLOAK2_ID=keycloak2
#KEYCLOAK2_NAME=
#KEYCLOAK2_URL=
#KEYCLOAK2_CLIENT_ID=
#KEYCLOAK2_CLIENT_DOMAIN=
#KEYCLOAK2_ALLOW_EXISTING_USERS=false
#SECRET_KEYCLOAK2_CLIENT_SECRET_VERSION=v1
### Third OIDC provider (compose.keycloak3.yml)
#COMPOSE_FILE="$COMPOSE_FILE:compose.keycloak3.yml"
#KEYCLOAK3_ENABLED=1
#KEYCLOAK3_ID=keycloak3
#KEYCLOAK3_NAME=
#KEYCLOAK3_URL=
#KEYCLOAK3_CLIENT_ID=
#KEYCLOAK3_CLIENT_DOMAIN=
#KEYCLOAK3_ALLOW_EXISTING_USERS=false
#SECRET_KEYCLOAK3_CLIENT_SECRET_VERSION=v1
### Matrix Authentication Service (MAS) — Element X / OIDC-native auth
#COMPOSE_FILE="$COMPOSE_FILE:compose.mas.yml"
#MAS_ENABLED=1
#PASSWORD_LOGIN_ENABLED=false
#SECRET_MAS_ENCRYPTION_VERSION=v1 # length=64 # charset=hex
#SECRET_MAS_SYNAPSE_SHARED_VERSION=v1 # length=64 # charset=hex
# PEM private key: abra cannot generate this format — insert only (e.g. openssl genrsa 2048 | abra app secret insert …)
#SECRET_MAS_SIGNING_RSA_VERSION=v1 # generate=false
#### MAS upstream OIDC provider (e.g. Authentik)
# Create a new OAuth2 app in your IdP with redirect URI: https://<DOMAIN>/upstream/callback/<MAS_UPSTREAM_PROVIDER_ID>
#COMPOSE_FILE="$COMPOSE_FILE:compose.mas-upstream.yml"
#MAS_UPSTREAM_PROVIDER_ID= # ULID, e.g. 01JSHPZHAXC50QBKH67MH33TNF — generate at https://www.ulidtools.com
#MAS_UPSTREAM_ISSUER= # e.g. https://auth.example.com/application/o/matrix-mas/
#MAS_UPSTREAM_CLIENT_ID=
#MAS_UPSTREAM_HUMAN_NAME=Authentik
# For migration from previous direct Keycloud-style config: set to oidc-<your old KEYCLOAK_ID> so syn2mas maps users correctly.
#MAS_UPSTREAM_SYNAPSE_IDP_ID=
#SECRET_MAS_UPSTREAM_CLIENT_SECRET_VERSION=v1
### Shared secret auth (bridges / automation)
#COMPOSE_FILE="$COMPOSE_FILE:compose.shared_secret_auth.yml"
#SHARED_SECRET_AUTH_ENABLED=1
#SECRET_SHARED_SECRET_AUTH_VERSION=v1 # length=128
## Federation ## Federation
#DISABLE_FEDERATION=1 #DISABLE_FEDERATION=1
@ -27,11 +104,6 @@ SERVE_SERVER_WELLKNOWN=false
ALLOW_PUBLIC_ROOMS_FEDERATION=false ALLOW_PUBLIC_ROOMS_FEDERATION=false
## Registration
ENABLE_REGISTRATION=false
PASSWORD_LOGIN_ENABLED=true
## Room auto-join ## Room auto-join
#AUTO_JOIN_ROOM_ENABLED=1 #AUTO_JOIN_ROOM_ENABLED=1
@ -64,6 +136,14 @@ ENCRYPTED_BY_DEFAULT=all
# Set these to keyservers you trust - usually the same as your federation allowlist # Set these to keyservers you trust - usually the same as your federation allowlist
#TRUSTED_KEYSERVERS="trusted_key_servers:\n - server_name: 'example.com'\n - server_name: 'example2.com'" #TRUSTED_KEYSERVERS="trusted_key_servers:\n - server_name: 'example.com'\n - server_name: 'example2.com'"
# some optional configs to increase privacy and security
#REQUIRE_AUTH_FOR_PROFILE_REQUESTS=true
#LIMIT_PROFILE_REQUESTS_TO_USERS_WHO_SHARE_ROOMS=true
#DELETE_STALE_DEVICES_AFTER=1y
#SESSION_LIFETIME=60d
#TRACK_PUPPETED_USER_IPS=true
## Retention ## Retention
ALLOWED_LIFETIME_MAX=4w ALLOWED_LIFETIME_MAX=4w
@ -74,6 +154,11 @@ RETENTION_MAX_LIFETIME=4w
#MEDIA_RETENTION_LOCAL_LIFETIME=30d #MEDIA_RETENTION_LOCAL_LIFETIME=30d
#MEDIA_RETENTION_REMOTE_LIFETIME=14d #MEDIA_RETENTION_REMOTE_LIFETIME=14d
## Old Signing Key
#OLD_SIGNING_KEY_ID=a_OLDKEYID
#OLD_SIGNING_KEY=base64string
#OLD_SIGNING_KEY_EXPIRES=123456789123
## Ratelimit ## Ratelimit
#LOGIN_LIMIT_IP_PER_SECOND=5 #LOGIN_LIMIT_IP_PER_SECOND=5
@ -81,30 +166,8 @@ RETENTION_MAX_LIFETIME=4w
#LOGIN_LIMIT_ACCOUNT_PER_SECOND=1 #LOGIN_LIMIT_ACCOUNT_PER_SECOND=1
#LOGIN_LIMIT_ACCOUNT_BURST=10 #LOGIN_LIMIT_ACCOUNT_BURST=10
## Keycloak SSO
#COMPOSE_FILE="$COMPOSE_FILE:compose.keycloak.yml"
#KEYCLOAK_ENABLED=1
#KEYCLOAK_ID=keycloak
#KEYCLOAK_NAME=
#KEYCLOAK_URL=
#KEYCLOAK_CLIENT_ID=
#KEYCLOAK_CLIENT_DOMAIN=
#KEYCLOAK_ALLOW_EXISTING_USERS=false
#SECRET_KEYCLOAK_CLIENT_SECRET_VERSION=v1
## TURN ## TURN
#COMPOSE_FILE="$COMPOSE_FILE:compose.keycloak3.yml"
#KEYCLOAK3_ENABLED=1
#KEYCLOAK3_ID=keycloak3
#KEYCLOAK3_NAME=
#KEYCLOAK3_URL=
#KEYCLOAK3_CLIENT_ID=
#KEYCLOAK3_CLIENT_DOMAIN=
#KEYCLOAK3_ALLOW_EXISTING_USERS=false
#SECRET_KEYCLOAK3_CLIENT_SECRET_VERSION=v1
#COMPOSE_FILE="$COMPOSE_FILE:compose.turn.yml" #COMPOSE_FILE="$COMPOSE_FILE:compose.turn.yml"
#TURN_ENABLED=1 #TURN_ENABLED=1
#TURN_URIS="[\"turns:coturn.foo.zone?transport=udp\", \"turns:coturn.foo.zone?transport=tcp\"]" #TURN_URIS="[\"turns:coturn.foo.zone?transport=udp\", \"turns:coturn.foo.zone?transport=tcp\"]"
@ -122,6 +185,13 @@ RETENTION_MAX_LIFETIME=4w
#SMTP_USER= #SMTP_USER=
#SECRET_SMTP_PASSWORD_VERSION=v1 #SECRET_SMTP_PASSWORD_VERSION=v1
## USER-DIRECTORY
#USER_DIRECTORY_ENABLED=true
#USER_DIRECTORY_SEARCH_ALL_USERS=true
#USER_DIRECTORY_PREFER_LOCAL_USERS=true
#USER_DIRECTORY_SHOW_LOCKED_USERS=false
## App services ## App services
#APP_SERVICES_ENABLED=1 #APP_SERVICES_ENABLED=1
@ -158,17 +228,17 @@ RETENTION_MAX_LIFETIME=4w
#COMPOSE_FILE="$COMPOSE_FILE:compose.signal.yml" #COMPOSE_FILE="$COMPOSE_FILE:compose.signal.yml"
#SIGNAL_ENABLE_ENCRYPTION=true #SIGNAL_ENABLE_ENCRYPTION=true
#SIGNAL_DEFAULT_ENCRYPTION=true
#SIGNAL_BRIDGE_PERMISSIONS="{ \"*\": \"relay\" }" #SIGNAL_BRIDGE_PERMISSIONS="{ \"*\": \"relay\" }"
#SECRET_SIGNAL_AS_TOKEN_VERSION=v1 #SECRET_SIGNAL_AS_TOKEN_VERSION=v1
#SECRET_SIGNAL_DB_PASSWORD_VERSION=v1 #SECRET_SIGNAL_DB_PASSWORD_VERSION=v1
#SECRET_SIGNAL_HS_TOKEN_VERSION=v1 #SECRET_SIGNAL_HS_TOKEN_VERSION=v1
#SECRET_SIGNAL_PICKLE_KEY_VERSION=v1 #SECRET_SIGNAL_PICKLE_KEY_VERSION=v1
## Shared auth
#COMPOSE_FILE="$COMPOSE_FILE:compose.shared_secret_auth.yml"
#SHARED_SECRET_AUTH_ENABLED=1
#SECRET_SHARED_SECRET_AUTH_VERSION=v1 # length=128
## Web Client (Redirect) ## Web Client (Redirect)
#WEB_CLIENT_LOCATION=https://element-web.example.com #WEB_CLIENT_LOCATION=https://element-web.example.com
## Admin interface at /admin
#COMPOSE_FILE="$COMPOSE_FILE:compose.admin.yml"
#ADMIN_INTERFACE_ENABLED=1

117
README.md
View File

@ -45,6 +45,50 @@ See [`#27`](https://git.coopcloud.tech/coop-cloud/matrix-synapse/pulls/27) for m
You'll need to deploy something like [this](https://git.autonomic.zone/ruangrupa/well-known-uris). This could be implemented in this recipe but we haven't merged it in yet. Change sets are welcome. You'll need to deploy something like [this](https://git.autonomic.zone/ruangrupa/well-known-uris). This could be implemented in this recipe but we haven't merged it in yet. Change sets are welcome.
### Matrix Authentication Service (MAS)
[MAS](https://element-hq.github.io/matrix-authentication-service/) is Elements OAuth/OIDC-native auth service for Matrix: it handles login, tokens, and upstream IdPs while Synapse delegates authentication via `matrix_authentication_service`.
**Enable the stack:**
- In `.env`, uncomment `compose.mas.yml` (and `compose.mas-upstream.yml` plus upstream envs if you use an external IdP), and uncomment the `SECRET_MAS_*` version lines.
- `abra app secret generate YOURAPPDOMAIN`
- **Manually insert** the PEM RSA key for `SECRET_MAS_SIGNING_RSA_VERSION` (`generate=false` in `.env.sample`) — abra cannot generate that format; see the comment there (e.g. `openssl genrsa 2048` piped to `abra app secret insert`).
- `abra app cmd YOURAPPDOMAIN db ensure_mas_database` (once, creates the `mas` database in Postgres)
- `abra app deploy YOURAPPDOMAIN`
**If you plan to migrate an existing homeserver with `syn2mas`:** deploy and configure MAS as above, but **leave `MAS_ENABLED=1` commented** until migration and cutover are done, so Synapse keeps using your current login path until you intentionally switch. You cannot use Synapse legacy OIDC/Keycloak SSO alongside MAS; plan IdP apps and envs accordingly.
<details>
<summary><strong>Migrating an existing server (<code>syn2mas</code>)</strong></summary>
Requires PostgreSQL on Synapse and a dedicated MAS database. Backup Postgres (and configs) before you start. Official background: [MAS migration guide](https://element-hq.github.io/matrix-authentication-service/setup/migration.html).
1. **Prepare (Synapse still running):** With MAS in `COMPOSE_FILE` but **`MAS_ENABLED` still off**, deploy, then run checks from your machine:
```bash
abra app cmd YOURAPPDOMAIN prepare_mas_migration
```
This fetches rendered `homeserver.yaml` into the MAS container, runs `syn2mas check`, then `migrate --dry-run` (the dry run rolls back MAS data at the end). The file stays in the MAS container until next restart, so you can repeat this step to provide the file for the actual migration.
2. **Optional snapshot:** save a copy of the rendered config while `app` is up, e.g. `abra app run -t YOURAPPDOMAIN app cat /data/homeserver.yaml > homeserver.snapshot.yaml`.
3. **Downtime — stop Synapse:** run on the **host** with Docker/Swarm access (not inside a container), e.g.:
```bash
docker service scale <STACK_NAME>_app=0
```
Use the real service name from `docker service ls` (suffix `_app`).
4. **Migration:** with MAS still running and Synapse at zero replicas,
```bash
abra app run YOURAPPDOMAIN mas -- mas-cli syn2mas migrate \
--config /etc/mas/config.yaml \
--synapse-config /tmp/homeserver.yaml
```
5. **Cutover:** in `.env`, set `MAS_ENABLED=1`, `PASSWORD_LOGIN_ENABLED=false`, remove legacy Keycloak/SSO envs, then `abra app deploy YOURAPPDOMAIN` (Synapse comes back with MAS delegation). `syn2mas` does not write to the Synapse database; if you abort before serving traffic through MAS, you can often drop and recreate the MAS DB and revert env.
</details>
## Bridges ## Bridges
For all Bridges: For all Bridges:
- Setting it up is a bit of a chicken/egg & chasing cats moment. - Setting it up is a bit of a chicken/egg & chasing cats moment.
@ -52,9 +96,10 @@ For all Bridges:
- include the registration in synapse, e.g. `APP_SERVICE_CONFIGS="[\"/telegram-data/registration.yaml\"]"` - include the registration in synapse, e.g. `APP_SERVICE_CONFIGS="[\"/telegram-data/registration.yaml\"]"`
- and set yourself as admin, e.g.: `TELEGRAM_BRIDGE_PERMISSIONS="{ \"*\": \"relaybot\", \"@akadmin:example.com\": \"admin\"}"` - and set yourself as admin, e.g.: `TELEGRAM_BRIDGE_PERMISSIONS="{ \"*\": \"relaybot\", \"@akadmin:example.com\": \"admin\"}"`
### Telegram bridging > [!IMPORTANT]
> The shared secret authenticator may break when matrix-synapse uses a newer python version with an error stating something like "module not found". You have to fix the path in the compose.shared_secret_auth.yml like [here](https://git.coopcloud.tech/coop-cloud/matrix-synapse/commit/3d1350533079ce1ad3bea92039fe003684589b95)
> WIP docs ### Telegram bridging
You need to get your bot setup on the telegram side first by creating a [telegram app](https://my.telegram.org/apps) and a [telegram bot](https://docs.mau.fi/bridges/python/telegram/relay-bot.html#setup) and have these values: You need to get your bot setup on the telegram side first by creating a [telegram app](https://my.telegram.org/apps) and a [telegram bot](https://docs.mau.fi/bridges/python/telegram/relay-bot.html#setup) and have these values:
@ -63,25 +108,36 @@ api_id: ...
api_hash: ... api_hash: ...
telegram_bot_token: ... telegram_bot_token: ...
``` ```
Experimental script for a automated token replacement:
```
DOMAIN=<domain>
abra app secret insert $DOMAIN telegram_api_hash v1 <secret>
abra app secret insert $DOMAIN telegram_bot_token v1 <secret>
abra app secret generate -a $DOMAIN
A rough guide for the following steps: abra app deploy $DOMAIN
abra app cmd -l $DOMAIN set_bridge_tokens telegram
```
Alternatively a manual guide for the necessary steps:
``` ```
abra app secret insert <domain> telegram_api_hash v1 <secret> DOMAIN=<domain>
abra app secret insert <domain> telegram_bot_token v1 <secret> abra app secret insert $DOMAIN telegram_api_hash v1 <secret>
abra app secret generate -a <domain> abra app secret insert $DOMAIN telegram_bot_token v1 <secret>
abra app secret generate -a $DOMAIN
abra app deploy <domain> abra app deploy $DOMAIN
abra app run matrix.fva.wtf telegram_bridge cat /data/registration.yaml abra app run $DOMAIN telegrambridge cat /data/registration.yaml
abra app undeploy <domain> abra app undeploy $DOMAIN
abra app secret rm <domain> telegram_as_token abra app secret rm $DOMAIN telegram_as_token
abra app secret insert <domain> telegram_as_token v1 <secret> abra app secret insert $DOMAIN telegram_as_token v1 <secret>
abra app secret rm <domain> telegram_as_token abra app secret rm $DOMAIN telegram_hs_token
abra app secret insert <domain> telegram_hs_token v1 <secret> abra app secret insert $DOMAIN telegram_hs_token v1 <secret>
abra app deploy <domain> abra app deploy $DOMAIN
``` ```
Some helpful documentation: Some helpful documentation:
@ -110,16 +166,29 @@ Some helpful documentation:
### Signal bridging ### Signal bridging
> WIP docs Experimental script for a more automated token replacement:
```
DOMAIN=<domain>
abra app secret generate -a $DOMAIN
abra app deploy $DOMAIN
abra app cmd -l $DOMAIN set_bridge_tokens signal
```
Alternatively a manual guide for the necessary steps:
```
DOMAIN=<domain>
abra app secret insert $DOMAIN signal_hs_token v1 foo
abra app secret insert $DOMAIN signal_as_token v1 foo
abra app secret generate $DOMAIN -a
abra app deploy $DOMAIN
abra app run $DOMAIN signalbridge cat /data/registration.yaml
OK, it's also awful to set this up. Do you see a pattern emerging :) abra app secret rm $DOMAIN signal_as_token
abra app secret insert $DOMAIN signal_as_token v1 <secret>
abra app secret rm $DOMAIN signal_hs_token
abra app secret insert $DOMAIN signal_hs_token v1 <secret>
- fake that you have the required tokens: abra app deploy $DOMAIN
- `abra app secret insert example.com signal_hs_token v1 foo` ```
- `abra app secret insert example.com signal_as_token v1 foo`
- generate the database password: - message `@signalbot:example.com` to test
- `abra app secret generate example.com -a`
- deploy the thing and then check the `/data/registration.yaml`
- rm the fake `signal_hs/as_token` values and re-insert the new ones from `registration.yaml`
- re-deploy the whole thing and then it should come up, message `@signalbot:example.com` to test
- See the [docs](https://docs.mau.fi/bridges/go/signal/authentication.html) for authentication - See the [docs](https://docs.mau.fi/bridges/go/signal/authentication.html) for authentication

92
abra.sh
View File

@ -1,13 +1,62 @@
export DISCORD_BRIDGE_YAML_VERSION=v2 export DISCORD_BRIDGE_YAML_VERSION=v2
export ENTRYPOINT_CONF_VERSION=v3 export ENTRYPOINT_CONF_VERSION=v3
export HOMESERVER_YAML_VERSION=v29 export HOMESERVER_YAML_VERSION=v36
export LOG_CONFIG_VERSION=v2 export LOG_CONFIG_VERSION=v2
export SHARED_SECRET_AUTH_VERSION=v1 export SHARED_SECRET_AUTH_VERSION=v2
export SIGNAL_BRIDGE_YAML_VERSION=v5 export SIGNAL_BRIDGE_YAML_VERSION=v6
export TELEGRAM_BRIDGE_YAML_VERSION=v6 export TELEGRAM_BRIDGE_YAML_VERSION=v6
export NGINX_CONFIG_VERSION=v7 export NGINX_CONFIG_VERSION=v13
export WK_SERVER_VERSION=v1 export WK_SERVER_VERSION=v1
export WK_CLIENT_VERSION=v1 export WK_CLIENT_VERSION=v2
export MAS_CONFIG_VERSION=v1
export PG_BACKUP_VERSION=v2
export ADMIN_CONFIG_VERSION=v1
ensure_mas_database () {
if ! psql -U synapse -d postgres -v ON_ERROR_STOP=1 -Atqc "SELECT 1 FROM pg_database WHERE datname = 'mas'" | grep -qx 1
then
psql -U synapse -d postgres -v ON_ERROR_STOP=1 -c "CREATE DATABASE mas OWNER synapse"
fi
}
# Local helper: fetch homeserver.yaml from app, push to mas, then syn2mas check + dry-run.
prepare_mas_migration () {
local hs_local syn_cfg
syn_cfg=/tmp/homeserver.yaml
cleanup_prepare_mas_migration() {
rm -f "homeserver.yaml"
}
trap cleanup_prepare_mas_migration EXIT
echo "Fetching /data/homeserver.yaml from app to homeserver.yaml (abra app run … cat)..."
if ! abra app run -t "$DOMAIN" app cat /data/homeserver.yaml > "homeserver.yaml"
then
return 1
fi
if [ ! -s "homeserver.yaml" ]; then
echo "Error: fetched homeserver.yaml is empty." >&2
return 1
fi
echo "Copying into mas:/tmp"
abra app cp "$DOMAIN" "homeserver.yaml" "mas:/tmp" || return 1
echo "Running mas-cli syn2mas check..."
abra app run -t "$DOMAIN" mas -- mas-cli syn2mas check \
--config /etc/mas/config.yaml \
--synapse-config "$syn_cfg" || return 1
echo "Running mas-cli syn2mas migrate --dry-run..."
abra app run -t "$DOMAIN" mas -- mas-cli syn2mas migrate \
--config /etc/mas/config.yaml \
--synapse-config "$syn_cfg" \
--dry-run || return 1
trap - EXIT
cleanup_prepare_mas_migration
}
set_admin () { set_admin () {
admin=akadmin admin=akadmin
@ -17,3 +66,36 @@ set_admin () {
fi fi
psql -U synapse -c "UPDATE users SET admin = 1 WHERE name = '@$admin:$DOMAIN'"; psql -U synapse -c "UPDATE users SET admin = 1 WHERE name = '@$admin:$DOMAIN'";
} }
set_bridge_tokens() {
if [ -z "$1" ]; then
echo "Error: Missing parameter. Usage: set_bridge_tokens <BRIDGETYPE>"
return 1
fi
BRIDGETYPE=$1
echo "retrieve tokens from registration.yaml..."
output=$(abra app run $DOMAIN app cat /${BRIDGETYPE}-data/registration.yaml)
if [ $? -ne 0 ]; then
echo "Error: Failed to retrieve registration.yaml for ${BRIDGETYPE} bridge:"
echo "$output"
return 1
fi
hs_token=$(echo "$output" | sed -n 's/^hs_token:[[:space:]]*\(.*\)$/\1/p')
as_token=$(echo "$output" | sed -n 's/^as_token:[[:space:]]*\(.*\)$/\1/p')
echo "HS Token: $hs_token"
echo "AS Token: $as_token"
echo "UNDEPLOY $DOMAIN?"
abra app undeploy $DOMAIN
echo "Replacing tokens:"
abra app secret rm $DOMAIN ${BRIDGETYPE}_as_token
abra app secret insert $DOMAIN ${BRIDGETYPE}_as_token v1 $as_token
abra app secret rm $DOMAIN ${BRIDGETYPE}_hs_token
abra app secret insert $DOMAIN ${BRIDGETYPE}_hs_token v1 $hs_token
echo "Redeploying $DOMAIN..."
abra app deploy -n $DOMAIN
}

3
admin.conf.tmpl Normal file
View File

@ -0,0 +1,3 @@
{
"restrictBaseUrl": "https://{{ env "DOMAIN" }}"
}

46
compose.admin.yml Normal file
View File

@ -0,0 +1,46 @@
---
version: "3.8"
services:
admin:
image: awesometechnologies/synapse-admin:0.11.4
networks:
- proxy
deploy:
labels:
- "traefik.enable=true"
- "traefik.swarm.network=proxy"
- "traefik.http.services.${STACK_NAME}_admin.loadbalancer.server.port=80"
- "traefik.http.routers.${STACK_NAME}_admin.rule=Host(`${DOMAIN}`${EXTRA_DOMAINS})&&PathPrefix(`/admin`)"
- "traefik.http.routers.${STACK_NAME}_admin.entrypoints=web-secure"
- "traefik.http.routers.${STACK_NAME}_admin.tls.certresolver=${LETS_ENCRYPT_ENV}"
- "traefik.http.routers.${STACK_NAME}_admin.middlewares=admin,admin_path"
- "traefik.http.middlewares.admin.redirectregex.regex=^(.*)/admin/?"
- "traefik.http.middlewares.admin.redirectregex.replacement=$${1}/admin/"
- "traefik.http.middlewares.admin_path.stripprefix.prefixes=/admin"
environment:
- DOMAIN
configs:
- source: admin_config
target: /app/config.json
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
timeout: 10s
retries: 10
start_period: 1m
web:
environment:
- ADMIN_INTERFACE_ENABLED
networks:
proxy:
external: true
configs:
admin_config:
name: ${STACK_NAME}_admin_config_${ADMIN_CONFIG_VERSION}
file: admin.conf.tmpl
template_driver: golang

21
compose.mas-upstream.yml Normal file
View File

@ -0,0 +1,21 @@
---
version: "3.8"
# Upstream OIDC provider for MAS (e.g. Authentik, Keycloak).
# Requires compose.mas.yml. Adds the client secret and env vars needed by mas.config.yaml.tmpl.
services:
mas:
environment:
- MAS_UPSTREAM_PROVIDER_ID
- MAS_UPSTREAM_ISSUER
- MAS_UPSTREAM_CLIENT_ID
- MAS_UPSTREAM_HUMAN_NAME
- MAS_UPSTREAM_SYNAPSE_IDP_ID
secrets:
- mas_upstream_client_secret
secrets:
mas_upstream_client_secret:
external: true
name: ${STACK_NAME}_mas_upstream_client_secret_${SECRET_MAS_UPSTREAM_CLIENT_SECRET_VERSION}

64
compose.mas.yml Normal file
View File

@ -0,0 +1,64 @@
---
version: "3.8"
# Matrix Authentication Service (MAS) — optional overlay for Element X / OIDC-native auth.
services:
mas:
image: ghcr.io/element-hq/matrix-authentication-service:1.14.0
command: ["server", "--config=/etc/mas/config.yaml"]
environment:
- DOMAIN
- SERVER_NAME
- STACK_NAME
networks:
- internal
configs:
- source: mas_config
target: /etc/mas/config.yaml
secrets:
- db_password
- mas_encryption
- mas_synapse_shared
- mas_signing_rsa
# Official image is distroless (no curl/wget); upstream suggests `mas-cli config check` for probes.
# See https://github.com/element-hq/matrix-authentication-service/issues/3741 — validates config, not HTTP.
# GET /health is still served (resource `health` in mas.config.yaml.tmpl) for probes from other images.
healthcheck:
test:
[
"CMD",
"/usr/local/bin/mas-cli",
"--config",
"/etc/mas/config.yaml",
"config",
"check",
]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
deploy:
restart_policy:
condition: on-failure
app:
secrets:
- mas_synapse_shared
configs:
mas_config:
name: ${STACK_NAME}_mas_config_${MAS_CONFIG_VERSION}
file: mas.config.yaml.tmpl
template_driver: golang
secrets:
mas_encryption:
external: true
name: ${STACK_NAME}_mas_encryption_${SECRET_MAS_ENCRYPTION_VERSION}
mas_synapse_shared:
external: true
name: ${STACK_NAME}_mas_synapse_shared_${SECRET_MAS_SYNAPSE_SHARED_VERSION}
mas_signing_rsa:
external: true
name: ${STACK_NAME}_mas_signing_rsa_${SECRET_MAS_SIGNING_RSA_VERSION}

View File

@ -9,7 +9,7 @@ services:
- shared_secret_auth - shared_secret_auth
configs: configs:
- source: shared_secret_auth - source: shared_secret_auth
target: /usr/local/lib/python3.11/site-packages/shared_secret_authenticator.py target: /usr/local/lib/python3.13/site-packages/shared_secret_authenticator.py
configs: configs:
shared_secret_auth: shared_secret_auth:

View File

@ -10,7 +10,7 @@ services:
- signal-data:/signal-data - signal-data:/signal-data
signalbridge: signalbridge:
image: dock.mau.dev/mautrix/signal:v0.7.0 image: dock.mau.dev/mautrix/signal:v0.8.7
depends_on: depends_on:
- signaldb - signaldb
configs: configs:
@ -21,6 +21,7 @@ services:
- HOMESERVER_URL - HOMESERVER_URL
- SIGNAL_BRIDGE_PERMISSIONS - SIGNAL_BRIDGE_PERMISSIONS
- SIGNAL_ENABLE_ENCRYPTION - SIGNAL_ENABLE_ENCRYPTION
- SIGNAL_DEFAULT_ENCRYPTION=${SIGNAL_DEFAULT_ENCRYPTION:-false}
- VERIFY_SSL - VERIFY_SSL
secrets: secrets:
- signal_as_token - signal_as_token
@ -32,10 +33,6 @@ services:
- signal-data:/data - signal-data:/data
networks: networks:
- internal - internal
deploy:
labels:
backupbot.backup: "true"
backupbot.backup.path: "/data"
signaldb: signaldb:
image: postgres:13-alpine image: postgres:13-alpine
@ -56,10 +53,13 @@ services:
- signal-postgres:/var/lib/postgresql/data - signal-postgres:/var/lib/postgresql/data
deploy: deploy:
labels: labels:
backupbot.backup: "true" backupbot.backup.pre-hook: "/pg_backup.sh backup"
backupbot.backup.pre-hook: "PGPASSWORD=$$(cat $${POSTGRES_PASSWORD_FILE}) pg_dump -U $${POSTGRES_USER} $${POSTGRES_DB} > /var/lib/postgresql/data/backup.sql" backupbot.backup.volumes.signal-postgres.path: "backup.sql"
backupbot.backup.post-hook: "rm -r /var/lib/postgresql/data/backup.sql" backupbot.restore.post-hook: '/pg_backup.sh restore'
backupbot.backup.path: "/var/lib/postgresql/data" configs:
- source: pg_backup
target: /pg_backup.sh
mode: 0555
configs: configs:
signal_bridge_yaml: signal_bridge_yaml:

View File

@ -10,7 +10,7 @@ services:
- telegram-data:/telegram-data - telegram-data:/telegram-data
telegrambridge: telegrambridge:
image: dock.mau.dev/mautrix/telegram:v0.15.2 image: dock.mau.dev/mautrix/telegram:v0.15.3
depends_on: depends_on:
- telegramdb - telegramdb
configs: configs:
@ -56,6 +56,15 @@ services:
test: ["CMD", "pg_isready", "-U", "$POSTGRES_USER" ] test: ["CMD", "pg_isready", "-U", "$POSTGRES_USER" ]
volumes: volumes:
- telegram-postgres:/var/lib/postgresql/data - telegram-postgres:/var/lib/postgresql/data
deploy:
labels:
backupbot.backup.pre-hook: "/pg_backup.sh backup"
backupbot.backup.volumes.telegram-postgres.path: "backup.sql"
backupbot.restore.post-hook: '/pg_backup.sh restore'
configs:
- source: pg_backup
target: /pg_backup.sh
mode: 0555
configs: configs:
telegram_bridge_yaml: telegram_bridge_yaml:

View File

@ -3,15 +3,17 @@ version: "3.8"
services: services:
web: web:
image: nginx:1.27.1 image: nginx:1.29.6
networks: networks:
- proxy - proxy
- internal - internal
environment: environment:
- DOMAIN - DOMAIN
- STACK_NAME - STACK_NAME
- MAS_ENABLED
- NGINX_ACCESS_LOG_LOCATION - NGINX_ACCESS_LOG_LOCATION
- NGINX_ERROR_LOG_LOCATION - NGINX_ERROR_LOG_LOCATION
- MAX_UPLOAD_SIZE
configs: configs:
- source: nginx_config - source: nginx_config
target: /etc/nginx/nginx.conf target: /etc/nginx/nginx.conf
@ -21,7 +23,7 @@ services:
target: /var/www/.well-known/matrix/client target: /var/www/.well-known/matrix/client
deploy: deploy:
restart_policy: restart_policy:
condition: on-failure condition: any
labels: labels:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=80" - "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=80"
@ -30,12 +32,13 @@ services:
- "traefik.http.routers.${STACK_NAME}.tls.certresolver=${LETS_ENCRYPT_ENV}" - "traefik.http.routers.${STACK_NAME}.tls.certresolver=${LETS_ENCRYPT_ENV}"
healthcheck: healthcheck:
test: curl -f http://${STACK_NAME}_app:8008/health || exit 1 test: curl -f http://${STACK_NAME}_app:8008/health || exit 1
interval: 5s interval: 30s
timeout: 3s timeout: 15s
retries: 20 retries: 90
start_period: 2m
app: app:
image: "matrixdotorg/synapse:v1.113.0" image: "matrixdotorg/synapse:v1.149.1"
volumes: volumes:
- "data:/data" - "data:/data"
secrets: secrets:
@ -44,6 +47,7 @@ services:
- macaroon - macaroon
- form_secret - form_secret
environment: environment:
- MAS_ENABLED
- ALLOWED_LIFETIME_MAX - ALLOWED_LIFETIME_MAX
- ALLOW_PUBLIC_ROOMS_FEDERATION - ALLOW_PUBLIC_ROOMS_FEDERATION
- AUTO_JOIN_ROOM - AUTO_JOIN_ROOM
@ -53,8 +57,21 @@ services:
- ENABLE_3PID_LOOKUP - ENABLE_3PID_LOOKUP
- ENABLE_ALLOWLIST - ENABLE_ALLOWLIST
- ENABLE_REGISTRATION - ENABLE_REGISTRATION
- REGISTRATION_REQUIRES_TOKEN
- ENCRYPTED_BY_DEFAULT - ENCRYPTED_BY_DEFAULT
- OLD_SIGNING_KEY
- OLD_SIGNING_KEY_ID
- OLD_SIGNING_KEY_EXPIRES
- USER_DIRECTORY_ENABLED=${USER_DIRECTORY_ENABLED:-true}
- USER_DIRECTORY_SEARCH_ALL_USERS=${USER_DIRECTORY_SEARCH_ALL_USERS:-true}
- USER_DIRECTORY_PREFER_LOCAL_USERS=${USER_DIRECTORY_PREFER_LOCAL_USERS:-true}
- USER_DIRECTORY_SHOW_LOCKED_USERS=${USER_DIRECTORY_SHOW_LOCKED_USERS:-false}
- FEDERATION_ALLOWLIST - FEDERATION_ALLOWLIST
- REQUIRE_AUTH_FOR_PROFILE_REQUESTS=${REQUIRE_AUTH_FOR_PROFILE_REQUESTS:-false}
- LIMIT_PROFILE_REQUESTS_TO_USERS_WHO_SHARE_ROOMS=${LIMIT_PROFILE_REQUESTS_TO_USERS_WHO_SHARE_ROOMS:-false}
- DELETE_STALE_DEVICES_AFTER
- SESSION_LIFETIME
- TRACK_PUPPETED_USER_IPS=${TRACK_PUPPETED_USER_IPS:-false}
- LETSENCRYPT_HOST=${DOMAIN} - LETSENCRYPT_HOST=${DOMAIN}
- MEDIA_RETENTION_LOCAL_LIFETIME - MEDIA_RETENTION_LOCAL_LIFETIME
- MEDIA_RETENTION_REMOTE_LIFETIME - MEDIA_RETENTION_REMOTE_LIFETIME
@ -91,43 +108,46 @@ services:
restart_policy: restart_policy:
condition: on-failure condition: on-failure
labels: labels:
- "coop-cloud.${STACK_NAME}.version=6.3.0+v1.113.0" - "coop-cloud.${STACK_NAME}.version=7.1.0+v1.149.1"
- "coop-cloud.${STACK_NAME}.timeout=${TIMEOUT:-120}" - "coop-cloud.${STACK_NAME}.timeout=${TIMEOUT}"
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8008/health"] test: ["CMD", "curl", "-f", "http://localhost:8008/health"]
interval: 30s interval: 30s
timeout: 10s timeout: 10s
retries: 10 retries: 30
start_period: 1m start_period: 1m
db: db:
image: postgres:13-alpine image: pgautoupgrade/pgautoupgrade:17-alpine
secrets: secrets:
- db_password - db_password
environment: environment:
- LC_COLLATE=C - LC_COLLATE=C
- LC_CTYPE=C - LC_CTYPE=C
- POSTGRES_DB=synapse - POSTGRES_DB=synapse
- POSTGRES_INITDB_ARGS="-E \"UTF8\"" - POSTGRES_INITDB_ARGS=-E UTF8
- POSTGRES_PASSWORD_FILE=/run/secrets/db_password - POSTGRES_PASSWORD_FILE=/run/secrets/db_password
- POSTGRES_USER=synapse - POSTGRES_USER=synapse
- DOMAIN - DOMAIN
networks: networks:
- internal - internal
healthcheck: healthcheck:
test: ["CMD", "pg_isready", "-U", "synapse"]
interval: 30s interval: 30s
timeout: 10s timeout: 10s
retries: 10 retries: 20
start_period: 1m start_period: 1m
volumes: volumes:
- postgres:/var/lib/postgresql/data - postgres:/var/lib/postgresql/data
deploy: deploy:
labels: labels:
backupbot.backup: "true" backupbot.backup: "${ENABLE_BACKUPS:-true}"
backupbot.backup.pre-hook: "PGPASSWORD=$$(cat $${POSTGRES_PASSWORD_FILE}) pg_dump -U $${POSTGRES_USER} $${POSTGRES_DB} > /var/lib/postgresql/data/backup.sql" backupbot.backup.pre-hook: "/pg_backup.sh backup"
backupbot.backup.post-hook: "rm -r /var/lib/postgresql/data/backup.sql" backupbot.backup.volumes.postgres.path: "backup.sql"
backupbot.backup.path: "/var/lib/postgresql/data" backupbot.restore.post-hook: "/pg_backup.sh restore"
configs:
- source: pg_backup
target: /pg_backup.sh
mode: 0555
volumes: volumes:
data: data:
@ -163,6 +183,9 @@ configs:
name: ${STACK_NAME}_wk_client_${WK_CLIENT_VERSION} name: ${STACK_NAME}_wk_client_${WK_CLIENT_VERSION}
file: well_known_client.conf.tmpl file: well_known_client.conf.tmpl
template_driver: golang template_driver: golang
pg_backup:
name: ${STACK_NAME}_pg_backup_${PG_BACKUP_VERSION}
file: pg_backup.sh
secrets: secrets:
db_password: db_password:

View File

@ -1,281 +1,390 @@
# All configuration options are documented on the following link: # All configuration options are documented on the following link:
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html
{{ if eq (env "SHARED_SECRET_AUTH_ENABLED") "1" }} {{ if eq (env "SHARED_SECRET_AUTH_ENABLED") "1" }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#modules-1 # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#modules-1
modules: modules:
- module: shared_secret_authenticator.SharedSecretAuthProvider - module: shared_secret_authenticator.SharedSecretAuthProvider
config: config:
shared_secret: {{ secret "shared_secret_auth" }} shared_secret: {{ secret "shared_secret_auth" }}
m_login_password_support_enabled: true m_login_password_support_enabled: true
{{ end }} {{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#server_name # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#server_name
server_name: {{ or (env "SERVER_NAME") (env "DOMAIN") }} server_name: {{ or (env "SERVER_NAME") (env "DOMAIN") }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#public_baseurl # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#public_baseurl
public_baseurl: https://{{ env "DOMAIN" }}/ public_baseurl: https://{{ env "DOMAIN" }}/
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#serve_server_wellknown # https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#require_auth_for_profile_requests
serve_server_wellknown: {{ env "SERVE_SERVER_WELLKNOWN" }} {{ if (env "REQUIRE_AUTH_FOR_PROFILE_REQUESTS") }}
require_auth_for_profile_requests: {{ env "REQUIRE_AUTH_FOR_PROFILE_REQUESTS" }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#allow_public_rooms_without_auth {{ end }}
allow_public_rooms_without_auth: false
# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#limit_profile_requests_to_users_who_share_rooms
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#allow_public_rooms_over_federation {{ if (env "LIMIT_PROFILE_REQUESTS_TO_USERS_WHO_SHARE_ROOMS") }}
allow_public_rooms_over_federation: {{ or (env "ALLOW_PUBLIC_ROOMS_FEDERATION") "true" }} limit_profile_requests_to_users_who_share_rooms: {{ env "LIMIT_PROFILE_REQUESTS_TO_USERS_WHO_SHARE_ROOMS" }}
{{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#listeners
listeners: # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#serve_server_wellknown
- port: 8008 {{ if (env "SERVE_SERVER_WELLKNOWN") }}
tls: false serve_server_wellknown: {{ env "SERVE_SERVER_WELLKNOWN" }}
type: http {{ end }}
x_forwarded: true
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#allow_public_rooms_without_auth
{{ if eq (env "DISABLE_FEDERATION") "1" }} allow_public_rooms_without_auth: false
resources:
{{ if eq (env "KEYCLOAK_ENABLED") "1" }} # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#allow_public_rooms_over_federation
- names: [client, openid] {{ if (env "ALLOW_PUBLIC_ROOMS_FEDERATION") }}
compress: true allow_public_rooms_over_federation: {{ env "ALLOW_PUBLIC_ROOMS_FEDERATION" }}
{{ else }} {{ end }}
- names: [client]
compress: true # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#listeners
{{ end }} listeners:
{{ else }} - port: 8008
resources: tls: false
{{ if eq (env "KEYCLOAK_ENABLED") "1" }} type: http
- names: [client, openid, federation] x_forwarded: true
compress: true
{{ else }} {{ if eq (env "DISABLE_FEDERATION") "1" }}
- names: [client, federation] resources:
compress: true {{ if eq (env "KEYCLOAK_ENABLED") "1" }}
{{ end }} - names: [client, openid]
{{ end }} compress: true
{{ else }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#admin_contact - names: [client]
admin_contact: 'mailto:{{ env "ADMIN_EMAIL" }}' compress: true
{{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#limit_remote_rooms {{ else }}
limit_remote_rooms: resources:
enabled: true {{ if eq (env "KEYCLOAK_ENABLED") "1" }}
complexity: 200.0 - names: [client, openid, federation]
compress: true
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#max_avatar_size {{ else }}
max_avatar_size: 10M - names: [client, federation]
compress: true
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#forgotten_room_retention_period {{ end }}
forgotten_room_retention_period: 3d {{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#request_token_inhibit_3pid_errors # https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#delete_stale_devices_after
request_token_inhibit_3pid_errors: true {{ if (env "DELETE_STALE_DEVICES_AFTER") }}
delete_stale_devices_after: {{ env "DELETE_STALE_DEVICES_AFTER" }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#redaction_retention_period {{ end }}
redaction_retention_period: {{ env "REDACTION_RETENTION_PERIOD" }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#admin_contact
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#user_ips_max_age {{ if (env "ADMIN_EMAIL") }}
user_ips_max_age: {{ env "USER_IPS_MAX_AGE" }} admin_contact: 'mailto:{{ env "ADMIN_EMAIL" }}'
{{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#retention
retention: # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#limit_remote_rooms
enabled: true limit_remote_rooms:
default_policy: enabled: true
min_lifetime: 1d complexity: 200.0
max_lifetime: {{ env "RETENTION_MAX_LIFETIME" }}
allowed_lifetime_min: 1d # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#max_avatar_size
allowed_lifetime_max: {{ env "ALLOWED_LIFETIME_MAX" }} max_avatar_size: 10M
purge_jobs:
- longest_max_lifetime: 3d # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#forgotten_room_retention_period
interval: 12h forgotten_room_retention_period: 3d
- shortest_max_lifetime: 3d
interval: 1d # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#request_token_inhibit_3pid_errors
request_token_inhibit_3pid_errors: true
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#federation_domain_whitelist
{{ if eq (env "DISABLE_FEDERATION") "1" }} # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#redaction_retention_period
federation_domain_whitelist: [] {{ if (env "REDACTION_RETENTION_PERIOD") }}
{{ else if eq (env "ENABLE_ALLOWLIST") "1" }} redaction_retention_period: {{ env "REDACTION_RETENTION_PERIOD" }}
federation_domain_whitelist: {{ env "FEDERATION_ALLOWLIST" }} {{ end }}
{{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#user_ips_max_age
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#database-1 {{ if (env "USER_IPS_MAX_AGE") }}
database: user_ips_max_age: {{ env "USER_IPS_MAX_AGE" }}
name: psycopg2 {{ end }}
txn_limit: 10000
args: # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#retention
user: synapse retention:
password: "{{ secret "db_password" }}" enabled: true
database: synapse default_policy:
host: "{{ env "STACK_NAME" }}_db" min_lifetime: 1d
port: 5432 {{ if (env "RETENTION_MAX_LIFETIME") }}
cp_min: 5 max_lifetime: {{ env "RETENTION_MAX_LIFETIME" }}
cp_max: 10 {{ end }}
keepalives_idle: 10 allowed_lifetime_min: 1d
keepalives_interval: 10 {{ if (env "ALLOWED_LIFETIME_MAX") }}
keepalives_count: 3 allowed_lifetime_max: {{ env "ALLOWED_LIFETIME_MAX" }}
{{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#log_config purge_jobs:
log_config: "/data/log.config" - longest_max_lifetime: 3d
interval: 12h
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#media_store_path - shortest_max_lifetime: 3d
media_store_path: "/data/media_store" interval: 1d
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#max_upload_size # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#federation_domain_whitelist
max_upload_size: 50M {{ if eq (env "DISABLE_FEDERATION") "1" }}
federation_domain_whitelist: []
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#turn {{ else if eq (env "ENABLE_ALLOWLIST") "1" }}
{{ if eq (env "TURN_ENABLED") "1" }} federation_domain_whitelist: {{ env "FEDERATION_ALLOWLIST" }}
turn_uris: {{ env "TURN_URIS" }} {{ end }}
turn_shared_secret: "{{ secret "turn_shared_secret" }}"
turn_user_lifetime: 1h # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#database-1
turn_allow_guests: {{ env "TURN_ALLOW_GUESTS" }} database:
{{ end }} name: psycopg2
txn_limit: 10000
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#enable_registration args:
enable_registration: {{ env "ENABLE_REGISTRATION" }} user: synapse
password: "{{ secret "db_password" }}"
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#enable_3pid_lookup database: synapse
enable_3pid_lookup: {{ env "ENABLE_3PID_LOOKUP" }} host: "{{ env "STACK_NAME" }}_db"
port: 5432
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#allow_guest_access cp_min: 5
allow_guest_access: false cp_max: 10
keepalives_idle: 10
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#registration_shared_secret keepalives_interval: 10
registration_shared_secret: {{ secret "registration" }} keepalives_count: 3
{{ if eq (env "AUTO_JOIN_ROOM_ENABLED") "1" }} # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#log_config
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#auto_join_rooms log_config: "/data/log.config"
auto_join_rooms:
- "{{ env "AUTO_JOIN_ROOM" }}" # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#media_store_path
{{ end }} media_store_path: "/data/media_store"
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#report_stats # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#max_upload_size
report_stats: false max_upload_size: 50M
{{ if eq (env "APP_SERVICES_ENABLED") "1" }} # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#turn
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#app_service_config_files {{ if eq (env "TURN_ENABLED") "1" }}
app_service_config_files: {{ env "APP_SERVICE_CONFIGS" }} {{ if (env "TURN_URIS") }}
{{ end }} turn_uris: {{ env "TURN_URIS" }}
{{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#macaroon_secret_key turn_shared_secret: "{{ secret "turn_shared_secret" }}"
macaroon_secret_key: "{{ secret "macaroon" }}" turn_user_lifetime: 1h
{{ if (env "TURN_ALLOW_GUESTS") }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#form_secret turn_allow_guests: {{ env "TURN_ALLOW_GUESTS" }}
form_secret: "{{ secret "form_secret" }}" {{ end }}
{{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#signing_key_path
signing_key_path: "/data/{{ env "DOMAIN" }}.signing.key" # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#enable_registration
{{ if (env "ENABLE_REGISTRATION") }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#trusted_key_servers enable_registration: {{ env "ENABLE_REGISTRATION" }}
{{ if eq (env "ENABLE_ALLOWLIST") "1" }} {{ end }}
trusted_key_servers: [] # NOTE(d1): defaults to requesting server directly, which matches FEDERATION_ALLOWLIST
{{ else }} # https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#registration_requires_token
trusted_key_servers: {{ if (env "REGISTRATION_REQUIRES_TOKEN") }}
- server_name: "matrix.org" registration_requires_token: {{ env "REGISTRATION_REQUIRES_TOKEN" }}
{{ end }} {{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#oidc_providers # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#enable_3pid_lookup
{{ if eq (env "KEYCLOAK_ENABLED") "1" }} {{ if (env "ENABLE_3PID_LOOKUP") }}
oidc_providers: enable_3pid_lookup: {{ env "ENABLE_3PID_LOOKUP" }}
- idp_id: {{ env "KEYCLOAK_ID" }} {{ end }}
idp_name: {{ env "KEYCLOAK_NAME" }}
issuer: "{{ env "KEYCLOAK_URL" }}" # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#allow_guest_access
client_id: "{{ env "KEYCLOAK_CLIENT_ID" }}" allow_guest_access: false
client_secret: "{{ secret "keycloak_client_secret" }}"
scopes: ["openid", "profile"] # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#registration_shared_secret
allow_existing_users: {{ env "KEYCLOAK_ALLOW_EXISTING_USERS" }} registration_shared_secret: {{ secret "registration" }}
user_mapping_provider:
config: {{ if eq (env "AUTO_JOIN_ROOM_ENABLED") "1" }}
localpart_template: "{{ "{{ user.preferred_username }}" }}" # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#auto_join_rooms
display_name_template: "{{ "{{ user.name }}" }}"
# AUTO_JOIN_ROOM only for backwards compatibility
{{ if eq (env "KEYCLOAK2_ENABLED") "1" }} {{ if (env "AUTO_JOIN_ROOM") }}
- idp_id: {{ env "KEYCLOAK2_ID" }} auto_join_rooms:
idp_name: {{ env "KEYCLOAK2_NAME" }} - "{{ env "AUTO_JOIN_ROOM" }}"
issuer: "{{ env "KEYCLOAK2_URL" }}" {{ else }}
client_id: "{{ env "KEYCLOAK2_CLIENT_ID" }}" auto_join_rooms: {{ env "AUTO_JOIN_ROOM_LIST" }}
client_secret: "{{ secret "keycloak2_client_secret" }}" {{ end }}
scopes: ["openid", "profile"]
allow_existing_users: {{ env "KEYCLOAK2_ALLOW_EXISTING_USERS" }} {{ end }}
user_mapping_provider:
config: # https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#session_lifetime
localpart_template: "{{ "{{ user.preferred_username }}" }}" {{ if (env "SESSION_LIFETIME") }}
display_name_template: "{{ "{{ user.name }}" }}" session_lifetime: {{ env "SESSION_LIFETIME" }}
{{ end }} {{ end }}
{{ if eq (env "KEYCLOAK3_ENABLED") "1" }} # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#report_stats
- idp_id: {{ env "KEYCLOAK3_ID" }} report_stats: false
idp_name: {{ env "KEYCLOAK3_NAME" }}
issuer: "{{ env "KEYCLOAK3_URL" }}" # https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#track_puppeted_user_ips
client_id: "{{ env "KEYCLOAK3_CLIENT_ID" }}" {{ if (env "TRACK_PUPPETED_USER_IPS") }}
client_secret: "{{ secret "keycloak3_client_secret" }}" track_puppeted_user_ips: {{ env "TRACK_PUPPETED_USER_IPS" }}
scopes: ["openid", "profile"] {{ end }}
allow_existing_users: {{ env "KEYCLOAK3_ALLOW_EXISTING_USERS" }}
user_mapping_provider: {{ if eq (env "APP_SERVICES_ENABLED") "1" }}
config: # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#app_service_config_files
localpart_template: "{{ "{{ user.preferred_username }}" }}" app_service_config_files: {{ env "APP_SERVICE_CONFIGS" }}
display_name_template: "{{ "{{ user.name }}" }}" {{ end }}
{{ end }}
{{ end }} # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#macaroon_secret_key
macaroon_secret_key: "{{ secret "macaroon" }}"
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#sso
{{ if eq (env "KEYCLOAK_ENABLED") "1" }} # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#form_secret
sso: form_secret: "{{ secret "form_secret" }}"
client_whitelist:
- https://{{ env "KEYCLOAK_CLIENT_DOMAIN" }} # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#signing_key_path
{{ end }} signing_key_path: "/data/{{ env "DOMAIN" }}.signing.key"
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#password_config # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#old_signing_keys
password_config: {{ if (and (env "OLD_SIGNING_KEY_ID") (env "OLD_SIGNING_KEY") (env "OLD_SIGNING_KEY_EXPIRES")) }}
enabled: {{ env "PASSWORD_LOGIN_ENABLED" }} old_signing_keys:
"ed25519:{{ env "OLD_SIGNING_KEY_ID" }}": { key: "{{ env "OLD_SIGNING_KEY" }}", expired_ts: {{ env "OLD_SIGNING_KEY_EXPIRES" }} }
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#email {{ end }}
{{ if eq (env "SMTP_ENABLED") "1" }}
email: # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#trusted_key_servers
smtp_host: {{ env "SMTP_HOST" }} {{ if eq (env "ENABLE_ALLOWLIST") "1" }}
smtp_port: {{ env "SMTP_PORT" }} trusted_key_servers: [] # NOTE(d1): defaults to requesting server directly, which matches FEDERATION_ALLOWLIST
smtp_user: {{ env "SMTP_USER" }} {{ else }}
smtp_pass: "{{ secret "smtp_password" }}" trusted_key_servers:
require_transport_security: true - server_name: "matrix.org"
notif_from: Your Friendly %(app)s homeserver <{{ env "SMTP_FROM" }}> {{ end }}
app_name: {{ env "SMTP_APP_NAME" }}
enable_notifs: true # https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#oidc_providers
client_base_url: https://{{ env "DOMAIN" }} {{ if eq (env "KEYCLOAK_ENABLED") "1" }}
{{ end }} oidc_providers:
- idp_id: {{ env "KEYCLOAK_ID" }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#encryption_enabled_by_default_for_room_type idp_name: {{ env "KEYCLOAK_NAME" }}
encryption_enabled_by_default_for_room_type: {{ env "ENCRYPTED_BY_DEFAULT" }} issuer: "{{ env "KEYCLOAK_URL" }}"
client_id: "{{ env "KEYCLOAK_CLIENT_ID" }}"
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#user_directory client_secret: "{{ secret "keycloak_client_secret" }}"
user_directory: scopes: ["openid", "profile"]
enabled: true {{ if (env "KEYCLOAK_ALLOW_EXISTING_USERS") }}
search_all_users: true allow_existing_users: {{ env "KEYCLOAK_ALLOW_EXISTING_USERS" }}
prefer_local_users: true {{ end }}
user_mapping_provider:
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#media_retention config:
media_retention: localpart_template: "{{ "{{ user.preferred_username }}" }}"
local_media_lifetime: {{ env "MEDIA_RETENTION_LOCAL_LIFETIME" }} display_name_template: "{{ "{{ user.name }}" }}"
remote_media_lifetime: {{ env "MEDIA_RETENTION_REMOTE_LIFETIME" }}
{{ if eq (env "KEYCLOAK2_ENABLED") "1" }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#enable_metrics - idp_id: {{ env "KEYCLOAK2_ID" }}
enable_metrics: false idp_name: {{ env "KEYCLOAK2_NAME" }}
issuer: "{{ env "KEYCLOAK2_URL" }}"
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#track_appservice_user_ips client_id: "{{ env "KEYCLOAK2_CLIENT_ID" }}"
track_appservice_user_ips: false client_secret: "{{ secret "keycloak2_client_secret" }}"
scopes: ["openid", "profile"]
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#forget_rooms_on_leave {{ if (env "KEYCLOAK2_ALLOW_EXISTING_USERS") }}
forget_rooms_on_leave: true allow_existing_users: {{ env "KEYCLOAK2_ALLOW_EXISTING_USERS" }}
{{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#opentracing-1 user_mapping_provider:
opentracing: config:
enabled: false localpart_template: "{{ "{{ user.preferred_username }}" }}"
display_name_template: "{{ "{{ user.name }}" }}"
# https://matrix-org.github.io/synapse/develop/usage/configuration/config_documentation.html#ratelimiting {{ end }}
rc_login:
address: {{ if eq (env "KEYCLOAK3_ENABLED") "1" }}
per_second: {{ env "LOGIN_LIMIT_IP_PER_SECOND" }} - idp_id: {{ env "KEYCLOAK3_ID" }}
burst_count: {{ env "LOGIN_LIMIT_IP_BURST" }} idp_name: {{ env "KEYCLOAK3_NAME" }}
account: issuer: "{{ env "KEYCLOAK3_URL" }}"
per_second: {{ env "LOGIN_LIMIT_ACCOUNT_PER_SECOND" }} client_id: "{{ env "KEYCLOAK3_CLIENT_ID" }}"
burst_count: {{ env "LOGIN_LIMIT_ACCOUNT_BURST" }} client_secret: "{{ secret "keycloak3_client_secret" }}"
scopes: ["openid", "profile"]
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#web_client_location {{ if (env "KEYCLOAK3_ALLOW_EXISTING_USERS") }}
web_client_location: {{ env "WEB_CLIENT_LOCATION" }} allow_existing_users: {{ env "KEYCLOAK3_ALLOW_EXISTING_USERS" }}
{{ end }}
user_mapping_provider:
config:
localpart_template: "{{ "{{ user.preferred_username }}" }}"
display_name_template: "{{ "{{ user.name }}" }}"
{{ end }}
{{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#sso
{{ if eq (env "KEYCLOAK_ENABLED") "1" }}
sso:
client_whitelist:
- https://{{ env "KEYCLOAK_CLIENT_DOMAIN" }}
{{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#password_config
# With MAS (matrix_authentication_service), Synapse rejects password_config.enabled: true — set PASSWORD_LOGIN_ENABLED=false in app .env when MAS_ENABLED=1 (.env.sample).
{{ if (env "PASSWORD_LOGIN_ENABLED") }}
password_config:
enabled: {{ env "PASSWORD_LOGIN_ENABLED" }}
{{ end }}
{{ if eq (env "MAS_ENABLED") "1" }}
# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#matrix_authentication_service
matrix_authentication_service:
enabled: true
endpoint: http://{{ env "STACK_NAME"}}_mas:8080/
secret_path: /run/secrets/mas_synapse_shared
{{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#email
{{ if eq (env "SMTP_ENABLED") "1" }}
email:
smtp_host: {{ env "SMTP_HOST" }}
smtp_port: {{ env "SMTP_PORT" }}
smtp_user: {{ env "SMTP_USER" }}
smtp_pass: "{{ secret "smtp_password" }}"
require_transport_security: true
notif_from: Your Friendly %(app)s homeserver <{{ env "SMTP_FROM" }}>
app_name: {{ env "SMTP_APP_NAME" }}
enable_notifs: true
client_base_url: https://{{ env "DOMAIN" }}
{{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#encryption_enabled_by_default_for_room_type
{{ if (env "ENCRYPTED_BY_DEFAULT") }}
encryption_enabled_by_default_for_room_type: {{ env "ENCRYPTED_BY_DEFAULT" }}
{{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#user_directory
{{ if or (env "USER_DIRECTORY_ENABLED") (env "USER_DIRECTORY_SEARCH_ALL_USERS") (env "USER_DIRECTORY_PREFER_LOCAL_USERS") (env "USER_DIRECTORY_SHOW_LOCKED_USERS") }}
user_directory:
{{ if (env "USER_DIRECTORY_ENABLED") }}
enabled: {{ env "USER_DIRECTORY_ENABLED" }}
{{ end }}
{{ if (env "USER_DIRECTORY_SEARCH_ALL_USERS") }}
search_all_users: {{ env "USER_DIRECTORY_SEARCH_ALL_USERS" }}
{{ end }}
{{ if (env "USER_DIRECTORY_PREFER_LOCAL_USERS") }}
prefer_local_users: {{ env "USER_DIRECTORY_PREFER_LOCAL_USERS" }}
{{ end }}
{{ if (env "USER_DIRECTORY_SHOW_LOCKED_USERS") }}
show_locked_users: {{ env "USER_DIRECTORY_SHOW_LOCKED_USERS" }}
{{ end }}
{{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#media_retention
{{ if or (env "MEDIA_RETENTION_LOCAL_LIFETIME") (env "MEDIA_RETENTION_REMOTE_LIFETIME") }}
media_retention:
{{ if (env "MEDIA_RETENTION_LOCAL_LIFETIME") }}
local_media_lifetime: {{ env "MEDIA_RETENTION_LOCAL_LIFETIME" }}
{{ end }}
{{ if (env "MEDIA_RETENTION_REMOTE_LIFETIME") }}
remote_media_lifetime: {{ env "MEDIA_RETENTION_REMOTE_LIFETIME" }}
{{ end }}
{{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#enable_metrics
enable_metrics: false
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#track_appservice_user_ips
track_appservice_user_ips: false
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#forget_rooms_on_leave
forget_rooms_on_leave: true
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#opentracing-1
opentracing:
enabled: false
# https://matrix-org.github.io/synapse/develop/usage/configuration/config_documentation.html#ratelimiting
{{ if or (and (env "LOGIN_LIMIT_IP_PER_SECOND") (env "LOGIN_LIMIT_IP_BURST")) (and (env "LOGIN_LIMIT_ACCOUNT_PER_SECOND") (env "LOGIN_LIMIT_ACCOUNT_BURST")) }}
rc_login:
{{ if and (env "LOGIN_LIMIT_IP_PER_SECOND") (env "LOGIN_LIMIT_IP_BURST") }}
address:
per_second: {{ env "LOGIN_LIMIT_IP_PER_SECOND" }}
burst_count: {{ env "LOGIN_LIMIT_IP_BURST" }}
{{ end }}
{{ if and (env "LOGIN_LIMIT_ACCOUNT_PER_SECOND") (env "LOGIN_LIMIT_ACCOUNT_BURST") }}
account:
per_second: {{ env "LOGIN_LIMIT_ACCOUNT_PER_SECOND" }}
burst_count: {{ env "LOGIN_LIMIT_ACCOUNT_BURST" }}
{{ end }}
{{ end }}
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#web_client_location
{{ if (env "WEB_CLIENT_LOCATION") }}
web_client_location: {{ env "WEB_CLIENT_LOCATION" }}
{{ end }}

73
mas.config.yaml.tmpl Normal file
View File

@ -0,0 +1,73 @@
# Docs: https://element-hq.github.io/matrix-authentication-service/
http:
public_base: https://{{ env "DOMAIN" }}/
trusted_proxies:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
- 127.0.0.0/8
- fd00::/8
- ::1/128
listeners:
- name: web
resources:
- name: discovery
- name: human
- name: oauth
- name: compat
- name: graphql
playground: false
- name: assets
# https://element-hq.github.io/matrix-authentication-service/reference/configuration.html#httplisteners
- name: health
binds:
- address: "[::]:8080"
database:
uri: postgresql://synapse:{{ secret "db_password" }}@{{ env "STACK_NAME" }}_db:5432/mas?sslmode=disable
matrix:
kind: synapse
homeserver: {{ or (env "SERVER_NAME") (env "DOMAIN") }}
endpoint: http://{{ env "STACK_NAME" }}_app:8008/
secret_file: /run/secrets/mas_synapse_shared
secrets:
# Plain hex in file (abra: length=64 charset=hex). See .env.sample modifiers.
encryption_file: /run/secrets/mas_encryption
keys:
- key_file: /run/secrets/mas_signing_rsa
passwords:
enabled: true
schemes:
- version: 1
algorithm: bcrypt
unicode_normalization: true
- version: 2
algorithm: argon2id
{{ if env "MAS_UPSTREAM_PROVIDER_ID" }}
# https://element-hq.github.io/matrix-authentication-service/setup/sso.html
upstream_oauth2:
providers:
- id: {{ env "MAS_UPSTREAM_PROVIDER_ID" }}
{{ if env "MAS_UPSTREAM_SYNAPSE_IDP_ID" }}synapse_idp_id: {{ env "MAS_UPSTREAM_SYNAPSE_IDP_ID" }}{{ end }}
human_name: {{ or (env "MAS_UPSTREAM_HUMAN_NAME") "SSO" }}
issuer: {{ env "MAS_UPSTREAM_ISSUER" }}
client_id: {{ env "MAS_UPSTREAM_CLIENT_ID" }}
client_secret_file: /run/secrets/mas_upstream_client_secret
token_endpoint_auth_method: client_secret_basic
scope: "openid profile email"
claims_imports:
localpart:
action: require
template: "{{ "{{ user.preferred_username }}" }}"
displayname:
action: suggest
template: "{{ "{{ user.name }}" }}"
email:
action: suggest
template: "{{ "{{ user.email }}" }}"
{{ end }}

View File

@ -5,6 +5,24 @@ events {
} }
http { http {
resolver 127.0.0.11 valid=30s ipv6=off;
resolver_timeout 5s;
upstream matrix_upstream {
zone matrix_upstream 64k;
server {{ env "STACK_NAME"}}_app:8008 resolve;
keepalive 16;
}
{{ if eq (env "MAS_ENABLED") "1" }}
upstream mas_upstream {
zone mas_upstream 64k;
server {{ env "STACK_NAME"}}_mas:8080 resolve;
keepalive 8;
}
{{ end }}
server { server {
listen 80; listen 80;
@ -14,7 +32,7 @@ http {
server_name {{ env "DOMAIN" }}; server_name {{ env "DOMAIN" }};
location = / { location = / {
proxy_pass http://{{ env "STACK_NAME"}}_app:8008; proxy_pass http://matrix_upstream;
proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $host; proxy_set_header Host $host;
@ -22,8 +40,31 @@ http {
proxy_http_version 1.1; proxy_http_version 1.1;
} }
location ~* ^(\/_matrix|\/_synapse\/client) { {{ if eq (env "MAS_ENABLED") "1" }}
proxy_pass http://{{ env "STACK_NAME"}}_app:8008; # MAS on same Host as Synapse (public_base = https://$DOMAIN/): browser/OIDC paths live at repo root, not only under /_matrix/
# Router reference: element-hq/matrix-authentication-service crates/router/src/endpoints.rs
# https://element-hq.github.io/matrix-authentication-service/setup/reverse-proxy.html
location ~ ^/(complete-compat-sso/|oauth2/|\.well-known/(openid-configuration|webfinger|change-password)|authorize|login|logout|register(/|$)|account/|upstream/|consent/|link(\?|/|$)|device/|recover(/|$)|assets/|graphql(/|$)|api/) {
proxy_pass http://mas_upstream;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
client_max_body_size 50M;
}
# Matrix CS API compat (login / logout / refresh and subpaths, e.g. …/login/sso/redirect) — before generic /_matrix
location ~ ^/_matrix/client/[^/]+/(login|logout|refresh)(/.*)?$ {
proxy_pass http://mas_upstream;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
client_max_body_size 50M;
}
{{ end }}
location ~* ^(\/_matrix|\/_synapse\/client|\/_synapse\/mas) {
proxy_pass http://matrix_upstream;
proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $host; proxy_set_header Host $host;
@ -36,5 +77,20 @@ http {
default_type application/json; default_type application/json;
add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Origin *;
} }
{{ if eq (env "ADMIN_INTERFACE_ENABLED") "1" }}
location ^~ /_synapse/admin {
if ($http_referer !~ "^https://{{ env "DOMAIN" }}/admin/") {
return 403;
}
proxy_pass http://matrix_upstream;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $host;
client_max_body_size 50M;
proxy_http_version 1.1;
}
{{ end }}
} }
} }

34
pg_backup.sh Normal file
View File

@ -0,0 +1,34 @@
#!/bin/bash
set -e
BACKUP_FILE='/var/lib/postgresql/data/backup.sql'
function backup {
export PGPASSWORD=$(cat $POSTGRES_PASSWORD_FILE)
pg_dump -U ${POSTGRES_USER} ${POSTGRES_DB} | gzip > $BACKUP_FILE
}
function restore {
cd /var/lib/postgresql/data/
restore_config(){
# Restore allowed connections
cat pg_hba.conf.bak > pg_hba.conf
su postgres -c 'pg_ctl reload'
}
# Don't allow any other connections than local
cp pg_hba.conf pg_hba.conf.bak
echo "local all all trust" > pg_hba.conf
su postgres -c 'pg_ctl reload'
trap restore_config EXIT INT TERM
# Recreate Database
psql -U ${POSTGRES_USER} -d postgres -c "DROP DATABASE ${POSTGRES_DB} WITH (FORCE);"
createdb -U ${POSTGRES_USER} ${POSTGRES_DB}
gunzip -c $BACKUP_FILE | psql -U ${POSTGRES_USER} -d ${POSTGRES_DB} -1 -f -
trap - EXIT INT TERM
restore_config
}
$@

1
release/6.6.1+v1.124.0 Normal file
View File

@ -0,0 +1 @@
added env REGISTRATION_REQUIRES_TOKEN

1
release/6.6.2+v1.124.0 Normal file
View File

@ -0,0 +1 @@
new optional env vars for user_directory and privacy options

1
release/6.6.3+v1.124.0 Normal file
View File

@ -0,0 +1 @@
added env for old-signing-keys

1
release/6.7.1+v1.133.0 Normal file
View File

@ -0,0 +1 @@
This patch contains a critical nginx fix, to allow resolving docker internal hosts.

1
release/6.8.2+v1.139.2 Normal file
View File

@ -0,0 +1 @@
this patch is a reset to the state of the last known deploying version 6.8.0 so better skip 6.8.1

2
release/7.0.0+v1.149.1 Normal file
View File

@ -0,0 +1,2 @@
WARNING: Backup your database!
This upgrade switches the database image from postgres to pgautoupgrade and performs an in-place database upgrades from version 13 to 17.

1
release/7.1.0+v1.149.1 Normal file
View File

@ -0,0 +1 @@
added matrix-authentication-service as opt-in to the recipe, see readme for details

View File

@ -329,7 +329,7 @@ encryption:
# Whether to enable encryption at all. If false, the bridge will not function in encrypted rooms. # Whether to enable encryption at all. If false, the bridge will not function in encrypted rooms.
allow: {{ env "SIGNAL_ENABLE_ENCRYPTION" }} allow: {{ env "SIGNAL_ENABLE_ENCRYPTION" }}
# Whether to force-enable encryption in all bridged rooms. # Whether to force-enable encryption in all bridged rooms.
default: false default: {{ env "SIGNAL_DEFAULT_ENCRYPTION" }}
# Whether to require all messages to be encrypted and drop any unencrypted messages. # Whether to require all messages to be encrypted and drop any unencrypted messages.
require: false require: false
# Whether to use MSC2409/MSC3202 instead of /sync long polling for receiving encryption-related data. # Whether to use MSC2409/MSC3202 instead of /sync long polling for receiving encryption-related data.

View File

@ -1,5 +1,8 @@
{ {
"m.homeserver": { "m.homeserver": {
"base_url": "https://{{ env "DOMAIN" }}" "base_url": "https://{{ env "DOMAIN" }}"
} }{{ if eq (env "MAS_ENABLED") "1" }},
"org.matrix.msc2965.authentication": {
"issuer": "https://{{ env "DOMAIN" }}/"
}{{ end }}
} }