Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ repos:
- id: end-of-file-fixer
exclude: ".*.sql"
- id: check-yaml
exclude: "templates/.*\\.yaml"
- id: check-added-large-files
- id: check-case-conflict
- id: check-json
Expand Down
60 changes: 60 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,61 @@
# docker-synapse-server

Matrix homeserver (Synapse) for the Deploy App integration stack.

## DNS records required

Two public DNS records must point to your WAN address:

- `synapse.domain` — Matrix homeserver; Element clients connect here and federation traffic arrives here
- `matrix.domain` — Deploy App Matrix integration UI/API (matrixrmapi)
- `mtls.matrix.domain` — mTLS access to the matrix integration API

## Environment variables

### Required

| Variable | Description |
|---|---|
| `SYNAPSE_DATABASE_PASSWORD` | PostgreSQL password for the `synapse` database |
| `SYNAPSE_MACAROON_SECRET_KEY` | Secret used to sign Synapse macaroon tokens. Generate with `openssl rand -hex 32` |
| `SYNAPSE_REGISTRATION_SECRET` | Shared secret used by matrixrmapi to register the admin bot. Generate with `openssl rand -hex 32` |

### Optional

| Variable | Default | Description |
|---|---|---|
| `SYNAPSE_BOT_USERNAME` | `matrixrmapi-bot` | Local part of the Synapse admin bot user |
| `SYNAPSE_FEDERATION` | `*` | Federation mode (see below) |

### Federation modes

`SYNAPSE_FEDERATION` controls server-to-server federation:

```
SYNAPSE_FEDERATION="*" # open — federate with any Matrix server (default)
SYNAPSE_FEDERATION="off" # disabled — no server-to-server traffic at all
SYNAPSE_FEDERATION="pvarki.fi,ally.org" # allowlist — only the listed domains
```

### Database variables (set automatically from the compose stack)

| Variable | Description |
|---|---|
| `POSTGRES_HOST` | PostgreSQL hostname |
| `POSTGRES_USER` | PostgreSQL user |
| `POSTGRES_DB` | PostgreSQL database name |

## Rooms and spaces created automatically

On first startup, matrixrmapi creates a Space and four rooms scoped to the deployment:

| Key | Alias pattern | Purpose |
|---|---|---|
| space | `#<deployment>-space:<domain>` | Top-level Space; all users auto-join |
| general | `#<deployment>-general:<domain>` | General work discussion |
| helpdesk | `#<deployment>-helpdesk:<domain>` | Issue reporting and help |
| offtopic | `#<deployment>-offtopic:<domain>` | Off-topic conversation |
| admin | `#<deployment>-admin:<domain>` | Admin-only channel |

All rooms use end-to-end encryption and restricted join rules (Space membership required).
Admins promoted in Deploy App receive power level 100 and are joined to the admin channel automatically.
27 changes: 27 additions & 0 deletions scripts/synapse-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,35 @@ else
export SYNAPSE_PUBLIC_BASEURL="https://synapse.${SERVER_DOMAIN}:${NGINX_HTTPS_PORT}"
fi

export DEPLOYMENT_NAME="${SERVER_DOMAIN%%.*}"

if [[ ! -f "$CONFIG_FILE" ]]; then
echo "Creating homeserver.yaml..."

# Compute the federation config block injected as ${SYNAPSE_FEDERATION_CONFIG}.
# SYNAPSE_FEDERATION controls the mode:
# * (default) — open federation with any server
# off / false / no — fully disabled
# domain1.tld,domain2.tld — allowlist specific servers only
case "${SYNAPSE_FEDERATION:-*}" in
off|false|no)
echo "Federation: disabled"
export SYNAPSE_FEDERATION_CONFIG="# Federation disabled — no server-to-server traffic allowed.
federation_domain_whitelist: []"
;;
"*"|"")
echo "Federation: open (all servers)"
export SYNAPSE_FEDERATION_CONFIG="# Federation open — this server can communicate with any Matrix server."
;;
*)
echo "Federation: allowlist — ${SYNAPSE_FEDERATION}"
DOMAIN_LINES=$(echo "${SYNAPSE_FEDERATION}" | tr ',' '\n' | sed 's/^[[:space:]]*/ - /' | sed 's/[[:space:]]*$//')
export SYNAPSE_FEDERATION_CONFIG="# Federation restricted to listed servers only.
federation_domain_whitelist:
${DOMAIN_LINES}"
;;
esac

mkdir -p "$DATA_DIR"
envsubst < "$CONFIG_TEMPLATE" > "$CONFIG_FILE"
chown -R 991:991 "$DATA_DIR"
Expand Down
48 changes: 45 additions & 3 deletions templates/homeserver.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,20 @@ listeners:
type: http
x_forwarded: true
resources:
- names: [client]
- names: [client, federation]
compress: false
- port: 8008
tls: false
type: http
x_forwarded: true
resources:
- names: [client]
- names: [client, federation]
compress: false

report_stats: no
media_store_path: /data/media_store
max_upload_size: 50M
max_image_pixels: 32M

allow_profile_lookup_over_federation: false
allow_public_rooms_over_federation: false
Expand All @@ -33,9 +35,49 @@ room_list_publication_rules:
- user_id: "*"
action: allow
allow_guest_access: false

registration_shared_secret: "${SYNAPSE_REGISTRATION_SECRET}"

auto_join_rooms:
- "#${DEPLOYMENT_NAME}-space:${SERVER_DOMAIN}"
- "#${DEPLOYMENT_NAME}-general:${SERVER_DOMAIN}"
- "#${DEPLOYMENT_NAME}-helpdesk:${SERVER_DOMAIN}"
- "#${DEPLOYMENT_NAME}-offtopic:${SERVER_DOMAIN}"
autocreate_auto_join_rooms: false
auto_join_rooms_for_guests: false
auto_join_mxid_localpart: "${SYNAPSE_BOT_USERNAME}"

rc_joins:
local:
per_second: 10
burst_count: 50
remote:
per_second: 0.01
burst_count: 3
per_room:
per_second: 50
burst_count: 100

rc_invites:
per_user:
per_second: 10
burst_count: 50
per_room:
per_second: 10
burst_count: 50

rc_presence:
per_user:
per_second: 10
burst_count: 50

enable_registration: false
enable_registration_without_verification: false
federation_domain_whitelist: []

${SYNAPSE_FEDERATION_CONFIG}
# Never use matrix.org as a key server — avoids leaking room/user metadata to a third party.
trusted_key_servers: []
suppress_key_server_warning: true

database:
name: psycopg2
Expand Down