name: vortex x-bridge-common: &bridge-common restart: unless-stopped depends_on: bootstrap: condition: service_completed_successfully synapse: condition: service_healthy environment: TZ: ${TZ:-UTC} services: postgres: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_USER: vortex POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in .env} POSTGRES_DB: synapse POSTGRES_INITDB_ARGS: --encoding=UTF8 --locale=C TZ: ${TZ:-UTC} volumes: - pgdata:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U vortex -d synapse"] interval: 5s timeout: 5s retries: 12 bootstrap: build: ./bootstrap environment: MATRIX_SERVER_NAME: ${MATRIX_SERVER_NAME:-localhost} MATRIX_USER: ${MATRIX_USER:-admin} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} REGISTRATION_SHARED_SECRET: ${REGISTRATION_SHARED_SECRET:-auto} DOUBLEPUPPET_SHARED_SECRET: ${DOUBLEPUPPET_SHARED_SECRET:-auto} BRIDGES_ENABLED: ${BRIDGES_ENABLED:-} TELEGRAM_API_ID: ${TELEGRAM_API_ID:-} TELEGRAM_API_HASH: ${TELEGRAM_API_HASH:-} TZ: ${TZ:-UTC} volumes: - data:/data - ./synapse:/templates/synapse:ro - ./bridges/templates:/templates/bridges:ro depends_on: postgres: condition: service_healthy command: /bootstrap.sh synapse: image: matrixdotorg/synapse:v1.156.0 restart: unless-stopped environment: TZ: ${TZ:-UTC} volumes: - type: volume source: data target: /data volume: { subpath: synapse } ports: - "8008:8008" depends_on: bootstrap: condition: service_completed_successfully postgres: condition: service_healthy healthcheck: test: ["CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:8008/health')\""] interval: 5s timeout: 5s retries: 24 start_period: 30s provision: build: ./bootstrap environment: MATRIX_SERVER_NAME: ${MATRIX_SERVER_NAME:-localhost} MATRIX_USER: ${MATRIX_USER:-admin} MATRIX_PASSWORD: ${MATRIX_PASSWORD:?set MATRIX_PASSWORD in .env} TZ: ${TZ:-UTC} volumes: - data:/data depends_on: synapse: condition: service_healthy command: /provision.sh whatsapp: <<: *bridge-common image: dock.mau.dev/mautrix/whatsapp:v0.2606.0 profiles: [whatsapp] volumes: - type: volume source: data target: /data volume: { subpath: bridges/whatsapp } gmessages: <<: *bridge-common image: dock.mau.dev/mautrix/gmessages:v26.05 profiles: [gmessages] volumes: - type: volume source: data target: /data volume: { subpath: bridges/gmessages } telegram: <<: *bridge-common image: dock.mau.dev/mautrix/telegram:v26.06 profiles: [telegram] entrypoint: ["/bin/sh", "-c", "if [ ! -f /data/config.yaml ]; then echo 'telegram bridge skipped: TELEGRAM_API_ID / TELEGRAM_API_HASH not set in .env'; exec sleep infinity; fi; exec /docker-run.sh"] volumes: - type: volume source: data target: /data volume: { subpath: bridges/telegram } twitter: <<: *bridge-common image: dock.mau.dev/mautrix/twitter:v26.06 profiles: [twitter] volumes: - type: volume source: data target: /data volume: { subpath: bridges/twitter } linkedin: <<: *bridge-common image: dock.mau.dev/mautrix/linkedin:v26.04 profiles: [linkedin] volumes: - type: volume source: data target: /data volume: { subpath: bridges/linkedin } discord: <<: *bridge-common image: dock.mau.dev/mautrix/discord:v0.7.6 profiles: [discord] volumes: - type: volume source: data target: /data volume: { subpath: bridges/discord } meta: <<: *bridge-common image: dock.mau.dev/mautrix/meta:v26.06 profiles: [meta] volumes: - type: volume source: data target: /data volume: { subpath: bridges/meta } mcp: build: ./mcp restart: unless-stopped environment: MCP_HTTP_PORT: ${MCP_HTTP_PORT:-8765} MCP_ALLOW_SEND: ${MCP_ALLOW_SEND:-false} CREDENTIALS_FILE: /shared/credentials.json DRAFTS_DB: /shared/drafts/drafts.db STORE_DIR: /shared/mcp-store TZ: ${TZ:-UTC} ports: - "${MCP_HTTP_PORT:-8765}:${MCP_HTTP_PORT:-8765}" volumes: - type: volume source: data target: /shared volume: { subpath: shared } depends_on: provision: condition: service_completed_successfully tui: build: ./tui profiles: [tui] stdin_open: true tty: true environment: CREDENTIALS_FILE: /shared/credentials.json DRAFTS_DB: /shared/drafts/drafts.db STORE_DIR: /shared/tui-store TZ: ${TZ:-UTC} volumes: - type: volume source: data target: /shared volume: { subpath: shared } depends_on: synapse: condition: service_healthy volumes: pgdata: data: