Skip to content

Releases: wlphi/ess-docker-compose

v1.6.4

12 May 12:33

Choose a tag to compare

Bug Fix

  • Fix Element Desktop native OIDC login: MAS was missing loopback redirect URIs for the Element Web/Desktop OIDC client. Without http://localhost registered, MAS rejects the authorization request when Element Desktop (≥1.11) attempts native OIDC, forcing fallback to the legacy compat SSO (login-token) flow. Added http://localhost and http://127.0.0.1 — per RFC 8252, these match any port on the loopback address.

Upgrading

Regenerate mas/config/config.yaml to pick up the new redirect URIs:

git pull
./deploy.sh   # or ./quickstart.sh for single-machine deployments
docker compose restart mas

Or add them manually to mas/config/config.yaml under the 01HQW90Z35CMXFJWQPHC3BGZGQ client:

      - 'http://localhost'
      - 'http://127.0.0.1'

Then: docker compose restart mas

v1.7.0

11 May 12:04

Choose a tag to compare

Replaces element-admin with Ketesa. Adds FluffyChat as an optional second web client (also registers it as a MAS OIDC client, which fixes the cross-signing reset "continue" button). Adds Prometheus + Grafana monitoring, Discord and Slack Go megabridges, matrix-hookshot, and a self-building synapse_auto_compressor container for continuous DB state compression.

New features

  • Ketesa replaces element-admin (admin panel, user/room management)
  • FluffyChat optional profile (--profile fluffychat); MAS client registered even without self-hosting so native apps work
  • Prometheus + Grafana monitoring profile with pre-provisioned Synapse dashboard (ID 10046)
  • Discord and Slack bridges use Go megabridge implementations
  • matrix-hookshot optional profile (GitHub, GitLab, JIRA, webhooks)
  • synapse_auto_compressor built from source, runs alongside Postgres for continuous DB state compression

Fixes

  • synapse_auto_compressor: install from GitHub (not crates.io); add make for jemalloc build
  • MAS FluffyChat client ID was 27 chars with invalid Crockford character — caused crash-loop on startup
  • Telegram bridge config updated for Go bridge database.uri format

Testing

  • SKIP_DOCKER=true mode: 355 config-generation assertions pass without a live Docker daemon
  • Full Docker run: 424 assertions pass

v1.6.3

10 May 13:41

Choose a tag to compare

