Compare commits
36 Commits
6.8.3+v1.1
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 74f1adaccb | |||
| 17a399ba25 | |||
| b63dde1275 | |||
| f836c74386 | |||
| e257349b37 | |||
| 5b21a6b4f9 | |||
| b730cadb06 | |||
| 59ad89cfb4 | |||
| d75ca4f11f | |||
| cff6cfb001 | |||
| d82d539424 | |||
| b4c3db38c3 | |||
| 3f488167bc | |||
| f66bfef727 | |||
| a809333dcb | |||
| b39c60d594 | |||
| 4830b0596c | |||
| 43d68aefb4 | |||
| 91efd92d31 | |||
| 3fab725957 | |||
| c71dc162cb | |||
| 625b0381f8 | |||
| 7492e8bd4e | |||
| 60bd8b1b49 | |||
| 6f47fca73b | |||
| dd92cd4bd7 | |||
| cf30cebf8e | |||
| 5481b7e31c | |||
| 8a7978b388 | |||
| d0d5cfb1bc | |||
| 3d13505330 | |||
| 68fd515297 | |||
| 01e3feb1cf | |||
| c51120c41a | |||
| b81fecdd23 | |||
| a5a3a1938d |
130
.env.sample
130
.env.sample
@ -19,23 +19,97 @@ SECRET_FORM_SECRET_VERSION=v1
|
||||
SECRET_MACAROON_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 # Leave commented if you plan to migrate an existing homeserver
|
||||
#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 — use `abra app cmd -l YOURAPPDOMAIN generate_mas_signing_rsa`
|
||||
#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_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
|
||||
|
||||
#DISABLE_FEDERATION=1
|
||||
|
||||
# SERVE_SERVER_WELLKNOWN only works if SERVER_NAME and DOMAIN are the same
|
||||
# if they are different, then a different federation method is needed (like compose.wellknown.yml)
|
||||
# Set "true" to enable federation endpoint on $DOMAIN/.well-known/matrix/server
|
||||
SERVE_SERVER_WELLKNOWN=false
|
||||
|
||||
# Serve /.well-known/matrix/{server,client} on SERVER_NAME via Traefik.
|
||||
# Can be used when SERVER_NAME != DOMAIN and SERVER_NAME is served by Traefik.
|
||||
#COMPOSE_FILE="$COMPOSE_FILE:compose.wellknown.yml"
|
||||
|
||||
ALLOW_PUBLIC_ROOMS_FEDERATION=false
|
||||
|
||||
## Registration
|
||||
|
||||
ENABLE_REGISTRATION=false
|
||||
PASSWORD_LOGIN_ENABLED=true
|
||||
|
||||
# Token based registration. Enable ADMIN_INTERFACE (below) to use the admin interface to generate tokens.
|
||||
#REGISTRATION_REQUIRES_TOKEN=true
|
||||
|
||||
## Room auto-join
|
||||
|
||||
#AUTO_JOIN_ROOM_ENABLED=1
|
||||
@ -76,6 +150,10 @@ ENCRYPTED_BY_DEFAULT=all
|
||||
#TRACK_PUPPETED_USER_IPS=true
|
||||
|
||||
|
||||
## Room complexity limit (prevents joining large remote rooms that cause DB bloat)
|
||||
## complexity ≈ state_events / 500. Default 100.0 blocks rooms with >50000 state events.
|
||||
#ROOM_COMPLEXITY_LIMIT=100.0
|
||||
|
||||
## Retention
|
||||
|
||||
ALLOWED_LIFETIME_MAX=4w
|
||||
@ -98,30 +176,8 @@ RETENTION_MAX_LIFETIME=4w
|
||||
#LOGIN_LIMIT_ACCOUNT_PER_SECOND=1
|
||||
#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
|
||||
|
||||
#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"
|
||||
#TURN_ENABLED=1
|
||||
#TURN_URIS="[\"turns:coturn.foo.zone?transport=udp\", \"turns:coturn.foo.zone?transport=tcp\"]"
|
||||
@ -189,16 +245,18 @@ RETENTION_MAX_LIFETIME=4w
|
||||
#SECRET_SIGNAL_HS_TOKEN_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_LOCATION=https://element-web.example.com
|
||||
|
||||
|
||||
## State compression (reduces database bloat from federation)
|
||||
## Runs synapse_auto_compressor daily, built from source on first start
|
||||
#COMPOSE_FILE="$COMPOSE_FILE:compose.compress-state.yml"
|
||||
# See https://github.com/matrix-org/rust-synapse-compress-state#running-options
|
||||
#STATE_COMPRESS_CHUNK_SIZE=500
|
||||
#STATE_COMPRESS_CHUNKS=100
|
||||
#STATE_COMPRESS_SCHEDULE=0 3 * * *
|
||||
|
||||
## Admin interface at /admin
|
||||
#COMPOSE_FILE="$COMPOSE_FILE:compose.admin.yml"
|
||||
#ADMIN_INTERFACE_ENABLED=1
|
||||
|
||||
139
README.md
139
README.md
@ -39,11 +39,143 @@
|
||||
|
||||
### Enabling federation
|
||||
|
||||
See [`#27`](https://git.coopcloud.tech/coop-cloud/matrix-synapse/pulls/27) for more. Depending on your setup, using `SERVE_SERVER_WELLKNOWN=true` might work to start federating. Make sure you don't leave `DISABLE_FEDERATION=1` set!
|
||||
Federation is on by default (`DISABLE_FEDERATION=0`). Remote homeservers need a way to discover the host:port that serves your `SERVER_NAME`.
|
||||
There are three supported approaches. At least one needs to be working for federation to work (and matrix will fallback between them).
|
||||
|
||||
#### Option 1: built-in well-known (`SERVER_NAME` = `DOMAIN`)
|
||||
|
||||
Set `SERVE_SERVER_WELLKNOWN=true` and leave `SERVER_NAME` unset (defaults to `DOMAIN`). The recipe's nginx serves `/.well-known/matrix/server` and `/.well-known/matrix/client` on `DOMAIN`.
|
||||
|
||||
Suitable when users are e.g. `@alice:matrix.example.com`.
|
||||
|
||||
#### Option 2: external well-known on `SERVER_NAME`
|
||||
|
||||
Use when you want users to be e.g. `@alice:example.com` while Synapse runs at `matrix.example.com` (and SERVER_NAME is served by the same machine that Synapse is running on). Set:
|
||||
|
||||
```
|
||||
SERVER_NAME=example.com
|
||||
DOMAIN=matrix.example.com
|
||||
SERVE_SERVER_WELLKNOWN=false
|
||||
```
|
||||
|
||||
The two paths that must be served on `SERVER_NAME` are:
|
||||
|
||||
- `https://example.com/.well-known/matrix/server` → `{"m.server": "matrix.example.com:443"}`
|
||||
- `https://example.com/.well-known/matrix/client` → `{"m.homeserver": {"base_url": "https://matrix.example.com"}}`
|
||||
|
||||
**Recommended — let this recipe serve them via Traefik** by enabling `compose.wellknown.yml`:
|
||||
|
||||
```
|
||||
COMPOSE_FILE="$COMPOSE_FILE:compose.wellknown.yml"
|
||||
```
|
||||
|
||||
This publishes a Traefik router `Host(${SERVER_NAME}) && PathPrefix(/.well-known/matrix)`
|
||||
pointing at the matrix nginx, which already serves both files. The path-scoped, high-priority
|
||||
rule coexists with any apex website that also serves `Host(${SERVER_NAME})` — that site keeps
|
||||
serving everything except `/.well-known/matrix`. `SERVER_NAME` must resolve to this Traefik so
|
||||
ACME can issue its certificate.
|
||||
|
||||
**Alternative** — serve the two files yourself from whatever already hosts `example.com`.
|
||||
|
||||
|
||||
#### Option 3: Traefik `matrix-federation` entrypoint (port 8448)
|
||||
|
||||
Use when `SERVER_NAME` ≠ `DOMAIN` but you have no separate web service at `SERVER_NAME`. Remote homeservers fall back to `SERVER_NAME:8448` when there's no delegation (also requires SERVER_NAME pointing to same server that matrix is running on).
|
||||
|
||||
Requirements:
|
||||
|
||||
- [traefik](https://git.coopcloud.tech/coop-cloud/traefik) `>= 5.1.2+v3.6.15` with `MATRIX_FEDERATION_ENABLED=1` and `compose.matrix.yml` enabled.
|
||||
- `SERVER_NAME` set in your matrix-synapse env (used by the federation router's Host rule).
|
||||
|
||||
With these in place, the recipe publishes a Traefik router on `Host(${SERVER_NAME})` via the `matrix-federation` entrypoint, reusing the existing matrix nginx → synapse path.
|
||||
|
||||
|
||||
#### Option 4: DNS SRV records (usually not viable here)
|
||||
|
||||
For reasons explained below, I might be confused, but I think SRV records usually don't help with co-op cloud matrix deployments.
|
||||
|
||||
You should probably prefer Option 2 (well known), but the possibility of SRV is explained below:
|
||||
|
||||
Federation can also be delegated with a DNS `SRV` record on `SERVER_NAME` instead of well-known:
|
||||
|
||||
```
|
||||
_matrix-fed._tcp.example.com. 3600 IN SRV 10 0 8448 matrix.example.com. # modern
|
||||
_matrix._tcp.example.com. 3600 IN SRV 10 0 8448 matrix.example.com. # deprecated, for older peers
|
||||
```
|
||||
|
||||
The catch is TLS: on the SRV path a remote validates the certificate against **`SERVER_NAME`**, *not* the SRV target. This recipe's Traefik only issues a cert for **`DOMAIN`**, so:
|
||||
|
||||
- **SRV → `DOMAIN`:443 fails** — the presented cert is for `DOMAIN`, but the peer requires one for `SERVER_NAME`.
|
||||
- **SRV → `SERVER_NAME`:443 collides** — Traefik routes TLS by SNI, and `Host(SERVER_NAME)` on `:443` is already owned by whatever apex site serves `SERVER_NAME`.
|
||||
- **SRV → `SERVER_NAME`:8448 works** — the Option 3 `matrix-federation` router holds a cert for `SERVER_NAME` — but that's just Option 3 made explicit (the `:8448` fallback already works with no SRV record).
|
||||
|
||||
|
||||
#### Verifying
|
||||
|
||||
The canonical test:
|
||||
|
||||
- https://federationtester.matrix.org/#YOUR_SERVER_NAME
|
||||
|
||||
Or check the underlying paths directly. They should all return JSON:
|
||||
|
||||
```bash
|
||||
# Options 1 & 2 — delegation
|
||||
curl https://SERVER_NAME/.well-known/matrix/server
|
||||
|
||||
# Option 3 — federation endpoint via 8448
|
||||
curl https://SERVER_NAME:8448/_matrix/key/v2/server
|
||||
|
||||
# Confirms Synapse itself is healthy (independent of the path remote servers use)
|
||||
curl https://DOMAIN/_matrix/key/v2/server
|
||||
```
|
||||
|
||||
### Getting client discovery on a custom domain
|
||||
|
||||
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.
|
||||
Enable `compose.wellknown.yml` (see Option 2 above) — it serves `/.well-known/matrix/client`
|
||||
on `SERVER_NAME` too, so clients signing in as `@alice:example.com` auto-discover the homeserver.
|
||||
|
||||
### Matrix Authentication Service (MAS)
|
||||
|
||||
[MAS](https://element-hq.github.io/matrix-authentication-service/) is Element’s OAuth/OIDC-native auth service for Matrix: it handles login, tokens, and upstream IdPs while Synapse delegates authentication via `matrix_authentication_service`.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **If you plan to migrate an existing homeserver with `syn2mas`:** deploy and configure MAS as below, 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.
|
||||
|
||||
**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`
|
||||
- `abra app cmd -l YOURAPPDOMAIN generate_mas_signing_rsa` — generates and inserts the PEM RSA key for `SECRET_MAS_SIGNING_RSA_VERSION`. Requires `openssl` on the local machine.
|
||||
- `abra app cmd YOURAPPDOMAIN db ensure_mas_database` (once, creates the `mas` database in Postgres)
|
||||
- `abra app deploy YOURAPPDOMAIN`
|
||||
|
||||
<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, run `run_mas_migration` from your machine. The homeserver snapshot at `/tmp/homeserver.yaml` in `mas` must still be present from step 1.
|
||||
```bash
|
||||
abra app cmd YOURAPPDOMAIN run_mas_migration
|
||||
```
|
||||
|
||||
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
|
||||
For all Bridges:
|
||||
@ -52,6 +184,9 @@ For all Bridges:
|
||||
- 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\"}"`
|
||||
|
||||
> [!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)
|
||||
|
||||
### 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:
|
||||
|
||||
306
abra.sh
306
abra.sh
@ -1,15 +1,315 @@
|
||||
export DISCORD_BRIDGE_YAML_VERSION=v2
|
||||
export ENTRYPOINT_CONF_VERSION=v3
|
||||
export HOMESERVER_YAML_VERSION=v35
|
||||
export HOMESERVER_YAML_VERSION=v37
|
||||
export LOG_CONFIG_VERSION=v2
|
||||
export SHARED_SECRET_AUTH_VERSION=v2
|
||||
export SIGNAL_BRIDGE_YAML_VERSION=v6
|
||||
export TELEGRAM_BRIDGE_YAML_VERSION=v6
|
||||
export NGINX_CONFIG_VERSION=v12
|
||||
export NGINX_CONFIG_VERSION=v13
|
||||
export WK_SERVER_VERSION=v1
|
||||
export WK_CLIENT_VERSION=v1
|
||||
export WK_CLIENT_VERSION=v2
|
||||
export MAS_CONFIG_VERSION=v2
|
||||
export PG_BACKUP_VERSION=v2
|
||||
export ADMIN_CONFIG_VERSION=v1
|
||||
export COMPRESS_STATE_ENTRYPOINT_VERSION=v5
|
||||
|
||||
###############################################################################
|
||||
# Database maintenance — shrink a bloated Synapse database
|
||||
#
|
||||
# See https://levans.fr/shrink-synapse-database.html
|
||||
#
|
||||
# Recommended steps to reclaim disk space:
|
||||
# 1. abra app cmd <domain> compress-state run_compressor 500 10000
|
||||
# (compress redundant state — safe while Synapse is running)
|
||||
# 2. abra app cmd <domain> db reindex
|
||||
# (rebuild indexes — stop Synapse first)
|
||||
# 3. abra app cmd <domain> db vacuum_full
|
||||
# (rewrite tables and reclaim disk — stop Synapse first)
|
||||
#
|
||||
# Diagnostic commands (safe to run anytime):
|
||||
# abra app cmd <domain> db db_size
|
||||
# abra app cmd <domain> db state_bloat
|
||||
# abra app cmd <domain> db empty_rooms
|
||||
#
|
||||
# Purge commands (require an admin token):
|
||||
# abra app cmd <domain> app register_admin <user> <pass>
|
||||
# abra app cmd <domain> app get_token <user> <pass>
|
||||
# abra app cmd <domain> app purge_remote_media <days> <token>
|
||||
# abra app cmd <domain> app purge_empty_rooms <token>
|
||||
# abra app cmd <domain> app purge_room <room_id> <token>
|
||||
# abra app cmd <domain> app purge_history <room_id> <days> <token>
|
||||
###############################################################################
|
||||
|
||||
# --- Diagnostics (db) ---
|
||||
|
||||
db_size() {
|
||||
echo "=== Database size ==="
|
||||
psql -U synapse -d synapse -c "SELECT pg_size_pretty(pg_database_size('synapse')) AS db_size;"
|
||||
echo ""
|
||||
echo "=== Top 10 largest tables ==="
|
||||
psql -U synapse -d synapse -c "
|
||||
SELECT nspname || '.' || relname AS table,
|
||||
pg_size_pretty(pg_total_relation_size(C.oid)) AS total_size
|
||||
FROM pg_class C
|
||||
LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
|
||||
WHERE nspname NOT IN ('pg_catalog', 'information_schema')
|
||||
ORDER BY pg_total_relation_size(C.oid) DESC
|
||||
LIMIT 10;"
|
||||
}
|
||||
|
||||
state_bloat() {
|
||||
echo "=== Rooms with most state bloat ==="
|
||||
psql -U synapse -d synapse -c "
|
||||
SELECT room_id, count(*) AS state_entries
|
||||
FROM state_groups_state
|
||||
GROUP BY room_id
|
||||
ORDER BY state_entries DESC
|
||||
LIMIT 20;"
|
||||
}
|
||||
|
||||
empty_rooms() {
|
||||
echo "=== Rooms with no local members ==="
|
||||
psql -U synapse -d synapse -c "
|
||||
SELECT room_id, room_version
|
||||
FROM rooms
|
||||
WHERE room_id NOT IN (
|
||||
SELECT room_id FROM local_current_membership WHERE membership = 'join'
|
||||
);"
|
||||
}
|
||||
|
||||
# --- Compression (compress-state) ---
|
||||
|
||||
run_compressor() {
|
||||
CHUNK_SIZE="${1:-${STATE_COMPRESS_CHUNK_SIZE:-500}}"
|
||||
CHUNKS="${2:-${STATE_COMPRESS_CHUNKS:-100}}"
|
||||
DB_PASS=$(cat /run/secrets/db_password)
|
||||
echo "Running synapse_auto_compressor (chunk_size=$CHUNK_SIZE, chunks=$CHUNKS)..."
|
||||
/build/synapse_auto_compressor \
|
||||
-p "postgresql://synapse:${DB_PASS}@db:5432/synapse" \
|
||||
-c "$CHUNK_SIZE" -n "$CHUNKS"
|
||||
}
|
||||
|
||||
# --- Maintenance (db) — stop Synapse before running these ---
|
||||
|
||||
reindex() {
|
||||
echo "WARNING: REINDEX locks tables. Synapse should be stopped before running this."
|
||||
echo "Running REINDEX on synapse database..."
|
||||
psql -U synapse -d synapse -c "REINDEX (VERBOSE) DATABASE synapse;"
|
||||
echo "REINDEX complete."
|
||||
psql -U synapse -d synapse -c "SELECT pg_size_pretty(pg_database_size('synapse')) AS db_size;"
|
||||
}
|
||||
|
||||
vacuum_full() {
|
||||
echo "WARNING: VACUUM FULL locks tables and requires temporary disk space."
|
||||
echo "Synapse should be stopped before running this."
|
||||
echo "Running VACUUM FULL on synapse database..."
|
||||
psql -U synapse -d synapse -c "VACUUM FULL;"
|
||||
echo "VACUUM FULL complete."
|
||||
psql -U synapse -d synapse -c "SELECT pg_size_pretty(pg_database_size('synapse')) AS db_size;"
|
||||
}
|
||||
|
||||
# --- Purge commands (app) — require an admin access token ---
|
||||
|
||||
register_admin() {
|
||||
USER="${1}"
|
||||
PASS="${2}"
|
||||
if [ -z "$USER" ] || [ -z "$PASS" ]; then
|
||||
echo "Usage: register_admin <username> <password>"
|
||||
return 1
|
||||
fi
|
||||
register_new_matrix_user -u "$USER" -p "$PASS" -a -c /data/homeserver.yaml http://localhost:8008
|
||||
}
|
||||
|
||||
get_token() {
|
||||
USER="${1}"
|
||||
PASS="${2}"
|
||||
if [ -z "$USER" ] || [ -z "$PASS" ]; then
|
||||
echo "Usage: get_token <username> <password>"
|
||||
echo "Returns an admin access token for use with purge commands."
|
||||
return 1
|
||||
fi
|
||||
curl -s -X POST "http://localhost:8008/_matrix/client/r0/login" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"type\":\"m.login.password\",\"user\":\"$USER\",\"password\":\"$PASS\"}" \
|
||||
| python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('access_token', d.get('error', 'unknown error')))"
|
||||
}
|
||||
|
||||
purge_remote_media() {
|
||||
DAYS="${1:-30}"
|
||||
TOKEN="${2}"
|
||||
if [ -z "$TOKEN" ]; then
|
||||
echo "Usage: purge_remote_media <days> <admin_token>"
|
||||
return 1
|
||||
fi
|
||||
BEFORE_TS=$(( $(date +%s) * 1000 - DAYS * 86400000 ))
|
||||
echo "Purging remote media older than $DAYS days..."
|
||||
curl -s -X POST "http://localhost:8008/_synapse/admin/v1/purge_media_cache?before_ts=$BEFORE_TS" \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
echo ""
|
||||
}
|
||||
|
||||
purge_room() {
|
||||
ROOM_ID="${1}"
|
||||
TOKEN="${2}"
|
||||
if [ -z "$ROOM_ID" ] || [ -z "$TOKEN" ]; then
|
||||
echo "Usage: purge_room <room_id> <admin_token>"
|
||||
return 1
|
||||
fi
|
||||
echo "Purging room $ROOM_ID..."
|
||||
curl -s -X DELETE "http://localhost:8008/_synapse/admin/v1/rooms/$ROOM_ID" \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"purge": true}'
|
||||
echo ""
|
||||
}
|
||||
|
||||
purge_history() {
|
||||
ROOM_ID="${1}"
|
||||
DAYS="${2:-90}"
|
||||
TOKEN="${3}"
|
||||
if [ -z "$ROOM_ID" ] || [ -z "$TOKEN" ]; then
|
||||
echo "Usage: purge_history <room_id> <days> <admin_token>"
|
||||
return 1
|
||||
fi
|
||||
BEFORE_TS=$(( $(date +%s) * 1000 - DAYS * 86400000 ))
|
||||
echo "Purging history older than $DAYS days from $ROOM_ID..."
|
||||
curl -s -X POST "http://localhost:8008/_synapse/admin/v1/purge_history/$ROOM_ID" \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"purge_up_to_ts\": $BEFORE_TS}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
purge_empty_rooms() {
|
||||
TOKEN="${1}"
|
||||
if [ -z "$TOKEN" ]; then
|
||||
echo "Usage: purge_empty_rooms <admin_token>"
|
||||
return 1
|
||||
fi
|
||||
echo "Fetching rooms with no local members..."
|
||||
ROOMS=$(curl -s "http://localhost:8008/_synapse/admin/v1/rooms?limit=1000" \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
| python3 -c "
|
||||
import sys, json
|
||||
data = json.load(sys.stdin)
|
||||
for r in data.get('rooms', []):
|
||||
if r.get('joined_local_members', 0) == 0:
|
||||
print(r['room_id'])
|
||||
")
|
||||
COUNT=$(echo "$ROOMS" | grep -c '.' || true)
|
||||
echo "Found $COUNT empty rooms."
|
||||
if [ "$COUNT" -eq 0 ]; then
|
||||
echo "Nothing to purge."
|
||||
return 0
|
||||
fi
|
||||
echo "$ROOMS"
|
||||
echo ""
|
||||
echo "Purging..."
|
||||
for ROOM_ID in $ROOMS; do
|
||||
echo " Purging $ROOM_ID"
|
||||
curl -s -X DELETE "http://localhost:8008/_synapse/admin/v1/rooms/$ROOM_ID" \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"purge": true}' > /dev/null
|
||||
done
|
||||
echo "Done."
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# Other commands
|
||||
###############################################################################
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
# Generate a PEM RSA private key and insert it as the MAS signing secret.
|
||||
# `abra app secret generate` can only produce random hex/charset strings, so this
|
||||
# secret is marked `generate=false` in .env.sample and handled here instead.
|
||||
generate_mas_signing_rsa() {
|
||||
if ! command -v openssl &> /dev/null; then
|
||||
echo "openssl is required on your local machine to generate the MAS signing key."
|
||||
echo "It could not be found in your PATH, please install openssl to proceed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
KEY=$(openssl genrsa 2048 2>/dev/null)
|
||||
if [ -z "$KEY" ]; then
|
||||
echo "Failed to generate RSA private key with openssl."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if printf '%s\n' "$KEY" | abra app secret insert -C "$APP_NAME" mas_signing_rsa v1; then
|
||||
echo "MAS signing RSA key generated and inserted as v1."
|
||||
else
|
||||
echo "Failed to insert MAS signing RSA key."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Local helper: fetch homeserver.yaml from app, push to mas, then syn2mas check + dry-run.
|
||||
prepare_mas_migration () {
|
||||
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
|
||||
|
||||
echo ""
|
||||
echo "=== Next migration step: stop Synapse (downtime) ==="
|
||||
echo "Run on a host whose Docker CLI targets this Swarm (same machine you use for 'abra app deploy')."
|
||||
if [ -n "${STACK_NAME:-}" ]; then
|
||||
echo " docker service scale ${STACK_NAME}_app=0"
|
||||
else
|
||||
echo "STACK_NAME is not set here; resolve the Synapse service name with 'docker service ls' on that host, then:"
|
||||
echo "docker service scale <STACK_NAME>_app=0"
|
||||
fi
|
||||
}
|
||||
|
||||
# Run syn2mas migrate for real (writes MAS data). Run from your operator machine as MAS image is distroless.
|
||||
# Requires /tmp/homeserver.yaml in the mas container (e.g. from prepare_mas_migration) and
|
||||
# Synapse scaled down before migrate.
|
||||
run_mas_migration () {
|
||||
local syn_cfg=/tmp/homeserver.yaml
|
||||
|
||||
echo "Running mas-cli syn2mas migrate in mas via abra app run..."
|
||||
abra app run -t "$DOMAIN" mas -- mas-cli syn2mas migrate \
|
||||
--config /etc/mas/config.yaml \
|
||||
--synapse-config "$syn_cfg"
|
||||
}
|
||||
|
||||
set_admin () {
|
||||
admin=akadmin
|
||||
|
||||
@ -3,13 +3,13 @@ version: "3.8"
|
||||
|
||||
services:
|
||||
admin:
|
||||
image: awesometechnologies/synapse-admin:0.11.1
|
||||
image: awesometechnologies/synapse-admin:0.11.4
|
||||
networks:
|
||||
- proxy
|
||||
deploy:
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.docker.network=proxy"
|
||||
- "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"
|
||||
|
||||
31
compose.compress-state.yml
Normal file
31
compose.compress-state.yml
Normal file
@ -0,0 +1,31 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
compress-state:
|
||||
image: rust:1-alpine
|
||||
entrypoint: /compress_state_entrypoint.sh
|
||||
environment:
|
||||
- STATE_COMPRESS_CHUNK_SIZE=${STATE_COMPRESS_CHUNK_SIZE:-500}
|
||||
- STATE_COMPRESS_CHUNKS=${STATE_COMPRESS_CHUNKS:-100}
|
||||
- STATE_COMPRESS_SCHEDULE=${STATE_COMPRESS_SCHEDULE:-0 3 * * *}
|
||||
secrets:
|
||||
- db_password
|
||||
configs:
|
||||
- source: compress_entrypoint
|
||||
target: /compress_state_entrypoint.sh
|
||||
mode: 0555
|
||||
volumes:
|
||||
- compress_state_build:/build
|
||||
networks:
|
||||
- internal
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
|
||||
volumes:
|
||||
compress_state_build:
|
||||
|
||||
configs:
|
||||
compress_entrypoint:
|
||||
name: ${STACK_NAME}_compress_ep_${COMPRESS_STATE_ENTRYPOINT_VERSION}
|
||||
file: compress_state_entrypoint.sh
|
||||
21
compose.mas-upstream.yml
Normal file
21
compose.mas-upstream.yml
Normal 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
|
||||
|
||||
secrets:
|
||||
mas_upstream_client:
|
||||
external: true
|
||||
name: ${STACK_NAME}_mas_upstream_client_${SECRET_MAS_UPSTREAM_CLIENT_VERSION}
|
||||
64
compose.mas.yml
Normal file
64
compose.mas.yml
Normal 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}
|
||||
@ -9,7 +9,7 @@ services:
|
||||
- shared_secret_auth
|
||||
configs:
|
||||
- source: shared_secret_auth
|
||||
target: /usr/local/lib/python3.12/site-packages/shared_secret_authenticator.py
|
||||
target: /usr/local/lib/python3.13/site-packages/shared_secret_authenticator.py
|
||||
|
||||
configs:
|
||||
shared_secret_auth:
|
||||
|
||||
24
compose.wellknown.yml
Normal file
24
compose.wellknown.yml
Normal file
@ -0,0 +1,24 @@
|
||||
---
|
||||
version: "3.8"
|
||||
|
||||
# Serve /.well-known/matrix/{server,client} on SERVER_NAME via Traefik, routed to
|
||||
# the matrix nginx (`web`) — so server/client delegation works without hand-placing
|
||||
# files on whatever else hosts SERVER_NAME.
|
||||
#
|
||||
# Enable when SERVER_NAME != DOMAIN (users are @alice:example.com, Synapse runs at
|
||||
# matrix.example.com). The PathPrefix rule is more specific than a bare Host()
|
||||
# router, and the explicit high priority guarantees it wins over any apex website
|
||||
# that also serves Host(SERVER_NAME) — so the two coexist, the apex site keeps
|
||||
# serving everything except /.well-known/matrix.
|
||||
#
|
||||
# Requires SERVER_NAME to resolve to this Traefik so ACME can issue its cert.
|
||||
services:
|
||||
web:
|
||||
deploy:
|
||||
labels:
|
||||
- "traefik.http.routers.${STACK_NAME}-wellknown.rule=Host(`${SERVER_NAME}`) && PathPrefix(`/.well-known/matrix`)"
|
||||
- "traefik.http.routers.${STACK_NAME}-wellknown.entrypoints=web-secure"
|
||||
- "traefik.http.routers.${STACK_NAME}-wellknown.tls=true"
|
||||
- "traefik.http.routers.${STACK_NAME}-wellknown.tls.certresolver=${LETS_ENCRYPT_ENV}"
|
||||
- "traefik.http.routers.${STACK_NAME}-wellknown.service=${STACK_NAME}"
|
||||
- "traefik.http.routers.${STACK_NAME}-wellknown.priority=1000"
|
||||
25
compose.yml
25
compose.yml
@ -3,13 +3,14 @@ version: "3.8"
|
||||
|
||||
services:
|
||||
web:
|
||||
image: nginx:1.29.2
|
||||
image: nginx:1.29.6
|
||||
networks:
|
||||
- proxy
|
||||
- internal
|
||||
environment:
|
||||
- DOMAIN
|
||||
- STACK_NAME
|
||||
- MAS_ENABLED
|
||||
- NGINX_ACCESS_LOG_LOCATION
|
||||
- NGINX_ERROR_LOG_LOCATION
|
||||
- MAX_UPLOAD_SIZE
|
||||
@ -22,22 +23,27 @@ services:
|
||||
target: /var/www/.well-known/matrix/client
|
||||
deploy:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
condition: any
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=80"
|
||||
- "traefik.http.routers.${STACK_NAME}.rule=Host(`${DOMAIN}`)"
|
||||
- "traefik.http.routers.${STACK_NAME}.entrypoints=web-secure"
|
||||
- "traefik.http.routers.${STACK_NAME}.tls.certresolver=${LETS_ENCRYPT_ENV}"
|
||||
- "traefik.http.routers.${STACK_NAME}-federation.rule=Host(`${SERVER_NAME}`)"
|
||||
- "traefik.http.routers.${STACK_NAME}-federation.entrypoints=matrix-federation"
|
||||
- "traefik.http.routers.${STACK_NAME}-federation.tls=true"
|
||||
- "traefik.http.routers.${STACK_NAME}-federation.tls.certresolver=${LETS_ENCRYPT_ENV}"
|
||||
- "traefik.http.routers.${STACK_NAME}-federation.service=${STACK_NAME}"
|
||||
healthcheck:
|
||||
test: curl -f http://${STACK_NAME}_app:8008/health || exit 1
|
||||
interval: 30s
|
||||
timeout: 15s
|
||||
retries: 30
|
||||
start_period: 1m
|
||||
retries: 90
|
||||
start_period: 2m
|
||||
|
||||
app:
|
||||
image: "matrixdotorg/synapse:v1.139.2"
|
||||
image: "matrixdotorg/synapse:v1.149.1"
|
||||
volumes:
|
||||
- "data:/data"
|
||||
secrets:
|
||||
@ -46,6 +52,7 @@ services:
|
||||
- macaroon
|
||||
- form_secret
|
||||
environment:
|
||||
- MAS_ENABLED
|
||||
- ALLOWED_LIFETIME_MAX
|
||||
- ALLOW_PUBLIC_ROOMS_FEDERATION
|
||||
- AUTO_JOIN_ROOM
|
||||
@ -90,6 +97,7 @@ services:
|
||||
- LOGIN_LIMIT_IP_BURST=${LOGIN_LIMIT_IP_BURST:-5}
|
||||
- LOGIN_LIMIT_ACCOUNT_PER_SECOND=${LOGIN_LIMIT_ACCOUNT_PER_SECOND:-0.003}
|
||||
- LOGIN_LIMIT_ACCOUNT_BURST=${LOGIN_LIMIT_ACCOUNT_BURST:-5}
|
||||
- ROOM_COMPLEXITY_LIMIT=${ROOM_COMPLEXITY_LIMIT:-100.0}
|
||||
- WEB_CLIENT_LOCATION
|
||||
networks:
|
||||
- internal
|
||||
@ -106,7 +114,7 @@ services:
|
||||
restart_policy:
|
||||
condition: on-failure
|
||||
labels:
|
||||
- "coop-cloud.${STACK_NAME}.version=6.8.3+v1.139.2"
|
||||
- "coop-cloud.${STACK_NAME}.version=7.1.1+v1.149.1"
|
||||
- "coop-cloud.${STACK_NAME}.timeout=${TIMEOUT}"
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8008/health"]
|
||||
@ -116,21 +124,20 @@ services:
|
||||
start_period: 1m
|
||||
|
||||
db:
|
||||
image: postgres:13-alpine
|
||||
image: pgautoupgrade/pgautoupgrade:17-alpine
|
||||
secrets:
|
||||
- db_password
|
||||
environment:
|
||||
- LC_COLLATE=C
|
||||
- LC_CTYPE=C
|
||||
- POSTGRES_DB=synapse
|
||||
- POSTGRES_INITDB_ARGS="-E \"UTF8\""
|
||||
- POSTGRES_INITDB_ARGS=-E UTF8
|
||||
- POSTGRES_PASSWORD_FILE=/run/secrets/db_password
|
||||
- POSTGRES_USER=synapse
|
||||
- DOMAIN
|
||||
networks:
|
||||
- internal
|
||||
healthcheck:
|
||||
test: ["CMD", "pg_isready", "-U", "synapse"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 20
|
||||
|
||||
46
compress_state_entrypoint.sh
Normal file
46
compress_state_entrypoint.sh
Normal file
@ -0,0 +1,46 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
BINARY="/build/synapse_auto_compressor"
|
||||
REPO_DIR="/build/rust-synapse-compress-state"
|
||||
DB_PASS=$(cat /run/secrets/db_password)
|
||||
CONN="postgresql://synapse:${DB_PASS}@db:5432/synapse"
|
||||
CHUNK_SIZE="${STATE_COMPRESS_CHUNK_SIZE:-500}"
|
||||
CHUNKS="${STATE_COMPRESS_CHUNKS:-100}"
|
||||
SCHEDULE="${STATE_COMPRESS_SCHEDULE:-0 3 * * *}"
|
||||
|
||||
# Build from source if binary doesn't exist
|
||||
if [ ! -f "$BINARY" ]; then
|
||||
echo "[compress-state] Binary not found, building from source..."
|
||||
apk add --no-cache git openssl-dev openssl-libs-static perl make musl-dev jemalloc-dev
|
||||
rm -rf "$REPO_DIR"
|
||||
git clone https://github.com/matrix-org/rust-synapse-compress-state "$REPO_DIR"
|
||||
cd "$REPO_DIR"
|
||||
cargo build --release -p synapse_auto_compressor
|
||||
cp target/release/synapse_auto_compressor "$BINARY"
|
||||
echo "[compress-state] Build complete"
|
||||
# Clean up source to save space
|
||||
rm -rf "$REPO_DIR"
|
||||
else
|
||||
echo "[compress-state] Using cached binary"
|
||||
fi
|
||||
|
||||
# Run once at startup
|
||||
echo "[compress-state] Running initial compression at $(date)"
|
||||
"$BINARY" -p "$CONN" -c "$CHUNK_SIZE" -n "$CHUNKS" || echo "[compress-state] Error: $?"
|
||||
|
||||
# Set up cron job
|
||||
CRON_SCRIPT="/build/run_compressor.sh"
|
||||
cat > "$CRON_SCRIPT" <<EOF
|
||||
#!/bin/sh
|
||||
echo "[compress-state] Running at \$(date)"
|
||||
$BINARY -p "$CONN" -c $CHUNK_SIZE -n $CHUNKS || echo "[compress-state] Error: \$?"
|
||||
echo "[compress-state] Done at \$(date)"
|
||||
EOF
|
||||
chmod +x "$CRON_SCRIPT"
|
||||
|
||||
echo "$SCHEDULE $CRON_SCRIPT" | crontab -
|
||||
echo "[compress-state] Cron scheduled: $SCHEDULE"
|
||||
|
||||
# Run crond in the foreground
|
||||
exec crond -f -l 2
|
||||
@ -1,317 +1,390 @@
|
||||
# All configuration options are documented on the following link:
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html
|
||||
|
||||
{{ if eq (env "SHARED_SECRET_AUTH_ENABLED") "1" }}
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#modules-1
|
||||
modules:
|
||||
- module: shared_secret_authenticator.SharedSecretAuthProvider
|
||||
config:
|
||||
shared_secret: {{ secret "shared_secret_auth" }}
|
||||
m_login_password_support_enabled: true
|
||||
{{ end }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#server_name
|
||||
server_name: {{ or (env "SERVER_NAME") (env "DOMAIN") }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#public_baseurl
|
||||
public_baseurl: https://{{ env "DOMAIN" }}/
|
||||
|
||||
# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#require_auth_for_profile_requests
|
||||
require_auth_for_profile_requests: {{ env "REQUIRE_AUTH_FOR_PROFILE_REQUESTS" }}
|
||||
|
||||
# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#limit_profile_requests_to_users_who_share_rooms
|
||||
limit_profile_requests_to_users_who_share_rooms: {{ env "LIMIT_PROFILE_REQUESTS_TO_USERS_WHO_SHARE_ROOMS" }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#serve_server_wellknown
|
||||
serve_server_wellknown: {{ env "SERVE_SERVER_WELLKNOWN" }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#allow_public_rooms_without_auth
|
||||
allow_public_rooms_without_auth: false
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#allow_public_rooms_over_federation
|
||||
allow_public_rooms_over_federation: {{ or (env "ALLOW_PUBLIC_ROOMS_FEDERATION") "true" }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#listeners
|
||||
listeners:
|
||||
- port: 8008
|
||||
tls: false
|
||||
type: http
|
||||
x_forwarded: true
|
||||
|
||||
{{ if eq (env "DISABLE_FEDERATION") "1" }}
|
||||
resources:
|
||||
{{ if eq (env "KEYCLOAK_ENABLED") "1" }}
|
||||
- names: [client, openid]
|
||||
compress: true
|
||||
{{ else }}
|
||||
- names: [client]
|
||||
compress: true
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
resources:
|
||||
{{ if eq (env "KEYCLOAK_ENABLED") "1" }}
|
||||
- names: [client, openid, federation]
|
||||
compress: true
|
||||
{{ else }}
|
||||
- names: [client, federation]
|
||||
compress: true
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#delete_stale_devices_after
|
||||
{{ if (env "DELETE_STALE_DEVICES_AFTER") }}
|
||||
delete_stale_devices_after: {{ env "DELETE_STALE_DEVICES_AFTER" }}
|
||||
{{ end }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#admin_contact
|
||||
admin_contact: 'mailto:{{ env "ADMIN_EMAIL" }}'
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#limit_remote_rooms
|
||||
limit_remote_rooms:
|
||||
enabled: true
|
||||
complexity: 200.0
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#max_avatar_size
|
||||
max_avatar_size: 10M
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#forgotten_room_retention_period
|
||||
forgotten_room_retention_period: 3d
|
||||
|
||||
# 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#redaction_retention_period
|
||||
redaction_retention_period: {{ env "REDACTION_RETENTION_PERIOD" }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#user_ips_max_age
|
||||
user_ips_max_age: {{ env "USER_IPS_MAX_AGE" }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#retention
|
||||
retention:
|
||||
enabled: true
|
||||
default_policy:
|
||||
min_lifetime: 1d
|
||||
max_lifetime: {{ env "RETENTION_MAX_LIFETIME" }}
|
||||
allowed_lifetime_min: 1d
|
||||
allowed_lifetime_max: {{ env "ALLOWED_LIFETIME_MAX" }}
|
||||
purge_jobs:
|
||||
- longest_max_lifetime: 3d
|
||||
interval: 12h
|
||||
- shortest_max_lifetime: 3d
|
||||
interval: 1d
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#federation_domain_whitelist
|
||||
{{ if eq (env "DISABLE_FEDERATION") "1" }}
|
||||
federation_domain_whitelist: []
|
||||
{{ else if eq (env "ENABLE_ALLOWLIST") "1" }}
|
||||
federation_domain_whitelist: {{ env "FEDERATION_ALLOWLIST" }}
|
||||
{{ end }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#database-1
|
||||
database:
|
||||
name: psycopg2
|
||||
txn_limit: 10000
|
||||
args:
|
||||
user: synapse
|
||||
password: "{{ secret "db_password" }}"
|
||||
database: synapse
|
||||
host: "{{ env "STACK_NAME" }}_db"
|
||||
port: 5432
|
||||
cp_min: 5
|
||||
cp_max: 10
|
||||
keepalives_idle: 10
|
||||
keepalives_interval: 10
|
||||
keepalives_count: 3
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#log_config
|
||||
log_config: "/data/log.config"
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#media_store_path
|
||||
media_store_path: "/data/media_store"
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#max_upload_size
|
||||
max_upload_size: 50M
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#turn
|
||||
{{ if eq (env "TURN_ENABLED") "1" }}
|
||||
turn_uris: {{ env "TURN_URIS" }}
|
||||
turn_shared_secret: "{{ secret "turn_shared_secret" }}"
|
||||
turn_user_lifetime: 1h
|
||||
turn_allow_guests: {{ env "TURN_ALLOW_GUESTS" }}
|
||||
{{ end }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#enable_registration
|
||||
enable_registration: {{ env "ENABLE_REGISTRATION" }}
|
||||
|
||||
# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#registration_requires_token
|
||||
registration_requires_token: {{ env "REGISTRATION_REQUIRES_TOKEN" }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#enable_3pid_lookup
|
||||
enable_3pid_lookup: {{ env "ENABLE_3PID_LOOKUP" }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#allow_guest_access
|
||||
allow_guest_access: false
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#registration_shared_secret
|
||||
registration_shared_secret: {{ secret "registration" }}
|
||||
|
||||
{{ if eq (env "AUTO_JOIN_ROOM_ENABLED") "1" }}
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#auto_join_rooms
|
||||
|
||||
# AUTO_JOIN_ROOM only for backwards compatibility
|
||||
{{ if (env "AUTO_JOIN_ROOM") }}
|
||||
auto_join_rooms:
|
||||
- "{{ env "AUTO_JOIN_ROOM" }}"
|
||||
{{ else }}
|
||||
auto_join_rooms: {{ env "AUTO_JOIN_ROOM_LIST" }}
|
||||
{{ end }}
|
||||
|
||||
{{ end }}
|
||||
|
||||
# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#session_lifetime
|
||||
{{ if (env "SESSION_LIFETIME") }}
|
||||
session_lifetime: {{ env "SESSION_LIFETIME" }}
|
||||
{{ end }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#report_stats
|
||||
report_stats: false
|
||||
|
||||
# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#track_puppeted_user_ips
|
||||
track_puppeted_user_ips: {{ env "TRACK_PUPPETED_USER_IPS" }}
|
||||
|
||||
{{ if eq (env "APP_SERVICES_ENABLED") "1" }}
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#app_service_config_files
|
||||
app_service_config_files: {{ env "APP_SERVICE_CONFIGS" }}
|
||||
{{ 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#form_secret
|
||||
form_secret: "{{ secret "form_secret" }}"
|
||||
|
||||
# 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#old_signing_keys
|
||||
{{ if (and (env "OLD_SIGNING_KEY_ID") (env "OLD_SIGNING_KEY") (env "OLD_SIGNING_KEY_EXPIRES")) }}
|
||||
old_signing_keys:
|
||||
"ed25519:{{ env "OLD_SIGNING_KEY_ID" }}": { key: "{{ env "OLD_SIGNING_KEY" }}", expired_ts: {{ env "OLD_SIGNING_KEY_EXPIRES" }} }
|
||||
{{ end }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#trusted_key_servers
|
||||
{{ if eq (env "ENABLE_ALLOWLIST") "1" }}
|
||||
trusted_key_servers: [] # NOTE(d1): defaults to requesting server directly, which matches FEDERATION_ALLOWLIST
|
||||
{{ else }}
|
||||
trusted_key_servers:
|
||||
- server_name: "matrix.org"
|
||||
{{ end }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#oidc_providers
|
||||
{{ if eq (env "KEYCLOAK_ENABLED") "1" }}
|
||||
oidc_providers:
|
||||
- idp_id: {{ env "KEYCLOAK_ID" }}
|
||||
idp_name: {{ env "KEYCLOAK_NAME" }}
|
||||
issuer: "{{ env "KEYCLOAK_URL" }}"
|
||||
client_id: "{{ env "KEYCLOAK_CLIENT_ID" }}"
|
||||
client_secret: "{{ secret "keycloak_client_secret" }}"
|
||||
scopes: ["openid", "profile"]
|
||||
allow_existing_users: {{ env "KEYCLOAK_ALLOW_EXISTING_USERS" }}
|
||||
user_mapping_provider:
|
||||
config:
|
||||
localpart_template: "{{ "{{ user.preferred_username }}" }}"
|
||||
display_name_template: "{{ "{{ user.name }}" }}"
|
||||
|
||||
{{ if eq (env "KEYCLOAK2_ENABLED") "1" }}
|
||||
- idp_id: {{ env "KEYCLOAK2_ID" }}
|
||||
idp_name: {{ env "KEYCLOAK2_NAME" }}
|
||||
issuer: "{{ env "KEYCLOAK2_URL" }}"
|
||||
client_id: "{{ env "KEYCLOAK2_CLIENT_ID" }}"
|
||||
client_secret: "{{ secret "keycloak2_client_secret" }}"
|
||||
scopes: ["openid", "profile"]
|
||||
allow_existing_users: {{ env "KEYCLOAK2_ALLOW_EXISTING_USERS" }}
|
||||
user_mapping_provider:
|
||||
config:
|
||||
localpart_template: "{{ "{{ user.preferred_username }}" }}"
|
||||
display_name_template: "{{ "{{ user.name }}" }}"
|
||||
{{ end }}
|
||||
|
||||
{{ if eq (env "KEYCLOAK3_ENABLED") "1" }}
|
||||
- idp_id: {{ env "KEYCLOAK3_ID" }}
|
||||
idp_name: {{ env "KEYCLOAK3_NAME" }}
|
||||
issuer: "{{ env "KEYCLOAK3_URL" }}"
|
||||
client_id: "{{ env "KEYCLOAK3_CLIENT_ID" }}"
|
||||
client_secret: "{{ secret "keycloak3_client_secret" }}"
|
||||
scopes: ["openid", "profile"]
|
||||
allow_existing_users: {{ env "KEYCLOAK3_ALLOW_EXISTING_USERS" }}
|
||||
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
|
||||
password_config:
|
||||
enabled: {{ env "PASSWORD_LOGIN_ENABLED" }}
|
||||
|
||||
# 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
|
||||
encryption_enabled_by_default_for_room_type: {{ env "ENCRYPTED_BY_DEFAULT" }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#user_directory
|
||||
user_directory:
|
||||
enabled: {{ env "USER_DIRECTORY_ENABLED" }}
|
||||
search_all_users: {{ env "USER_DIRECTORY_SEARCH_ALL_USERS" }}
|
||||
prefer_local_users: {{ env "USER_DIRECTORY_PREFER_LOCAL_USERS" }}
|
||||
show_locked_users: {{ env "USER_DIRECTORY_SHOW_LOCKED_USERS" }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#media_retention
|
||||
media_retention:
|
||||
local_media_lifetime: {{ env "MEDIA_RETENTION_LOCAL_LIFETIME" }}
|
||||
remote_media_lifetime: {{ env "MEDIA_RETENTION_REMOTE_LIFETIME" }}
|
||||
|
||||
# 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
|
||||
rc_login:
|
||||
address:
|
||||
per_second: {{ env "LOGIN_LIMIT_IP_PER_SECOND" }}
|
||||
burst_count: {{ env "LOGIN_LIMIT_IP_BURST" }}
|
||||
account:
|
||||
per_second: {{ env "LOGIN_LIMIT_ACCOUNT_PER_SECOND" }}
|
||||
burst_count: {{ env "LOGIN_LIMIT_ACCOUNT_BURST" }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#web_client_location
|
||||
web_client_location: {{ env "WEB_CLIENT_LOCATION" }}
|
||||
# All configuration options are documented on the following link:
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html
|
||||
|
||||
{{ if eq (env "SHARED_SECRET_AUTH_ENABLED") "1" }}
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#modules-1
|
||||
modules:
|
||||
- module: shared_secret_authenticator.SharedSecretAuthProvider
|
||||
config:
|
||||
shared_secret: {{ secret "shared_secret_auth" }}
|
||||
m_login_password_support_enabled: true
|
||||
{{ end }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#server_name
|
||||
server_name: {{ or (env "SERVER_NAME") (env "DOMAIN") }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#public_baseurl
|
||||
public_baseurl: https://{{ env "DOMAIN" }}/
|
||||
|
||||
# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#require_auth_for_profile_requests
|
||||
{{ if (env "REQUIRE_AUTH_FOR_PROFILE_REQUESTS") }}
|
||||
require_auth_for_profile_requests: {{ env "REQUIRE_AUTH_FOR_PROFILE_REQUESTS" }}
|
||||
{{ end }}
|
||||
|
||||
# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#limit_profile_requests_to_users_who_share_rooms
|
||||
{{ if (env "LIMIT_PROFILE_REQUESTS_TO_USERS_WHO_SHARE_ROOMS") }}
|
||||
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#serve_server_wellknown
|
||||
{{ if (env "SERVE_SERVER_WELLKNOWN") }}
|
||||
serve_server_wellknown: {{ env "SERVE_SERVER_WELLKNOWN" }}
|
||||
{{ end }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#allow_public_rooms_without_auth
|
||||
allow_public_rooms_without_auth: false
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#allow_public_rooms_over_federation
|
||||
{{ if (env "ALLOW_PUBLIC_ROOMS_FEDERATION") }}
|
||||
allow_public_rooms_over_federation: {{ env "ALLOW_PUBLIC_ROOMS_FEDERATION" }}
|
||||
{{ end }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#listeners
|
||||
listeners:
|
||||
- port: 8008
|
||||
tls: false
|
||||
type: http
|
||||
x_forwarded: true
|
||||
|
||||
{{ if eq (env "DISABLE_FEDERATION") "1" }}
|
||||
resources:
|
||||
{{ if eq (env "KEYCLOAK_ENABLED") "1" }}
|
||||
- names: [client, openid]
|
||||
compress: true
|
||||
{{ else }}
|
||||
- names: [client]
|
||||
compress: true
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
resources:
|
||||
{{ if eq (env "KEYCLOAK_ENABLED") "1" }}
|
||||
- names: [client, openid, federation]
|
||||
compress: true
|
||||
{{ else }}
|
||||
- names: [client, federation]
|
||||
compress: true
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#delete_stale_devices_after
|
||||
{{ if (env "DELETE_STALE_DEVICES_AFTER") }}
|
||||
delete_stale_devices_after: {{ env "DELETE_STALE_DEVICES_AFTER" }}
|
||||
{{ end }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#admin_contact
|
||||
{{ if (env "ADMIN_EMAIL") }}
|
||||
admin_contact: 'mailto:{{ env "ADMIN_EMAIL" }}'
|
||||
{{ end }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#limit_remote_rooms
|
||||
limit_remote_rooms:
|
||||
enabled: true
|
||||
complexity: {{ env "ROOM_COMPLEXITY_LIMIT" }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#max_avatar_size
|
||||
max_avatar_size: 10M
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#forgotten_room_retention_period
|
||||
forgotten_room_retention_period: 3d
|
||||
|
||||
# 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#redaction_retention_period
|
||||
{{ if (env "REDACTION_RETENTION_PERIOD") }}
|
||||
redaction_retention_period: {{ env "REDACTION_RETENTION_PERIOD" }}
|
||||
{{ end }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#user_ips_max_age
|
||||
{{ if (env "USER_IPS_MAX_AGE") }}
|
||||
user_ips_max_age: {{ env "USER_IPS_MAX_AGE" }}
|
||||
{{ end }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#retention
|
||||
retention:
|
||||
enabled: true
|
||||
default_policy:
|
||||
min_lifetime: 1d
|
||||
{{ if (env "RETENTION_MAX_LIFETIME") }}
|
||||
max_lifetime: {{ env "RETENTION_MAX_LIFETIME" }}
|
||||
{{ end }}
|
||||
allowed_lifetime_min: 1d
|
||||
{{ if (env "ALLOWED_LIFETIME_MAX") }}
|
||||
allowed_lifetime_max: {{ env "ALLOWED_LIFETIME_MAX" }}
|
||||
{{ end }}
|
||||
purge_jobs:
|
||||
- longest_max_lifetime: 3d
|
||||
interval: 12h
|
||||
- shortest_max_lifetime: 3d
|
||||
interval: 1d
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#federation_domain_whitelist
|
||||
{{ if eq (env "DISABLE_FEDERATION") "1" }}
|
||||
federation_domain_whitelist: []
|
||||
{{ else if eq (env "ENABLE_ALLOWLIST") "1" }}
|
||||
federation_domain_whitelist: {{ env "FEDERATION_ALLOWLIST" }}
|
||||
{{ end }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#database-1
|
||||
database:
|
||||
name: psycopg2
|
||||
txn_limit: 10000
|
||||
args:
|
||||
user: synapse
|
||||
password: "{{ secret "db_password" }}"
|
||||
database: synapse
|
||||
host: "{{ env "STACK_NAME" }}_db"
|
||||
port: 5432
|
||||
cp_min: 5
|
||||
cp_max: 10
|
||||
keepalives_idle: 10
|
||||
keepalives_interval: 10
|
||||
keepalives_count: 3
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#log_config
|
||||
log_config: "/data/log.config"
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#media_store_path
|
||||
media_store_path: "/data/media_store"
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#max_upload_size
|
||||
max_upload_size: 50M
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#turn
|
||||
{{ if eq (env "TURN_ENABLED") "1" }}
|
||||
{{ if (env "TURN_URIS") }}
|
||||
turn_uris: {{ env "TURN_URIS" }}
|
||||
{{ end }}
|
||||
turn_shared_secret: "{{ secret "turn_shared_secret" }}"
|
||||
turn_user_lifetime: 1h
|
||||
{{ if (env "TURN_ALLOW_GUESTS") }}
|
||||
turn_allow_guests: {{ env "TURN_ALLOW_GUESTS" }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#enable_registration
|
||||
{{ if (env "ENABLE_REGISTRATION") }}
|
||||
enable_registration: {{ env "ENABLE_REGISTRATION" }}
|
||||
{{ end }}
|
||||
|
||||
# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#registration_requires_token
|
||||
{{ if (env "REGISTRATION_REQUIRES_TOKEN") }}
|
||||
registration_requires_token: {{ env "REGISTRATION_REQUIRES_TOKEN" }}
|
||||
{{ end }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#enable_3pid_lookup
|
||||
{{ if (env "ENABLE_3PID_LOOKUP") }}
|
||||
enable_3pid_lookup: {{ env "ENABLE_3PID_LOOKUP" }}
|
||||
{{ end }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#allow_guest_access
|
||||
allow_guest_access: false
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#registration_shared_secret
|
||||
registration_shared_secret: {{ secret "registration" }}
|
||||
|
||||
{{ if eq (env "AUTO_JOIN_ROOM_ENABLED") "1" }}
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#auto_join_rooms
|
||||
|
||||
# AUTO_JOIN_ROOM only for backwards compatibility
|
||||
{{ if (env "AUTO_JOIN_ROOM") }}
|
||||
auto_join_rooms:
|
||||
- "{{ env "AUTO_JOIN_ROOM" }}"
|
||||
{{ else }}
|
||||
auto_join_rooms: {{ env "AUTO_JOIN_ROOM_LIST" }}
|
||||
{{ end }}
|
||||
|
||||
{{ end }}
|
||||
|
||||
# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#session_lifetime
|
||||
{{ if (env "SESSION_LIFETIME") }}
|
||||
session_lifetime: {{ env "SESSION_LIFETIME" }}
|
||||
{{ end }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#report_stats
|
||||
report_stats: false
|
||||
|
||||
# https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html#track_puppeted_user_ips
|
||||
{{ if (env "TRACK_PUPPETED_USER_IPS") }}
|
||||
track_puppeted_user_ips: {{ env "TRACK_PUPPETED_USER_IPS" }}
|
||||
{{ end }}
|
||||
|
||||
{{ if eq (env "APP_SERVICES_ENABLED") "1" }}
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#app_service_config_files
|
||||
app_service_config_files: {{ env "APP_SERVICE_CONFIGS" }}
|
||||
{{ 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#form_secret
|
||||
form_secret: "{{ secret "form_secret" }}"
|
||||
|
||||
# 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#old_signing_keys
|
||||
{{ if (and (env "OLD_SIGNING_KEY_ID") (env "OLD_SIGNING_KEY") (env "OLD_SIGNING_KEY_EXPIRES")) }}
|
||||
old_signing_keys:
|
||||
"ed25519:{{ env "OLD_SIGNING_KEY_ID" }}": { key: "{{ env "OLD_SIGNING_KEY" }}", expired_ts: {{ env "OLD_SIGNING_KEY_EXPIRES" }} }
|
||||
{{ end }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#trusted_key_servers
|
||||
{{ if eq (env "ENABLE_ALLOWLIST") "1" }}
|
||||
trusted_key_servers: [] # NOTE(d1): defaults to requesting server directly, which matches FEDERATION_ALLOWLIST
|
||||
{{ else }}
|
||||
trusted_key_servers:
|
||||
- server_name: "matrix.org"
|
||||
{{ end }}
|
||||
|
||||
# https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#oidc_providers
|
||||
{{ if eq (env "KEYCLOAK_ENABLED") "1" }}
|
||||
oidc_providers:
|
||||
- idp_id: {{ env "KEYCLOAK_ID" }}
|
||||
idp_name: {{ env "KEYCLOAK_NAME" }}
|
||||
issuer: "{{ env "KEYCLOAK_URL" }}"
|
||||
client_id: "{{ env "KEYCLOAK_CLIENT_ID" }}"
|
||||
client_secret: "{{ secret "keycloak_client_secret" }}"
|
||||
scopes: ["openid", "profile"]
|
||||
{{ if (env "KEYCLOAK_ALLOW_EXISTING_USERS") }}
|
||||
allow_existing_users: {{ env "KEYCLOAK_ALLOW_EXISTING_USERS" }}
|
||||
{{ end }}
|
||||
user_mapping_provider:
|
||||
config:
|
||||
localpart_template: "{{ "{{ user.preferred_username }}" }}"
|
||||
display_name_template: "{{ "{{ user.name }}" }}"
|
||||
|
||||
{{ if eq (env "KEYCLOAK2_ENABLED") "1" }}
|
||||
- idp_id: {{ env "KEYCLOAK2_ID" }}
|
||||
idp_name: {{ env "KEYCLOAK2_NAME" }}
|
||||
issuer: "{{ env "KEYCLOAK2_URL" }}"
|
||||
client_id: "{{ env "KEYCLOAK2_CLIENT_ID" }}"
|
||||
client_secret: "{{ secret "keycloak2_client_secret" }}"
|
||||
scopes: ["openid", "profile"]
|
||||
{{ if (env "KEYCLOAK2_ALLOW_EXISTING_USERS") }}
|
||||
allow_existing_users: {{ env "KEYCLOAK2_ALLOW_EXISTING_USERS" }}
|
||||
{{ end }}
|
||||
user_mapping_provider:
|
||||
config:
|
||||
localpart_template: "{{ "{{ user.preferred_username }}" }}"
|
||||
display_name_template: "{{ "{{ user.name }}" }}"
|
||||
{{ end }}
|
||||
|
||||
{{ if eq (env "KEYCLOAK3_ENABLED") "1" }}
|
||||
- idp_id: {{ env "KEYCLOAK3_ID" }}
|
||||
idp_name: {{ env "KEYCLOAK3_NAME" }}
|
||||
issuer: "{{ env "KEYCLOAK3_URL" }}"
|
||||
client_id: "{{ env "KEYCLOAK3_CLIENT_ID" }}"
|
||||
client_secret: "{{ secret "keycloak3_client_secret" }}"
|
||||
scopes: ["openid", "profile"]
|
||||
{{ if (env "KEYCLOAK3_ALLOW_EXISTING_USERS") }}
|
||||
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
73
mas.config.yaml.tmpl
Normal 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
|
||||
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 }}
|
||||
@ -15,6 +15,14 @@ http {
|
||||
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 {
|
||||
listen 80;
|
||||
|
||||
@ -32,7 +40,30 @@ http {
|
||||
proxy_http_version 1.1;
|
||||
}
|
||||
|
||||
location ~* ^(\/_matrix|\/_synapse\/client) {
|
||||
{{ if eq (env "MAS_ENABLED") "1" }}
|
||||
# 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-Proto https;
|
||||
|
||||
2
release/7.0.0+v1.149.1
Normal file
2
release/7.0.0+v1.149.1
Normal 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
1
release/7.1.0+v1.149.1
Normal file
@ -0,0 +1 @@
|
||||
added matrix-authentication-service as opt-in to the recipe, see readme for details
|
||||
6
renovate.json
Normal file
6
renovate.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": [
|
||||
"config:recommended"
|
||||
]
|
||||
}
|
||||
@ -1,5 +1,8 @@
|
||||
{
|
||||
"m.homeserver": {
|
||||
"base_url": "https://{{ env "DOMAIN" }}"
|
||||
}
|
||||
}{{ if eq (env "MAS_ENABLED") "1" }},
|
||||
"org.matrix.msc2965.authentication": {
|
||||
"issuer": "https://{{ env "DOMAIN" }}/"
|
||||
}{{ end }}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user