feat: Sample Matrix swarm deployment compose file (#387)
All checks were successful
ci/woodpecker/push/infra Pipeline was successful
All checks were successful
ci/woodpecker/push/infra Pipeline was successful
Standalone Synapse + Element Web deployment for Docker Swarm/Portainer. Separate infrastructure from Mosaic Stack (same pattern as Authentik). Includes: Synapse, Element Web, dedicated PostgreSQL, optional coturn. Traefik labels match existing Stack conventions. Refs #387 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
206
docker/docker-compose.sample.matrix.yml
Normal file
206
docker/docker-compose.sample.matrix.yml
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
# ==============================================
|
||||||
|
# Matrix (Synapse + Element) - Sample Swarm Deployment
|
||||||
|
# ==============================================
|
||||||
|
#
|
||||||
|
# Standalone Matrix homeserver deployment for use with Mosaic Stack.
|
||||||
|
# This is SEPARATE infrastructure — not part of the Mosaic Stack itself.
|
||||||
|
# Mosaic connects to it via MATRIX_HOMESERVER_URL environment variable.
|
||||||
|
#
|
||||||
|
# Also serves: personal communications, GoToSocial bridges, other projects.
|
||||||
|
#
|
||||||
|
# Usage (Docker Swarm via Portainer):
|
||||||
|
# 1. Create a new stack in Portainer
|
||||||
|
# 2. Paste this file or point to the repo
|
||||||
|
# 3. Set environment variables in Portainer's env var section
|
||||||
|
# 4. Deploy the stack
|
||||||
|
#
|
||||||
|
# Usage (Docker Swarm CLI):
|
||||||
|
# 1. cp docker-compose.sample.matrix.env .env
|
||||||
|
# 2. nano .env # Configure
|
||||||
|
# 3. docker stack deploy -c docker-compose.sample.matrix.yml matrix
|
||||||
|
#
|
||||||
|
# Post-Deploy Setup:
|
||||||
|
# 1. Generate Synapse config (first run only):
|
||||||
|
# docker exec <synapse_container> python -m synapse.app.homeserver \
|
||||||
|
# --server-name ${MATRIX_DOMAIN} --report-stats no \
|
||||||
|
# --generate-config --config-path /data/homeserver.yaml
|
||||||
|
#
|
||||||
|
# 2. Create admin account:
|
||||||
|
# docker exec -it <synapse_container> register_new_matrix_user \
|
||||||
|
# -u admin -a -c /data/homeserver.yaml http://localhost:8008
|
||||||
|
#
|
||||||
|
# 3. Create Mosaic bot account:
|
||||||
|
# docker exec -it <synapse_container> register_new_matrix_user \
|
||||||
|
# -u mosaic-bot -c /data/homeserver.yaml http://localhost:8008
|
||||||
|
#
|
||||||
|
# 4. Generate bot access token:
|
||||||
|
# curl -X POST http://localhost:8008/_matrix/client/v3/login \
|
||||||
|
# -d '{"type":"m.login.password","user":"mosaic-bot","password":"<password>"}'
|
||||||
|
#
|
||||||
|
# 5. Set MATRIX_ACCESS_TOKEN in Mosaic Stack .env
|
||||||
|
#
|
||||||
|
# Required Environment Variables:
|
||||||
|
# MATRIX_DOMAIN=matrix.example.com # Synapse server name (permanent!)
|
||||||
|
# ELEMENT_DOMAIN=chat.example.com # Element Web domain
|
||||||
|
# POSTGRES_PASSWORD=<strong-password> # Synapse database password
|
||||||
|
#
|
||||||
|
# Optional Environment Variables:
|
||||||
|
# SYNAPSE_IMAGE_TAG=latest # Synapse version
|
||||||
|
# ELEMENT_IMAGE_TAG=latest # Element Web version
|
||||||
|
# POSTGRES_IMAGE_TAG=16-alpine # PostgreSQL version
|
||||||
|
# TRAEFIK_ENTRYPOINT=websecure # Traefik entrypoint name
|
||||||
|
# TRAEFIK_CERTRESOLVER=letsencrypt # Traefik cert resolver
|
||||||
|
# TRAEFIK_DOCKER_NETWORK=traefik-public # Traefik network name
|
||||||
|
# SYNAPSE_ENABLE_REGISTRATION=false # Public registration
|
||||||
|
# SYNAPSE_REPORT_STATS=no # Anonymous stats reporting
|
||||||
|
# SYNAPSE_MAX_UPLOAD_SIZE=50M # Max file upload size
|
||||||
|
#
|
||||||
|
# Connecting to Mosaic Stack:
|
||||||
|
# Add to your Mosaic Stack .env:
|
||||||
|
# MATRIX_HOMESERVER_URL=http://synapse:8008 (if same Docker network)
|
||||||
|
# MATRIX_HOMESERVER_URL=https://matrix.example.com (if external)
|
||||||
|
# MATRIX_ACCESS_TOKEN=<bot access token from step 4>
|
||||||
|
# MATRIX_BOT_USER_ID=@mosaic-bot:matrix.example.com
|
||||||
|
#
|
||||||
|
# ==============================================
|
||||||
|
|
||||||
|
services:
|
||||||
|
# ======================
|
||||||
|
# Synapse (Matrix Homeserver)
|
||||||
|
# ======================
|
||||||
|
synapse:
|
||||||
|
image: matrixdotorg/synapse:${SYNAPSE_IMAGE_TAG:-latest}
|
||||||
|
environment:
|
||||||
|
SYNAPSE_SERVER_NAME: ${MATRIX_DOMAIN}
|
||||||
|
SYNAPSE_REPORT_STATS: ${SYNAPSE_REPORT_STATS:-no}
|
||||||
|
SYNAPSE_CONFIG_DIR: /data
|
||||||
|
SYNAPSE_DATA_DIR: /data
|
||||||
|
SYNAPSE_LOG_LEVEL: ${SYNAPSE_LOG_LEVEL:-WARNING}
|
||||||
|
# Database connection (external PostgreSQL or bundled)
|
||||||
|
POSTGRES_HOST: synapse-postgres
|
||||||
|
POSTGRES_PORT: 5432
|
||||||
|
POSTGRES_DB: ${SYNAPSE_POSTGRES_DB:-synapse}
|
||||||
|
POSTGRES_USER: ${SYNAPSE_POSTGRES_USER:-synapse}
|
||||||
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||||
|
volumes:
|
||||||
|
- synapse-data:/data
|
||||||
|
- synapse-media:/data/media_store
|
||||||
|
depends_on:
|
||||||
|
synapse-postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "curl -fSs http://localhost:8008/health || exit 1"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 30s
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
- traefik-public
|
||||||
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: on-failure
|
||||||
|
delay: 10s
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.matrix.rule=Host(`${MATRIX_DOMAIN}`)"
|
||||||
|
- "traefik.http.routers.matrix.entrypoints=${TRAEFIK_ENTRYPOINT:-websecure}"
|
||||||
|
- "traefik.http.routers.matrix.tls=${TRAEFIK_TLS_ENABLED:-true}"
|
||||||
|
- "traefik.http.routers.matrix.tls.certresolver=${TRAEFIK_CERTRESOLVER:-}"
|
||||||
|
- "traefik.http.services.matrix.loadbalancer.server.port=8008"
|
||||||
|
- "traefik.docker.network=${TRAEFIK_DOCKER_NETWORK:-traefik-public}"
|
||||||
|
# Well-known delegation (optional — for .well-known/matrix/server)
|
||||||
|
# - "traefik.http.routers.matrix-wellknown.rule=Host(`${MATRIX_DOMAIN}`) && PathPrefix(`/.well-known/matrix`)"
|
||||||
|
|
||||||
|
# ======================
|
||||||
|
# Element Web (Matrix Client)
|
||||||
|
# ======================
|
||||||
|
element-web:
|
||||||
|
image: vectorim/element-web:${ELEMENT_IMAGE_TAG:-latest}
|
||||||
|
volumes:
|
||||||
|
- element-config:/app/config
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:80 || exit 1"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 3
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
- traefik-public
|
||||||
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: on-failure
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.element.rule=Host(`${ELEMENT_DOMAIN}`)"
|
||||||
|
- "traefik.http.routers.element.entrypoints=${TRAEFIK_ENTRYPOINT:-websecure}"
|
||||||
|
- "traefik.http.routers.element.tls=${TRAEFIK_TLS_ENABLED:-true}"
|
||||||
|
- "traefik.http.routers.element.tls.certresolver=${TRAEFIK_CERTRESOLVER:-}"
|
||||||
|
- "traefik.http.services.element.loadbalancer.server.port=80"
|
||||||
|
- "traefik.docker.network=${TRAEFIK_DOCKER_NETWORK:-traefik-public}"
|
||||||
|
|
||||||
|
# ======================
|
||||||
|
# PostgreSQL (Synapse Database)
|
||||||
|
# ======================
|
||||||
|
# Separate from Mosaic's PostgreSQL — Synapse manages its own schema.
|
||||||
|
# If you prefer a shared PostgreSQL instance, remove this service and
|
||||||
|
# point POSTGRES_HOST to your existing PostgreSQL with a separate database.
|
||||||
|
synapse-postgres:
|
||||||
|
image: postgres:${POSTGRES_IMAGE_TAG:-16-alpine}
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: ${SYNAPSE_POSTGRES_DB:-synapse}
|
||||||
|
POSTGRES_USER: ${SYNAPSE_POSTGRES_USER:-synapse}
|
||||||
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||||
|
POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C"
|
||||||
|
volumes:
|
||||||
|
- synapse-postgres-data:/var/lib/postgresql/data
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
[
|
||||||
|
"CMD-SHELL",
|
||||||
|
"pg_isready -U ${SYNAPSE_POSTGRES_USER:-synapse} -d ${SYNAPSE_POSTGRES_DB:-synapse}",
|
||||||
|
]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
deploy:
|
||||||
|
restart_policy:
|
||||||
|
condition: on-failure
|
||||||
|
|
||||||
|
# ======================
|
||||||
|
# coturn (TURN/STUN for VoIP) - Optional
|
||||||
|
# ======================
|
||||||
|
# Uncomment if you need voice/video calls through NAT.
|
||||||
|
# Requires additional DNS and port configuration.
|
||||||
|
#
|
||||||
|
# coturn:
|
||||||
|
# image: coturn/coturn:latest
|
||||||
|
# environment:
|
||||||
|
# TURN_REALM: ${MATRIX_DOMAIN}
|
||||||
|
# TURN_SECRET: ${COTURN_SECRET}
|
||||||
|
# ports:
|
||||||
|
# - "3478:3478/tcp"
|
||||||
|
# - "3478:3478/udp"
|
||||||
|
# - "5349:5349/tcp"
|
||||||
|
# - "5349:5349/udp"
|
||||||
|
# - "49152-49200:49152-49200/udp"
|
||||||
|
# networks:
|
||||||
|
# - internal
|
||||||
|
# deploy:
|
||||||
|
# restart_policy:
|
||||||
|
# condition: on-failure
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
synapse-data:
|
||||||
|
synapse-media:
|
||||||
|
synapse-postgres-data:
|
||||||
|
element-config:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
internal:
|
||||||
|
driver: overlay
|
||||||
|
traefik-public:
|
||||||
|
external: true
|
||||||
|
name: ${TRAEFIK_DOCKER_NETWORK:-traefik-public}
|
||||||
Reference in New Issue
Block a user