Bug Fixes

  • Fix telegram bridge database not configured after setup: setup-bridges.sh was targeting the old Python bridge scalar key (database: postgres://...). The Go rewrite restructured this into a block with database.uri. The sed pattern now correctly targets uri: so the postgres connection string is actually written into the config.
  • Add element-admin to local compose: The service was routed in the local Caddyfile but the container was missing from compose-variants/docker-compose.local.yml, causing 502 errors in local testing. Added with healthcheck.
  • Add healthcheck to element-admin in both compose files (wget -qO- http://localhost:8080/health).

Upgrading

Pull the latest and re-run bridge setup if you use the Telegram bridge:

git pull
./setup-bridges.sh

If running local mode, recreate the element-admin container:

git pull
docker compose -f compose-variants/docker-compose.local.yml up -d element-admin

v1.6.2

05 May 06:07

Choose a tag to compare

Bug Fixes

  • Fix Caddy crash on startup (matcher is defined more than once: @preflight): The @preflight named matcher was defined twice within the same Caddy site block — once for OPTIONS /_matrix/* and again inside the /_synapse/admin* handler. Renamed the latter to @admin_preflight. Affected local mode, production mode, and quickstart.

Upgrading

Re-run ./deploy.sh or ./quickstart.sh to regenerate the Caddyfile. Or manually rename the duplicate in caddy/Caddyfile:

Inside the handle /_synapse/admin* block, change:

@preflight method OPTIONS
respond @preflight "" 204

to:

@admin_preflight method OPTIONS
respond @admin_preflight "" 204

Then: docker compose exec caddy caddy reload --config /etc/caddy/Caddyfile

v1.6.1 — Permission regression test coverage

22 Apr 15:29

Choose a tag to compare

Test coverage

Added assertions that catch the issue #21 class of permission regressions on every test run:

  • mas/config/ must be world-executable (mode ≥ 755) — MAS container (UID 65532) must enter it
  • mas/config/config.yaml must be world-readable (mode ≥ 644) — MAS must read its config
  • mas/data/ must be owned by UID 65532
  • synapse/data/ must be owned by UID 991
  • .env must not be world-readable (mode 600)

No functional changes. If you're on v1.6 everything is already correct — this release only adds test guards.

Upgrading

git pull

No restart needed.

v1.6 — Element Admin CORS fix, permission fixes, CORS test coverage

22 Apr 13:26

Choose a tag to compare

Bug fixes

  • Element Admin CORS error (#22) — All API requests in the admin panel failed with browser CORS errors. The /_synapse/admin/* route returned 403 with no CORS headers, blocking the browser before requests reached Synapse. Replaced with a CORS-enabled proxy scoped to your admin domain. Synapse's own admin token auth remains the security boundary.
  • MAS config permissionsmas/config/ was set to 700 and config.yaml to 600, which prevented the MAS container (uid 65532) from reading its own config. Fixed to 755/644.
  • quickstart.sh: Synapse image not built before startdocker compose up could pull a stale image if the build step hadn't run. Fixed to build explicitly before starting.

Test coverage

Added live HTTP response CORS assertions for all user-facing endpoints. Previous tests only verified Caddyfile text contained the right config strings — a Caddy syntax error could silently drop headers and tests would still pass. Now the integration suite sends an actual Origin header and checks the response:

  • /_synapse/admin/* — scoped to admin domain origin
  • /_matrix/client/versions
  • /_matrix/client/v3/login
  • MAS /.well-known/openid-configuration

Upgrading from v1.5

git pull
docker compose pull
docker compose up -d

⚠ Existing deployments — Element Admin CORS fix requires a manual Caddyfile edit.
docker compose up -d pulls new images but does not regenerate your caddy/Caddyfile. The old 403 block stays on disk until you update it.

Find this block in caddy/Caddyfile inside your matrix.<domain> vhost:

handle /_synapse/admin* {
    respond "Forbidden" 403
}

Replace it with:

handle /_synapse/admin* {
    header Access-Control-Allow-Origin "https://admin.<your-domain>"
    header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
    header Access-Control-Allow-Headers "Authorization, Content-Type, Accept"
    @preflight method OPTIONS
    respond @preflight "" 204
    reverse_proxy synapse:8008 {
        header_down -Access-Control-Allow-Origin
    }
}

Then reload Caddy (no restart needed):

docker compose exec caddy caddy reload --config /etc/caddy/Caddyfile

v1.5.2

21 Apr 17:39

Choose a tag to compare

Bug Fixes

  • Fix MAS startup failure (Error: missing field 'secrets'): mas/config/ was set to chmod 700, blocking MAS (UID 65532) from reading its config. Changed to chmod 755/644. Also fixes mas/data/ ownership which was incorrectly set to Synapse's UID (991) instead of MAS's UID (65532).
  • Fix Synapse image on fresh install: quickstart.sh now runs docker compose build synapse before starting the stack, so Docker builds the local image instead of trying to pull matrix-synapse:local from the registry.
  • Guard openssl key generation: quickstart.sh now fails immediately with a clear message if openssl is unavailable instead of silently producing a broken MAS config.

Upgrading

git pull
chmod 755 mas/config
chmod 644 mas/config/config.yaml
sudo chown -R 65532:65532 mas/data/
docker compose restart mas

v1.5 — MAS config fixes, OIDC, single-server mode, security hardening

20 Apr 16:24

Choose a tag to compare

Bug fixes

  • Element Admin broke on new installs (#19) — SERVER_NAME was incorrectly set to MATRIX_DOMAIN in docker-compose.yml. Element Admin requires the bare server name (e.g. example.com), not the Matrix subdomain.
  • LiveKit secret rejected (#20) — generate_secret() produces base64-like output; go-jose requires a pure hex string. Switched to generate_hex_secret() (64 hex chars) for LIVEKIT_SECRET.
  • Open registration silently broken (#18) — MAS ignored the registration policy due to incorrect config structure (policy.registration instead of policy.data.registration) and a non-existent require_email field. Fixed across deploy.sh, quickstart.sh, and the template.

MAS config correctness

  • Added missing passwords.schemes block (argon2id, minimum_complexity: 3) — without this, MAS v1.11+ rejects the config entirely and won't start.
  • Added account: block with password_registration_enabled, password_registration_email_required, password_change_allowed, etc.
  • Fixed policy.data.registration nesting (was one level too shallow).
  • Updated templates/mas-config.yaml to match the corrected structure.

LiveKit security

  • Added room.auto_create: false to livekit.yaml — without this, anyone with a valid JWT can create arbitrary rooms on your LiveKit server.

Element Web

  • Removed participant_limit from Element Call config — deprecated field, rejected in recent Element Web versions.

Synapse

  • Added enable_authenticated_media: true to homeserver.yaml — prevents unauthenticated media access (hardening, not a breaking change).
  • Added synapse/Dockerfile + synapse/requirements.txt — drop Python packages (e.g. synapse-s3-storage-provider) into requirements.txt to install them into the Synapse image at build time. Empty file = no-op.

New: generic OIDC upstream provider

deploy.sh now offers a third SSO option alongside "None" and "Authelia":

3) Other OIDC — Authentik, Keycloak, Zitadel, or any OIDC-compliant provider

Prompts for issuer URL, client ID, and client secret. Generates the upstream_oauth2: block in the MAS config automatically. No extra containers needed.

New: production single-server deployment mode

deploy.sh now has three deployment types:

Choice Mode Description
1 Local testing Self-signed certs, *.example.test domains
2 Production (single-server) Let's Encrypt, all services on one machine
3 Production (distributed) Caddy / Authelia / Matrix on separate hosts

Single-server mode generates a proper Caddyfile with Let's Encrypt and starts the stack with --profile single-machine automatically.

Security

  • mas/config/ set to 700, mas/config/config.yaml set to 600 — was world-readable, exposed database credentials and signing keys.
  • .env set to 600 — was world-readable, exposed all secrets.
  • OIDC client secret no longer echoed to terminal during input (read -s).

Upgrading from v1.4

git pull
docker compose pull
docker compose up -d --build

If you have a running MAS and your mas/config/config.yaml was generated by an older version:

  1. Open mas/config/config.yaml and check the policy: section. If it looks like this:

    policy:
      registration:
        enabled: false

    Change it to:

    policy:
      data:
        registration:
          enabled: false
  2. Add the passwords.schemes block if missing (MAS v1.11+ requires it):

    passwords:
      enabled: true
      minimum_complexity: 3
      schemes:
        - version: 1
          algorithm: argon2id
  3. Fix permissions:

    chmod 700 mas/config
    chmod 600 mas/config/config.yaml
    chmod 600 .env
  4. Restart MAS: docker compose restart mas

If you used Element Call and LiveKit isn't accepting connections, regenerate LIVEKIT_SECRET:

new_secret=$(openssl rand -hex 32)
sed -i "s/^LIVEKIT_SECRET=.*/LIVEKIT_SECRET=${new_secret}/" .env
# Update livekit/livekit.yaml key_secret to match, then:
docker compose restart livekit lk-jwt-service

Breaking change: mautrix-telegram Go rewrite

The mautrix-telegram image was rewritten from Python to Go. Two permission level names changed in bridges/telegram/config/config.yaml:

Old (Python) New (Go)
relaybot relay
full user

If you have an existing Telegram bridge deployment, edit bridges/telegram/config/config.yaml before or after pulling the new image:

# Change this:
bridge:
  permissions:
    '*': relaybot
    'example.com': full

# To this:
bridge:
  permissions:
    '*': relay
    'example.com': user

Then restart: docker compose restart mautrix-telegram

No data loss, no database migration — config key rename only.

v1.4.1 — permission fix & templates clarification

10 Apr 08:05

Choose a tag to compare

What's new

  • Permission fix — Synapse/MAS data directories created with correct ownership on new installs (fixes #17)
  • templates/ clarification — added README noting these are reference files generated by deploy.sh, not for manual editing

Upstream component updates

No config changes required. Images are on :latest — run docker compose pull to update.

Component Latest
Synapse v1.151.0
MAS v1.15.0
Element Web v1.12.15
Element Call v0.19.0
LiveKit v1.10.1
Authelia v4.39.18

Note: Authelia v4.39.17 tightened domain matching — review your access_control rules after upgrading.

Upgrade

git pull && git checkout v1.4.1 && docker compose pull

v1.4.0 — quickstart.sh security fixes & full test coverage

30 Mar 07:10

Choose a tag to compare

What's new

  • quickstart.sh security fixes — synced with the security hardening applied to deploy.sh in v1.3.x:

    • Caddy admin API bound to localhost:2019 only (was 0.0.0.0:2019)
    • /_synapse/admin endpoints now blocked (403) at the reverse proxy
    • Host and X-Forwarded-Host headers forwarded to MAS on all proxy blocks (fixes silent OAuth2 breakage)
    • /account/ portal route uses handle instead of handle_path (prefix was being stripped, breaking MAS SPA routing)
    • allow_guest_access, allow_public_rooms_without_auth, allow_public_rooms_over_federation set to false in Synapse config
    • Fixed sed -i permission error on Synapse config after docker run generate
  • Expanded test coverage — test_deploy.sh now covers all described install scenarios:

    • Scenario P: production Caddyfile (caddy/Caddyfile.production) config assertions
    • Scenario Q: quickstart.sh config assertions (all 5 security properties verified)
    • SKIP_START=true support added to both deploy.sh and quickstart.sh for config-only CI testing

Upgrade

git pull && git checkout v1.4.0