wmair c7fffdf4bb Update docs: element-admin port, bridge guide, production ports
SETUP.md:
- element-admin access URL: port 8081 → 8091
- Replace incorrect "no authentication by default" note with correct
  description of MAS/OIDC auth and required env vars
- netstat grep: port 8081 → 8091

PRODUCTION_DEPLOYMENT.md:
- Backend port list: 8090 → 8083 (element-call) + add 8091 (element-admin)

BRIDGE_SETUP_GUIDE.md:
- doublepuppet url: "" → url: null (empty string causes Synapse transaction
  retry loops; null tells Synapse the appservice has no HTTP endpoint)
- WhatsApp/Signal encryption examples: remove non-existent fields
  allow_key_sharing and self_sign; fix section nesting (top-level in
  megabridge format, not nested under bridge:)
- Script description: rewrite to match what setup-bridges.sh actually does
  (hostname 0.0.0.0, file permissions, conditional Telegram)
- Telegram: document TELEGRAM_API_ID/HASH requirement before running script
- Future encryption section: remove outdated self_sign field, update note
  to reflect current status (MAS appservice login not yet implemented)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 13:06:28 +01:00

Matrix Server - Docker Compose Setup

A self-hosted Matrix server stack with modern OIDC authentication, web client, optional video calling, and optional messaging bridges.

What's Included

Core (always on)

Optional: Element Call (--profile element-call)

  • LiveKit — WebRTC SFU media server (self-hosted, media stays on your server)
  • lk-jwt-service — LiveKit token issuer
  • Element Call — Self-hosted video/voice calling frontend

Optional: Messaging Bridges (via setup-bridges.sh)

Optional: Upstream OIDC (--profile authelia)

Quick Start

./deploy.sh

The script handles everything interactively: generates secrets, writes configs, starts Docker services. It asks whether to enable Element Call and optionally Authelia.

Bridges are set up separately after the core stack is running:

./setup-bridges.sh

Architecture

Browser
  |
Caddy (HTTPS, Let's Encrypt)
  |
  +-- matrix.example.com  -->  Synapse :8008
  |     /.well-known       -->  (inline, served by Caddy)
  |     /login, /logout    -->  MAS :8080
  +-- auth.example.com    -->  MAS :8080
  +-- element.example.com -->  Element Web :80
  +-- admin.example.com   -->  Element Admin :8080
  +-- call.example.com    -->  Element Call :8080   (optional)
  +-- rtc.example.com     -->  lk-jwt-service :8080 (optional)
                               LiveKit :7880         (optional)

All services communicate over an internal Docker network. The database is not exposed.

Deployment Options

Local testing — self-signed certificates, all services on localhost:

docker compose -f docker-compose.yml -f compose-variants/docker-compose.local.yml up -d

Single server — production with Caddy on the same machine:

./deploy.sh  # choose "single server" mode

Multi-server — Matrix backend on one machine, Caddy on another:

./deploy.sh  # choose "multi server" mode

The script generates a caddy/Caddyfile.production for the Caddy machine.

Element Call

When enabled, all three components are self-hosted. Media streams never leave your server (they route through your LiveKit SFU). The Element Call frontend is served from your own call. subdomain instead of call.element.io.

Required open ports for LiveKit:

  • TCP 7881 (WebRTC signaling)
  • UDP 5010050200 (media streams)

Bridges

setup-bridges.sh configures WhatsApp and Signal automatically. Telegram requires API credentials from my.telegram.org — add them to .env before running:

TELEGRAM_API_ID=your_id
TELEGRAM_API_HASH=your_hash

Bridges use double puppet support (users in Matrix rooms appear as themselves, not the bridge bot) and have encryption disabled for compatibility with MAS.

Requirements

  • Docker and Docker Compose v2
  • A domain with DNS control
  • Ports 80 and 443 accessible from the internet
  • For Element Call: ports 7881/TCP and 5010050200/UDP open

Common Operations

# Status
docker compose ps

# Logs
docker compose logs -f [service]

# Restart a service
docker compose restart synapse

# Update all images
docker compose pull && docker compose up -d

# Bridge logs
docker compose logs mautrix-whatsapp

Data Directories

postgres/data/    database
synapse/data/     media store, signing keys
mas/data/         MAS sessions
.env              all secrets and domain config

Backup:

tar -czf matrix-backup-$(date +%Y%m%d).tar.gz postgres/data synapse/data mas/data .env

Documentation

License

  • Synapse: Apache 2.0
  • Matrix Authentication Service: Apache 2.0
  • Element Web / Element Admin / Element Call: Apache 2.0
  • PostgreSQL: PostgreSQL License
  • Caddy: Apache 2.0
  • LiveKit: Apache 2.0
S
Description
Element Server Suite on Docker Compose
Readme 270 KiB
Languages
Shell 100%