diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..3c9fd8e --- /dev/null +++ b/.env.example @@ -0,0 +1,18 @@ +# FEDEO Matrix-Kommunikation +# +# Diese Werte werden von docker-compose.yml gelesen, wenn das Profil "matrix" +# genutzt wird. Für produktive Systeme müssen alle Geheimnisse ersetzt werden. + +MATRIX_SERVER_NAME=fedeo.de +MATRIX_HOMESERVER_HOST=matrix.fedeo.de +MATRIX_RTC_HOST=call.fedeo.de +MATRIX_TURN_HOST=turn.fedeo.de + +MATRIX_POSTGRES_DB=synapse +MATRIX_POSTGRES_USER=synapse +MATRIX_POSTGRES_PASSWORD=change-this-matrix-db-password + +MATRIX_TURN_SHARED_SECRET=change-this-turn-secret + +LIVEKIT_KEY=fedeo-livekit +LIVEKIT_SECRET=change-this-livekit-secret diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ab1815e --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.env + +# Lokale Runtime-Daten und generierte Konfigurationen +matrix/postgres/ +matrix/synapse/ diff --git a/docker-compose.yml b/docker-compose.yml index 7263a44..b57bca1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -71,6 +71,182 @@ services: - "traefik.http.routers.fedeo-backend-secure.entrypoints=web-secured" # - "traefik.http.routers.fedeo-backend-secure.tls.certresolver=mytlschallenge" - "traefik.http.routers.fedeo-backend-secure.middlewares=fedeo-backend-strip" + matrix-db: + image: postgres:16-alpine + restart: unless-stopped + profiles: + - matrix + environment: + - POSTGRES_DB=${MATRIX_POSTGRES_DB:-synapse} + - POSTGRES_USER=${MATRIX_POSTGRES_USER:-synapse} + - POSTGRES_PASSWORD=${MATRIX_POSTGRES_PASSWORD:-change-this-matrix-db-password} + - POSTGRES_INITDB_ARGS=--encoding=UTF8 --lc-collate=C --lc-ctype=C + volumes: + - ./matrix/postgres:/var/lib/postgresql/data + networks: + - traefik + + matrix-redis: + image: redis:7-alpine + restart: unless-stopped + profiles: + - matrix + networks: + - traefik + + matrix-synapse: + image: ghcr.io/element-hq/synapse:latest + restart: unless-stopped + profiles: + - matrix + depends_on: + - matrix-db + - matrix-redis + environment: + - SYNAPSE_CONFIG_PATH=/data/homeserver.yaml + volumes: + - ./matrix/synapse:/data + networks: + - traefik + labels: + - "traefik.enable=true" + - "traefik.docker.network=traefik" + - "traefik.port=8008" + - "traefik.http.services.fedeo-matrix.loadbalancer.server.port=8008" + # Matrix Client-Server API + - "traefik.http.routers.fedeo-matrix.rule=Host(`${MATRIX_HOMESERVER_HOST:-matrix.fedeo.de}`) && PathPrefix(`/_matrix`)" + - "traefik.http.routers.fedeo-matrix.entrypoints=web" + - "traefik.http.routers.fedeo-matrix.middlewares=fedeo-matrix-redirect-web-secure" + - "traefik.http.routers.fedeo-matrix.service=fedeo-matrix" + - "traefik.http.middlewares.fedeo-matrix-redirect-web-secure.redirectscheme.scheme=https" + - "traefik.http.routers.fedeo-matrix-secure.rule=Host(`${MATRIX_HOMESERVER_HOST:-matrix.fedeo.de}`) && PathPrefix(`/_matrix`)" + - "traefik.http.routers.fedeo-matrix-secure.entrypoints=web-secured" + - "traefik.http.routers.fedeo-matrix-secure.tls.certresolver=mytlschallenge" + - "traefik.http.routers.fedeo-matrix-secure.service=fedeo-matrix" + # Matrix Federation API, nur öffnen wenn Federation gewünscht ist. + - "traefik.http.routers.fedeo-matrix-federation.rule=Host(`${MATRIX_HOMESERVER_HOST:-matrix.fedeo.de}`) && PathPrefix(`/_matrix/federation`)" + - "traefik.http.routers.fedeo-matrix-federation.entrypoints=web-secured" + - "traefik.http.routers.fedeo-matrix-federation.tls.certresolver=mytlschallenge" + - "traefik.http.routers.fedeo-matrix-federation.service=fedeo-matrix" + + matrix-well-known: + image: nginx:1.27-alpine + restart: unless-stopped + profiles: + - matrix + volumes: + - ./matrix/well-known:/usr/share/nginx/html/.well-known/matrix:ro + networks: + - traefik + labels: + - "traefik.enable=true" + - "traefik.docker.network=traefik" + - "traefik.port=80" + - "traefik.http.services.fedeo-matrix-well-known.loadbalancer.server.port=80" + - "traefik.http.middlewares.fedeo-matrix-well-known-cors.headers.accesscontrolalloworiginlist=*" + - "traefik.http.middlewares.fedeo-matrix-well-known-cors.headers.accesscontrolallowmethods=GET,OPTIONS" + - "traefik.http.middlewares.fedeo-matrix-well-known-cors.headers.accesscontrolallowheaders=Content-Type,Authorization" + - "traefik.http.routers.fedeo-matrix-well-known.rule=Host(`${MATRIX_SERVER_NAME:-fedeo.de}`) && PathPrefix(`/.well-known/matrix`)" + - "traefik.http.routers.fedeo-matrix-well-known.entrypoints=web-secured" + - "traefik.http.routers.fedeo-matrix-well-known.tls.certresolver=mytlschallenge" + - "traefik.http.routers.fedeo-matrix-well-known.middlewares=fedeo-matrix-well-known-cors" + - "traefik.http.routers.fedeo-matrix-well-known.service=fedeo-matrix-well-known" + + matrix-turn: + image: instrumentisto/coturn:4 + restart: unless-stopped + profiles: + - matrix + command: + - --fingerprint + - --use-auth-secret + - --static-auth-secret=${MATRIX_TURN_SHARED_SECRET:-change-this-turn-secret} + - --realm=${MATRIX_SERVER_NAME:-fedeo.de} + - --listening-port=3478 + - --tls-listening-port=5349 + - --min-port=49160 + - --max-port=49200 + - --no-cli + - --no-tlsv1 + - --no-tlsv1_1 + ports: + - "3478:3478/tcp" + - "3478:3478/udp" + - "5349:5349/tcp" + - "49160-49200:49160-49200/udp" + networks: + - traefik + + matrix-livekit: + image: livekit/livekit-server:v1.9 + restart: unless-stopped + profiles: + - matrix + depends_on: + - matrix-redis + entrypoint: /bin/sh + command: + - -ec + - | + cat >/tmp/livekit.yaml <" + database: synapse + host: matrix-db + cp_min: 5 + cp_max: 10 + +redis: + enabled: true + host: matrix-redis + +turn_uris: + - "turn::3478?transport=udp" + - "turn::3478?transport=tcp" +turn_shared_secret: "" +turn_user_lifetime: "1h" + +experimental_features: + msc3266_enabled: true + msc4222_enabled: true + +max_event_delay_duration: 24h +rc_message: + per_second: 0.5 + burst_count: 30 +rc_delayed_event_mgmt: + per_second: 1 + burst_count: 20 +``` + +## Start + +```bash +docker compose --profile matrix up -d +``` + +Ohne Profil startet weiterhin nur der bisherige FEDEO-Stack: + +```bash +docker compose up -d +``` + +## Hinweise + +- Die Matrix-Services sind bewusst im bestehenden Compose-Stack definiert, damit FEDEO nicht in mehrere Deployment-Dateien zerfällt. +- Die aktuellen Ports für TURN und LiveKit müssen auf der Firewall des Servers freigegeben werden. +- Federation sollte erst nach einer expliziten Entscheidung geöffnet werden. Für B2B-Kommunikation ist eine Allowlist sinnvoll. +- Die Werte in `.env.example` sind Platzhalter und nicht produktionssicher. diff --git a/matrix/well-known/client b/matrix/well-known/client new file mode 100644 index 0000000..8be3bb0 --- /dev/null +++ b/matrix/well-known/client @@ -0,0 +1,11 @@ +{ + "m.homeserver": { + "base_url": "https://matrix.fedeo.de" + }, + "org.matrix.msc4143.rtc_foci": [ + { + "type": "livekit", + "livekit_service_url": "https://call.fedeo.de/livekit/jwt" + } + ] +} diff --git a/matrix/well-known/server b/matrix/well-known/server new file mode 100644 index 0000000..0703b40 --- /dev/null +++ b/matrix/well-known/server @@ -0,0 +1,3 @@ +{ + "m.server": "matrix.fedeo.de:443" +}