librelad b9e334dc49 matrix: add Synapse + Element as a federated chat app
Synapse on Postgres plus the Element web client, on two subdomains: the
homeserver on matrix.<domain> (which becomes server_name, so IDs read
@alice:matrix.<domain>) and Element on element.<domain>.

Two hosts rather than one because server_name then matches the host Traefik
already terminates TLS for, so 'serve_server_wellknown: true' is all the
federation delegation needed and nothing has to be published at the apex
domain — which this app has no way to configure.

CFG_MATRIX_AUTHELIA is pinned false and documented: forward-auth in front of
/_matrix locks out every client and every federating peer, since they carry
Matrix access tokens and cannot follow a redirect. Real SSO goes through the
OIDC block in resources/homeserver.yaml instead.

The install hook generates the signing key once via upstream's own 'generate'
command and refuses to regenerate it over an existing install — a new key would
be rejected by every server that had cached the old one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 05:28:31 +01:00

104 lines
4.1 KiB
YAML

# Synapse homeserver configuration.
#
# Copied to <app dir>/data/homeserver.yaml by matrix_install_post_compose, which
# substitutes the *_PLACEHOLDER values below. Edit the deployed copy, not this
# template — this one is only read at install time.
#
# Restart the container after editing: docker restart matrix-synapse
# server_name is permanent. It is signed into every event this server has ever
# sent and forms the second half of every user ID (@alice:<server_name>).
# Changing it later does not migrate anything — it orphans the whole database.
server_name: "SYNAPSE_SERVER_NAME_PLACEHOLDER"
public_baseurl: "https://SYNAPSE_SERVER_NAME_PLACEHOLDER/"
pid_file: /data/homeserver.pid
# Serve /.well-known/matrix/server ourselves, advertising port 443. Federation
# otherwise defaults to port 8448 on server_name, which Traefik is not
# listening on. Because server_name is the same host Traefik already terminates
# TLS for, this is all the delegation that is needed — nothing has to be
# published at the apex domain.
serve_server_wellknown: true
listeners:
# Port 8008 is the container-internal port and is deliberately hardcoded: it
# is what CFG_MATRIX_PORT_1 declares as the internal half of its mapping, and
# what the Traefik service label points at. Change one and you must change all
# three.
- port: 8008
tls: false
type: http
# Traefik terminates TLS and proxies onward, so the source address Synapse
# sees is Traefik's. Without this, rate limiting and the audit log would
# attribute every request in the world to a single internal IP.
x_forwarded: true
bind_addresses: ['0.0.0.0']
resources:
- names: [client, federation]
compress: false
database:
name: psycopg2
args:
user: synapse
password: "SYNAPSE_DB_PASSWORD_PLACEHOLDER"
dbname: synapse
host: matrix-postgres
port: 5432
cp_min: 5
cp_max: 10
log_config: "/data/log.config"
media_store_path: /data/media_store
signing_key_path: "/data/signing.key"
# Uploads. Raise max_upload_size if your users share video; remember the
# reverse proxy has its own limit too.
max_upload_size: 50M
# Open registration is off by default: a reachable homeserver with registration
# enabled will be found and used for spam within days. The install creates one
# admin account for you; invite everyone else, or turn this on deliberately via
# CFG_MATRIX_ENABLE_REGISTRATION and re-run the install.
enable_registration: SYNAPSE_ENABLE_REGISTRATION_PLACEHOLDER
enable_registration_without_verification: SYNAPSE_ENABLE_REGISTRATION_PLACEHOLDER
registration_shared_secret: "SYNAPSE_REGISTRATION_SECRET_PLACEHOLDER"
macaroon_secret_key: "SYNAPSE_MACAROON_SECRET_PLACEHOLDER"
form_secret: "SYNAPSE_FORM_SECRET_PLACEHOLDER"
report_stats: false
suppress_key_server_warning: true
# Which servers to fetch other servers' signing keys from. matrix.org is the
# conventional default; federation still works if it is unreachable, just more
# slowly on first contact with a new server.
trusted_key_servers:
- server_name: "matrix.org"
# ---------------------------------------------------------------------------
# Single sign-on against Authelia (optional)
# ---------------------------------------------------------------------------
# CFG_MATRIX_AUTHELIA must stay false — that switch puts Authelia's forward-auth
# in front of /_matrix, which breaks every client. Real SSO is done here
# instead, with Synapse as an OIDC client of Authelia.
#
# Register the client in Authelia's configuration.yml first, then uncomment and
# fill in the block below and restart the container.
#
# oidc_providers:
# - idp_id: authelia
# idp_name: "Authelia"
# issuer: "https://auth.<your domain>"
# client_id: "synapse"
# client_secret: "<the secret you set in Authelia>"
# scopes: ["openid", "profile", "email"]
# user_mapping_provider:
# config:
# localpart_template: "{{ user.preferred_username }}"
# display_name_template: "{{ user.name }}"
# email_template: "{{ user.email }}"
#
# The redirect URI to register in Authelia is:
# https://SYNAPSE_SERVER_NAME_PLACEHOLDER/_synapse/client/oidc/callback