41 Commits

Author SHA1 Message Date
wmair 9dc60194c7 Sync quickstart.sh with deploy.sh security fixes; add production + quickstart test scenarios
quickstart.sh:
- admin localhost:2019 (was 0.0.0.0:2019 — exposed admin API publicly)
- Add /_synapse/admin block returning 403
- Forward Host + X-Forwarded-Host headers to MAS on all proxy blocks
- handle /account/* (was handle_path — stripped prefix, broke MAS SPA routing)
- Add allow_guest_access/allow_public_rooms_* false to Synapse config
- sudo chown synapse/data/ after docker run generate (sed -i needs ownership)

deploy.sh:
- Add SKIP_START=true env var to skip docker compose up (enables config-only CI testing)

test_deploy.sh:
- Scenario P: production Caddyfile assertions (caddy/Caddyfile.production)
- Scenario Q: quickstart.sh config assertions
- assert_quickstart_configs(): 15 assertions covering all previously-missed security properties

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v1.4.0
2026-03-30 09:08:50 +02:00
wmair 6d9b156738 Expand test coverage and fix /_synapse/admin in local mode
test_deploy.sh:
- Add curl_local_status helper (returns HTTP status code)
- Config assertions: MAS public_base/issuer/endpoint, Synapse MAS endpoint,
  registration disabled, allow_public_rooms_* false, Caddyfile admin binding,
  X-Forwarded-Host header, /_synapse/admin block, m.authentication in well-known
- Endpoint assertions: OIDC issuer + authorization_endpoint domain (issue #16
  regression), well-known m.authentication.issuer, Synapse /versions,
  login compat proxy to MAS, /_synapse/admin 403

deploy.sh:
- Add /_synapse/admin block to local Caddyfile generation (was production-only)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v1.3.1
2026-03-27 20:34:14 +01:00
wmair 7353cae399 Fix MAS authorization: forward Host and X-Forwarded-Host headers
Caddy does not set X-Forwarded-Host by default. Without it, MAS cannot
verify the request host when building OAuth2 redirect URIs, causing the
login "Continue" button to do nothing.

Added header_up Host and X-Forwarded-Host to all MAS reverse_proxy
blocks in both local and production Caddyfile generation.

Fixes #16

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 20:23:02 +01:00
wmair 88806d12fb Security hardening: Caddy admin API, Synapse admin endpoint, public room settings
- Caddy admin API: bind to localhost:2019 instead of 0.0.0.0:2019 (local + production)
- Production Caddyfile: block /_synapse/admin* with 403 (not needed publicly)
- homeserver.yaml: explicitly set allow_public_rooms_without_auth/over_federation to false

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 09:10:36 +01:00
wmair 74b0a3ecb9 Fix well-known CORS header missing on production Caddy config 2026-03-24 08:55:38 +01:00
wmair 0799cd3e38 Fix two deploy.sh bugs: Caddy handle_path strips /account/, cert copy needs sudo
- Replace handle_path /account/* with handle /account/* in both local and
  production Caddyfile templates. handle_path was stripping the /account/
  prefix before proxying to MAS, causing MAS to serve the root landing page
  instead of the account management SPA — making it impossible to edit
  account data.

- Fix Caddy CA cert extraction: use sudo cp/chmod (caddy/data/ is root-owned
  via Docker) and replace the one-shot sleep check with a retry loop (24×5s)
  that triggers curl on each iteration to prompt Caddy to generate the cert.
  Previously the cert copy silently failed, leaving MAS in a crash loop.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-22 19:24:05 +01:00
wmair e2f578fde5 Fix MAS adminapi listener missing — Element Admin panel broken
Add `adminapi` resource to MAS HTTP listener in deploy.sh and quickstart.sh.
Without it, MAS never served /api/admin/v1/... causing Element Admin to always
throw TypeError: Failed to fetch. Updated docs and added regression test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v1.3
2026-03-19 17:16:44 +01:00
wmair ff3143cd1f Auto-generate doublepuppet appservice registration during deployment
deploy.sh now generates appservices/doublepuppet.yaml with fresh random
tokens on every run and registers it in homeserver.yaml under
app_service_config_files. The user regex is scoped to SERVER_NAME so it
works correctly in both TLD and subdomain identity modes.

test_deploy.sh: add 7 assertions per scenario (14 total) verifying the
file exists, tokens are present, and homeserver.yaml references it.
All 66 tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v1.1 v1.2
2026-03-02 20:53:41 +01:00
wmair 9318a69eae gitignore: exclude appservices/ (contains deployment-specific tokens)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 20:42:15 +01:00
wmair 26993e8a6f Add TLD identity support, integration tests, and CI pipeline
- deploy.sh: add SERVER_NAME prompt so users can choose @user:example.com
  (TLD) vs @user:matrix.example.com (subdomain); wire SERVER_NAME through
  .env, MAS config, Element config, Synapse init, and both Caddyfiles
- deploy.sh: add identity-domain well-known delegation block to local and
  production Caddyfiles when SERVER_NAME != MATRIX_DOMAIN
- deploy.sh: remove -it flag from synapse docker run (non-interactive);
  fix synapse/data ownership (uid 991) around homeserver.yaml modifications
- test_deploy.sh: new integration test suite — two scenarios (TLD + subdomain),
  config-file assertions, live endpoint checks, automatic teardown; 52/52 passing
- .gitlab-ci.yml: new CI pipeline with full (25 min) and config-only (12 min) jobs
- .gitignore: add caddy/Caddyfile (now generated); remove both Caddyfiles from tracking

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 19:30:17 +01:00
wmair 4e43a6f713 Add custom Docker registry and hardened image support
All image references in docker-compose.yml and docker-compose.local.yml
are replaced with ${IMAGE_VAR:-default} env var syntax, so compose files
work standalone without .env while deploy.sh writes resolved image paths.

deploy.sh gains two new prompts:
- Custom registry prefix (prepended to all image names)
- Hardened images from dhi.io for Redis/PostgreSQL/Caddy (takes priority
  over custom registry for those three)

Compared to PR #10: interactive prompts instead of hardcoded vars,
no sed-based compose file mutation, all 14 images covered (PR #10 missed
element-admin, element-call, lk-jwt-service, and all 3 bridges), and
standalone compose usage is preserved via :-default fallbacks.

SETUP.md and README.md document the feature including a note on
pull-through cache registries (Harbor/Artifactory/Nexus) that require
the full docker.io/ path prefix in image names.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 09:55:18 +01:00
wmair e789b845cb Rewrite all documentation to reflect current project state
- README: add quickstart.sh as primary entry point, update deployment options
- SETUP.md: replace stale manual wizard with accurate manual config reference
- QUICK_REFERENCE.md: remove emojis/AI fluff, update compose commands, fix stale paths
- BUGFIXES.md: fix compose command references, add CVE-2025-49090, remove emojis

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v1.0
2026-03-01 14:37:09 +01:00
wmair 9e42903b1f Fix quickstart.sh issues found during testing
- Wipe postgres/data when user confirms overwrite (password mismatch fix)
- Start only core services to avoid bridge restart loop noise
- Suppress Authelia env var warnings with empty .env entries

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 14:29:03 +01:00
wmair c674619cb2 Add quickstart.sh for simple single-machine deployment
Stripped-down alternative to deploy.sh aimed at users with little
hosting experience. Asks three questions (domain, Let's Encrypt email,
Element Call yes/no), generates all secrets and configs automatically,
and starts the full stack with a single command.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 14:20:03 +01:00
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
wmair ac40364f65 Add self-hosted Element Call frontend container
Previously Element Call used call.element.io for the frontend JS while
routing media through a local LiveKit SFU. This adds the self-hosted
Element Call frontend so no requests go to Element's CDN at all.

Changes:
- docker-compose.yml: add element-call service (ghcr.io/element-hq/element-call)
  under the element-call profile, port 8083:8080. No config required — the app
  reads the Matrix homeserver from URL params passed by Element Web, and gets
  the livekit_service_url from the homeserver's .well-known/matrix/client.
- caddy/Caddyfile: add call.example.test:443 virtual host for local dev.
- deploy.sh: add CALL_DOMAIN variable (call.example.test / call.<domain>),
  prompt for call subdomain in production mode, write CALL_DOMAIN to .env,
  update element_call.url from call.element.io to the self-hosted CALL_DOMAIN
  in all three places (element/config.json generator and both Caddyfile
  inline JSON strings), add Caddy blocks for CALL_DOMAIN in local and
  production Caddyfile generation, add CALL_DOMAIN to /etc/hosts hint,
  update summary output.
- README.md: rewrite to reflect actual project state — deploy.sh workflow,
  all optional components, correct architecture diagram, bridge setup, ports.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 12:54:40 +01:00
wmair 973fb631c5 Fix element-admin port and env vars; document Caddy inline JSON pitfall
Production deployment revealed two bugs:

1. element-admin container port changed to 8080 in recent image versions
   (was 80). Update docker-compose.yml port mapping 8091:80 → 8091:8080,
   and Caddy reverse_proxy targets in deploy.sh and caddy/Caddyfile.

2. element-admin requires SERVER_NAME, OIDC_CLIENT_ID, OIDC_ISSUER env vars
   to function. Add them to the docker-compose.yml service definition using
   the stack's existing MATRIX_DOMAIN, AUTH_DOMAIN variables and the
   corrected MAS client ID 01ADMN00000000000000000000.

3. Document Caddy inline-JSON single-line requirement: if a `respond` body
   containing JSON is manually edited and an editor wraps the line, Caddy
   refuses to start with "invalid control character in string". Add warning
   comments to both affected respond blocks in caddy/Caddyfile.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 12:41:06 +01:00
wmair 69b645580b Fix bridge setup: 7 bugs resolved, bridges confirmed working end-to-end
Setup-bridges.sh complete rewrite and bug fixes:
- Fix YAML ordering bug: bare app_service_config_files: key was added then
  immediately removed before entries were appended, leaving orphaned list
  items and breaking Synapse YAML parsing. Rewrite as atomic teardown+rebuild.
- Fix appservice section accumulation: remove old comment line on each run
  so comments do not pile up across re-runs.
- Fix bridge listen address: megabridges default to hostname 127.0.0.1,
  which prevents Synapse (different container) from pinging back. Add sed
  to set hostname to 0.0.0.0 for both WhatsApp and Signal.
- Fix missing chmod: registration.yaml files created by bridge containers
  are root:root 600; Synapse cannot read them. Add chmod 644 after wait loop.
- Fix sed ordering: all removals now run before the fresh section is written.
- Conditionalize Telegram on TELEGRAM_API_ID/HASH presence in .env.
- Fix WhatsApp/Signal sed patterns: correct 4-space megabridge indentation,
  add missing homeserver address update (example.localhost→synapse:8008),
  replace double_puppet placeholder directly instead of inserting new block,
  remove broken encryption range sed (allow_key_sharing field not present).

Tested: WhatsApp and Signal bridges start cleanly, connect to Synapse,
register bot users, migrate databases, and reach UNCONFIGURED state
(waiting for user logins) without restart loops.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 12:36:15 +01:00
wmair 9cd680f5d0 Fix setup-bridges.sh grep false-positive on commented app_service_config_files
homeserver.yaml contains a commented-out '# app_service_config_files:' line
(from the template). The unanchored grep matched it, causing the script to
skip adding the real key — resulting in appservice list entries being appended
directly into the preceding rc_delayed_event_mgmt block (invalid YAML).

Fix: anchor grep with ^ so only an actual key at column 0 matches.

Discovered during local integration test of setup-bridges.sh.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 11:26:52 +01:00
wmair 8738178c03 Fix doublepuppet appservice null URL to stop Synapse transaction retries
Synapse continuously retries HTTP transactions to any appservice with a
non-null URL. Setting url: null (not url: "") tells Synapse this appservice
has no HTTP endpoint, stopping the retry loop.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 11:10:44 +01:00
wmair 31009a376e Fix MAS client ID (Issue #7) and add optional Element Call (Issues #5/#8)
- Fix invalid MAS admin client ID: 01ADMIN000000000000000000 → 01ADMN00000000000000000000
  (was 25 chars and contained 'I', both invalid for Crockford base32/ULID)
- Add Element Call (LiveKit SFU) as an optional feature prompted in deploy.sh
  - Adds livekit + lk-jwt-service services with element-call Docker Compose profile
  - Generates livekit/livekit.yaml at deploy time (excluded from git, contains secrets)
  - Conditionally adds MSC3266/4222/4140 to Synapse experimental_features
  - Conditionally adds element_call block to Element Web config and rtc_foci to well-known
  - Adds Caddy routing for /livekit/jwt and /livekit/sfu under RTC domain
- Fix Synapse MAS config: migrate from removed experimental_features.msc3861 to
  stable matrix_authentication_service: block (Synapse 1.137+)
- Fix Docker Compose v5 path resolution: add --project-directory . for local mode
- Fix cleanup to use correct compose project scope

Tested locally: core stack (no Element Call) and full stack (with Element Call) both pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 11:07:26 +01:00
wmair 3357bfb191 Set default room version to 12 (CVE-2025-49090 fix) 2026-02-17 10:15:04 +01:00
wmair a33c6eed57 Update MAS config template for v1.11.0 compatibility
- Switch http.listeners to binds: list format
- Add internal health listener on 127.0.0.1:8081
- Add http.trusted_proxies (RFC 1918 + loopback) for Caddy
- Add database connect/idle/max_lifetime timeouts
- Change password scheme from bcrypt to argon2id with minimum_complexity: 3
- Add matrix.kind: synapse
- Move registration under policy.registration
- Remove graphql.playground: false (not in generated config)
- Document Synapse CVE-2026-24044 security release in BUGFIXES.md
2026-02-17 09:47:20 +01:00
wmair fff5d935e0 Fix Synapse container permission errors by using
official generate command

Fixes #4

Replace manual homeserver.yaml template copying with the official
Synapse
docker generate command. This resolves permission errors and missing
configuration files that prevented Synapse from starting.

Changes:
- Step 4: Use docker generate command instead of template copying
- Step 9a: Remove synapse/data from mkdir (created by generate command)
- Update all path references from synapse/config to synapse/data
- Update backup section to reflect correct directory structure
- Fix incorrect line number reference for database section

The generate command creates homeserver.yaml with correct permissions
(UID 991) and generates required signing keys automatically.
2026-01-23 08:42:07 +01:00
wmair e06860f6ea Fix MAS v1.8.0 compatibility issues
Addresses three breaking changes in MAS v1.8.0:

1. Database separation (wlphi/ess-docker-compose#1)
   - Update mas-config.yaml to use dedicated 'mas' database
   - Database is created by postgres/init/01-init-databases.sql

2. Signing key format (wlphi/ess-docker-compose#2)
   - Replace hex string keys with EC private keys
   - Update key generation: openssl ecparam -name prime256v1 -genkey
   - Add reference to official MAS signing keys documentation
   - Update templates and docs to reflect new key format

3. CLI syntax change (wlphi/ess-docker-compose#3)
   - Update register-user command to use positional username
   - Old: --username admin
   - New: admin (positional argument)
2026-01-11 11:50:43 +01:00
wmair c6264a2c5e Add WhatsApp bridge encryption fix with double puppet support
Problem:
- WhatsApp bridge cannot respond to messages in encrypted Matrix rooms
- Root cause: Synapse 1.144.0 has incomplete MSC4190 implementation with MAS
- Bridge encryption (MSC4190) is incompatible with MAS authentication

Solution:
- Implement double puppet appservices for better message attribution
- Disable bridge encryption (use unencrypted Matrix rooms)
- Configure all bridges with proper encryption flags for future compatibility

Changes:
- Add templates/doublepuppet.yaml: Appservice template for double puppet
- Update setup-bridges.sh: Automated setup with double puppet + encryption config
- Update BRIDGE_SETUP_GUIDE.md: Comprehensive double puppet setup guide
- Update templates/homeserver.yaml: Add MSC flags and appservice section
- Update docker-compose files: Mount appservices directory in Synapse

Technical details:
- Double puppet allows bridges to send as actual user (not bot)
- Encryption disabled: allow: false, msc4190: false
- Future-ready: MSC flags configured for when Synapse fixes compatibility
- All changes tested and validated with simulated bridge configs

Users can now run ./setup-bridges.sh to automatically configure bridges
with working message attribution in unencrypted rooms.
2026-01-06 15:44:14 +01:00
wmair 0b583f9726 Update bridge docs to reflect MAS setup without encryption
Changes:
- Add clear warning at top: MAS is used, encryption is disabled
- Update all bridge config examples to show encryption: allow: false
- Remove misleading MSC4190/MSC3202 instructions for registration.yaml
- Make it clear this is a MAS-first setup where encryption won't work

This ensures users understand upfront that:
- MAS is required for this deployment
- Bridge encryption is incompatible with MAS
- All configs reflect the non-encrypted bridge setup

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-01 11:52:48 +01:00
wmair 83fd416d39 Add Element Admin and update to stable MAS integration
Major improvements:
- Add Element Admin service for user/room management
- Upgrade to stable MAS integration (Synapse 1.136+)
- Add QR code login support (MSC4108) with rendezvous endpoints
- Fix CORS header duplication by stripping backend headers
- Document known MAS + encrypted bridge compatibility issue
- Add bridge encryption configuration examples (MSC3202/MSC4190)
- Update deploy.sh to support Element Admin domain configuration
- Remove stale bridge registrations during deployment

Breaking changes:
- MSC3861 experimental config replaced with stable matrix_authentication_service
- Synapse OIDC client no longer needed in MAS config

Known issues:
- Encrypted bridges incompatible with MAS (appservice login not supported)
- QR code login may fail with NotImplementedError on some setups
- Workaround: Disable encryption in bridge configs until MAS adds appservice support

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-01 11:47:08 +01:00
wmair 82bc5c2131 Improve setup guide with phase-based structure and verification checkpoints 2025-10-31 15:05:04 +01:00
wmair cc5a903896 Add Matrix server setup guide and configuration templates 2025-10-30 21:58:11 +01:00
wmair 94f3dcd951 Expose ports to host for multi-machine deployment
- Change 'expose' to 'ports' for Synapse (8008, 8448)
- Change 'expose' to 'ports' for MAS (8080, 8081)
- Change 'expose' to 'ports' for Element (80->8090)
- Allows external reverse proxies to reach services
- Fixes 502 errors in multi-machine deployments

Without this, ports are only accessible within Docker network

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 20:11:42 +01:00
wmair c09f3fc661 Always update database password in homeserver.yaml on re-deploy
- Split config generation from database section update
- Generate homeserver.yaml only if missing (preserves custom configs)
- Always update database credentials section (matches current .env)
- Always update MAS integration section
- Preserves custom configurations like mail setup
- Fixes password authentication failures on re-deployment

Resolves Issue #9 while maintaining user customizations

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 19:51:35 +01:00
wmair 739bdec4fb Use surgical cleanup: preserve homeserver.yaml customizations
- Only remove postgres/data (fixes password mismatch)
- Preserve synapse/data/homeserver.yaml (keeps mail config, etc.)
- Preserve mas/config (keeps CLIENT_SECRET for Authelia)
- Stop containers before cleanup to prevent database locks
- Remove only regenerable data (mas/data, certs, bridges)

Fixes Issue #9 without destroying user customizations

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 19:47:31 +01:00
wmair fb51f930f1 Fix bridge setup script compose file references
- Remove all -f docker-compose.local.yml flags
- Use default docker-compose.yml instead
- Fixes 'no such file or directory' error after compose file restructuring

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 19:39:12 +01:00
wmair 5a5f1105ce Preserve CLIENT_SECRET during automatic cleanup
- Extract CLIENT_SECRET from mas/config/config.yaml before cleanup
- Reuse preserved secret when re-deploying with Authelia
- Prevents breaking Authelia integration on re-deployment
- Fixes Issue #9 (PostgreSQL password mismatch) while maintaining OAuth connection
- Regenerates hash from preserved secret for Authelia config
2025-10-29 19:38:28 +01:00
wmair 56ca4119ea Remove unnecessary prompts for multi-machine production deployment
Removed Prompts:
- Matrix server IP (3 prompts removed)
- Authelia server IP
- Let's Encrypt email
- "Is this correct?" confirmation

Why Removed:
- Multi-machine deployments access services via domains, not IPs
- Caddy runs on separate machine with its own Let's Encrypt config
- User copies generated Authelia configs to separate servers
- IP/email values were only used in Caddyfile template generation
- MULTI_MACHINE_CONFIG_SNIPPETS.md provides the actual deployment guide

Changes:
1. Set placeholder values automatically:
   - MATRIX_SERVER_IP=10.0.1.10
   - AUTHELIA_SERVER_IP=10.0.1.20
   - LETSENCRYPT_EMAIL=admin@{domain}

2. Simplified configuration summary (no IPs shown)

3. Added helpful note pointing to MULTI_MACHINE_CONFIG_SNIPPETS.md

4. Updated .env comments to indicate these are placeholders

Result:
- Faster deployment: 12 prompts → 7 prompts
- Domain prompts preserved (user requested)
- Still generates Caddyfile template with placeholder IPs
- User updates actual IPs manually on Caddy server

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 19:16:46 +01:00
wmair 5cc781b57e Simplify compose file structure: Use docker-compose.yml as default
Changes:
- Renamed docker-compose.production.yml → docker-compose.yml (main config)
- Moved unused compose files to compose-variants/ folder:
  - docker-compose.local.yml → compose-variants/
  - docker-compose.authelia.yml → compose-variants/
  - docker-compose.caddy.yml → compose-variants/
  - docker-compose.yml (old) → compose-variants/docker-compose.old.yml
- Added compose-variants/README.md explaining the variants

Benefits:
- Default command now works: docker compose up -d (no -f flag needed)
- Cleaner project root directory
- Clear separation between active config and variants
- Multi-machine deployment is the default mode

Updated Documentation:
- MULTI_MACHINE_CONFIG_SNIPPETS.md: Removed -f flags from all commands
- README.md: Updated deploy commands to use simplified syntax
- All commands now use: docker compose up -d

Deployment Modes (from docker-compose.yml):
1. Multi-machine (default):
   docker compose up -d
   → Starts: Synapse, MAS, Element, PostgreSQL only

2. Single-machine with Authelia:
   docker compose --profile single-machine --profile authelia up -d
   → Starts everything including Caddy and Authelia

3. Single-machine without Authelia:
   docker compose --profile single-machine up -d
   → Starts everything with Caddy, no Authelia

This makes the default behavior match the multi-machine architecture
where Caddy and Authelia run on separate servers.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 19:05:03 +01:00
wmair 7ca76828c6 Fix deploy.sh directory creation and add multi-machine deployment guide
Deploy Script Fix:
- Add Step 1.5: Create directory structure before config generation
- Fixes "No such file or directory" error when writing configs
- Creates authelia/config, mas/config, element/config, etc.
- Ensures all required directories exist before deploy starts

Multi-Machine Configuration Guide:
- New file: MULTI_MACHINE_CONFIG_SNIPPETS.md (750+ lines)
- Complete guide for 3-machine deployment architecture
- All services accessible on standard HTTPS port 443

Architecture:
- Machine 1: Caddy (SSL termination) - matrix, auth, element domains
- Machine 2: Authelia (SSO with own reverse proxy) - authelia domain
- Machine 3: Matrix Stack (Synapse, MAS, Element, PostgreSQL)

Key Features:
- Step-by-step deployment workflow (6 phases)
- Explains how to generate and extract secrets from deploy.sh
- Simple copy-paste method: scp generated configs to servers
- Complete Authelia config with port 443 reverse proxy examples
- Complete Caddy config for Matrix/MAS/Element proxying
- DNS configuration guide
- Validation checklist
- Troubleshooting section

Authelia Integration:
- Authelia behind its own reverse proxy (Caddy/Nginx) on port 443
- MAS uses correct discovery_url: https://authelia.example.com
- OAuth2 client secrets and hashes all generated by deploy.sh
- Config files have secrets pre-embedded for easy deployment

Validated:
- Production deployment tested
- Directory creation works correctly
- Config files generated successfully
- Discovery URL uses HTTPS domain in production mode

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 18:48:25 +01:00
wmair f546ad0566 Fix Authelia discovery URL for production deployments
Production deployments now use HTTPS domain for Authelia discovery URL
instead of internal Docker service name. This ensures OAuth2 validation
works correctly with Let's Encrypt certificates and multi-machine setups.

Changes:
- Production: discovery_url uses https://${AUTHELIA_DOMAIN}
- Local: discovery_url uses http://authelia:9091 (avoids self-signed cert issues)

Technical Details:
- OAuth2 spec requires consistent issuer and discovery URLs
- Multi-machine deployments need public HTTPS domains, not internal service names
- Local deployments continue using internal HTTP for container-to-container communication

Validated:
- Logic tested with production variables ✓
- Logic tested with local variables ✓
- Generated configs verified ✓

Fixes OAuth issuer URL consistency for production with separate Authelia servers.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 18:36:32 +01:00
wmair 861f01990d Production-ready Matrix stack with optional Authelia and automated bridge setup
Major Features:
- Optional Authelia deployment via Docker Compose profiles
- Issue #9 fix: Pre-flight check for PostgreSQL data persistence
- Issue #10 fix: DNS resolution and TLS certificate trust (local)
- Automated bridge setup script for post-deployment configuration
- Production deployment with Let's Encrypt support

Configuration Updates:
- deploy.sh: Interactive Authelia selection, data directory pre-flight check
- docker-compose.local.yml: Issue #10 fixes (CA cert mount, extra_hosts, SSL_CERT_FILE)
- docker-compose.production.yml: All fixes applied, profile-based Authelia
- caddy/Caddyfile.production: Let's Encrypt configuration template

New Documentation:
- PRODUCTION_DEPLOYMENT.md: Comprehensive production deployment guide
- BRIDGE_SETUP_GUIDE.md: Explains bridge chicken-and-egg dependency issue
- BUGFIXES.md: Updated with Issue #9 and #10 documentation (10 issues total)
- README.md: Rewritten for deployment focus, removed verbose content

Bridge Automation:
- setup-bridges.sh: Post-deployment bridge configuration script
- Handles correct startup sequence to avoid registration dependency loop
- Configures Telegram, WhatsApp, and Signal bridges automatically

Cleanup:
- Removed redundant documentation files (DEPLOYMENT_GUIDE.md, PRODUCTION.md, etc.)
- Removed temporary scripts (configure-bridges.sh, validate-setup.sh, etc.)
- Streamlined documentation structure for actual deployment use

All critical issues documented in BUGFIXES.md.
Production deployment tested and ready.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 17:45:27 +01:00
wmair 8cb92b9226 Initial commit: Complete Matrix Stack with SSO and all bugfixes
This is a clean, ready-to-deploy Matrix communication stack with:

Features:
- Matrix Synapse homeserver with PostgreSQL
- Element Web client
- Matrix Authentication Service (MAS) with OIDC
- Authelia SSO with 2FA support
- Caddy reverse proxy with automatic HTTPS
- Bridges: Telegram, WhatsApp, Signal (pre-configured)

Deployment Modes:
- Local testing (all-in-one with self-signed certs)
- Production (distributed 3-machine setup with Let's Encrypt)

All Critical Bugfixes Applied:
1. Using example.test domains (not .localhost - public suffix list issue)
2. MAS assets resource enabled (fixes CSS 404 errors)
3. MAS fetch_userinfo enabled (required for Authelia claims)
4. Internal discovery URL for faster OIDC metadata fetching
5. Claims templates using preferred_username (Authelia compatible)
6. All redirect URIs configured in Authelia
7. Caddy CA certificate extraction automated
8. Correct email domains throughout

Security:
- All secrets generated dynamically on deployment
- Cryptographically secure random generation (OpenSSL)
- 4096-bit RSA keys for OIDC/JWT signing
- Argon2 password hashing
- No hardcoded secrets in repository

Documentation:
- BUGFIXES.md - Comprehensive troubleshooting guide
- DEPLOYMENT_GUIDE.md - Step-by-step deployment manual
- QUICK_REFERENCE.md - Command cheatsheet
- README.md - Quick start guide
- PRODUCTION.md - Production deployment guide

Deployment:
- Single command: ./deploy.sh
- Fully automated configuration generation
- ~10 minutes to complete setup

State: Clean slate, ready for validation deployment
2025-10-29 14:46:30 +01:00