mirror of
https://github.com/prdlk/vortex.git
synced 2026-08-02 17:31:41 +00:00
feat: unified messaging TUI MVP — Synapse + 7 mautrix bridges + Textual TUI + MCP draft staging
One-command local stack: cp .env.example .env && make up. Idempotent bootstrap renders Synapse + bridge configs from pristine upstream examples, provisions databases, registrations, double puppeting, and the admin user. Textual TUI with bridge manager, in-terminal QR login, and drafts panel. MCP server exposes read tools and a human-gated draft send workflow. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,203 @@
|
||||
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:
|
||||
Reference in New Issue
Block a user