Matrix Synapse Server
Self-hosted Matrix homeserver with Synapse, Element web client, and PostgreSQL.
Overview
Matrix Synapse is the reference homeserver implementation of the Matrix protocol, an open-source real-time communication system designed for decentralized messaging, voice, and video. Developed by the Matrix.org Foundation, Synapse enables organizations and individuals to host their own communication server while maintaining the ability to federate with other Matrix homeservers across the internet, creating a distributed network similar to email but for modern chat applications.
This stack combines Synapse with Element Web (the flagship Matrix web client), PostgreSQL for robust data persistence, and NGINX for reverse proxy and SSL termination. PostgreSQL provides ACID-compliant storage for chat history, user accounts, and room state data, while NGINX handles client connections, federation traffic on port 8448, and serves the Element web interface. The configuration supports full Matrix federation, allowing users to communicate with anyone on the Matrix network while maintaining complete control over their data.
This deployment suits organizations seeking data sovereignty in their communications, privacy-conscious teams wanting end-to-end encrypted chat, or homelab enthusiasts building self-hosted alternatives to Slack or Discord. The combination provides enterprise-grade messaging capabilities with the flexibility to customize features, implement custom authentication systems, or integrate with existing infrastructure while maintaining compatibility with the broader Matrix ecosystem.
Key Features
- Full Matrix protocol federation enabling communication with users on any Matrix homeserver worldwide
- End-to-end encryption support with cross-device verification for secure communications
- PostgreSQL backend with optimized schema for chat message storage and room state management
- Element Web client integration providing modern chat interface with file sharing and voice/video calls
- NGINX reverse proxy handling both client traffic and Matrix federation on dedicated port 8448
- Room management with granular permissions, moderation tools, and custom power levels
- Bridge support for connecting to IRC, Discord, Telegram, and other chat platforms
- Application service integration allowing custom bots and Matrix protocol extensions
Common Use Cases
- 1Corporate communication server replacing proprietary solutions like Slack or Microsoft Teams
- 2Privacy-focused community chat for open source projects or activist organizations
- 3Educational institution messaging platform with room-based class organization
- 4Gaming community server with voice chat integration and custom bot development
- 5Healthcare or legal organizations requiring HIPAA/GDPR compliant messaging with data residency
- 6Homelab enthusiasts building personal communication infrastructure for family or friend groups
- 7Development teams needing integrated chat with custom webhooks and CI/CD notifications
Prerequisites
- Minimum 2GB RAM recommended for Synapse with PostgreSQL (1GB+ for PostgreSQL, 1GB+ for Synapse)
- Valid domain name with DNS control for Matrix federation and SSL certificate setup
- Ports 80, 443, and 8448 accessible from internet for web client and Matrix federation
- SSL/TLS certificates configured in nginx.conf for HTTPS and federation security
- Understanding of Matrix concepts like homeserver names, user IDs, and federation requirements
- Basic NGINX configuration knowledge for customizing reverse proxy settings
For development & testing. Review security settings, change default credentials, and test thoroughly before production use. See Terms
docker-compose.yml
docker-compose.yml
1services: 2 synapse: 3 image: matrixdotorg/synapse:latest4 environment: 5 SYNAPSE_SERVER_NAME: ${MATRIX_SERVER_NAME}6 SYNAPSE_REPORT_STATS: "no"7 volumes: 8 - synapse_data:/data9 depends_on: 10 postgres: 11 condition: service_healthy12 networks: 13 - matrix-net14 restart: unless-stopped1516 postgres: 17 image: postgres:15-alpine18 environment: 19 POSTGRES_USER: ${POSTGRES_USER}20 POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}21 POSTGRES_DB: synapse22 POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C"23 volumes: 24 - postgres_data:/var/lib/postgresql/data25 healthcheck: 26 test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]27 interval: 10s28 timeout: 5s29 retries: 530 networks: 31 - matrix-net32 restart: unless-stopped3334 element: 35 image: vectorim/element-web:latest36 volumes: 37 - ./element-config.json:/app/config.json:ro38 depends_on: 39 - synapse40 networks: 41 - matrix-net42 restart: unless-stopped4344 nginx: 45 image: nginx:alpine46 ports: 47 - "80:80"48 - "443:443"49 - "8448:8448"50 volumes: 51 - ./nginx.conf:/etc/nginx/nginx.conf:ro52 - ./certs:/etc/nginx/certs:ro53 depends_on: 54 - synapse55 - element56 networks: 57 - matrix-net58 restart: unless-stopped5960volumes: 61 synapse_data: 62 postgres_data: 6364networks: 65 matrix-net: 66 driver: bridge.env Template
.env
1# Matrix Server Name2MATRIX_SERVER_NAME=matrix.example.com34# PostgreSQL5POSTGRES_USER=synapse6POSTGRES_PASSWORD=secure_postgres_passwordUsage Notes
- 1Generate config: docker run --rm -v ./synapse_data:/data matrixdotorg/synapse:latest generate
- 2Element web at https://chat.example.com
- 3Federation port 8448 must be accessible
- 4Register users: docker exec synapse register_new_matrix_user
Individual Services(4 services)
Copy individual services to mix and match with your existing compose files.
synapse
synapse:
image: matrixdotorg/synapse:latest
environment:
SYNAPSE_SERVER_NAME: ${MATRIX_SERVER_NAME}
SYNAPSE_REPORT_STATS: "no"
volumes:
- synapse_data:/data
depends_on:
postgres:
condition: service_healthy
networks:
- matrix-net
restart: unless-stopped
postgres
postgres:
image: postgres:15-alpine
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: synapse
POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C"
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test:
- CMD-SHELL
- pg_isready -U ${POSTGRES_USER}
interval: 10s
timeout: 5s
retries: 5
networks:
- matrix-net
restart: unless-stopped
element
element:
image: vectorim/element-web:latest
volumes:
- ./element-config.json:/app/config.json:ro
depends_on:
- synapse
networks:
- matrix-net
restart: unless-stopped
nginx
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
- "8448:8448"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./certs:/etc/nginx/certs:ro
depends_on:
- synapse
- element
networks:
- matrix-net
restart: unless-stopped
Quick Start
terminal
1# 1. Create the compose file2cat > docker-compose.yml << 'EOF'3services:4 synapse:5 image: matrixdotorg/synapse:latest6 environment:7 SYNAPSE_SERVER_NAME: ${MATRIX_SERVER_NAME}8 SYNAPSE_REPORT_STATS: "no"9 volumes:10 - synapse_data:/data11 depends_on:12 postgres:13 condition: service_healthy14 networks:15 - matrix-net16 restart: unless-stopped1718 postgres:19 image: postgres:15-alpine20 environment:21 POSTGRES_USER: ${POSTGRES_USER}22 POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}23 POSTGRES_DB: synapse24 POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C"25 volumes:26 - postgres_data:/var/lib/postgresql/data27 healthcheck:28 test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]29 interval: 10s30 timeout: 5s31 retries: 532 networks:33 - matrix-net34 restart: unless-stopped3536 element:37 image: vectorim/element-web:latest38 volumes:39 - ./element-config.json:/app/config.json:ro40 depends_on:41 - synapse42 networks:43 - matrix-net44 restart: unless-stopped4546 nginx:47 image: nginx:alpine48 ports:49 - "80:80"50 - "443:443"51 - "8448:8448"52 volumes:53 - ./nginx.conf:/etc/nginx/nginx.conf:ro54 - ./certs:/etc/nginx/certs:ro55 depends_on:56 - synapse57 - element58 networks:59 - matrix-net60 restart: unless-stopped6162volumes:63 synapse_data:64 postgres_data:6566networks:67 matrix-net:68 driver: bridge69EOF7071# 2. Create the .env file72cat > .env << 'EOF'73# Matrix Server Name74MATRIX_SERVER_NAME=matrix.example.com7576# PostgreSQL77POSTGRES_USER=synapse78POSTGRES_PASSWORD=secure_postgres_password79EOF8081# 3. Start the services82docker compose up -d8384# 4. View logs85docker compose logs -fOne-Liner
Run this command to download and set up the recipe in one step:
terminal
1curl -fsSL https://docker.recipes/api/recipes/matrix-synapse-stack/run | bashTroubleshooting
- Federation not working with 'Host not found' errors: Ensure port 8448 is open and DNS SRV records are configured correctly for your domain
- Synapse container failing with database connection errors: Check PostgreSQL health check passes and POSTGRES_PASSWORD environment variable matches Synapse configuration
- Element web showing 'Failed to connect to homeserver': Verify nginx.conf properly proxies /_matrix/ endpoints to Synapse container and SSL certificates are valid
- High memory usage from PostgreSQL: Tune shared_buffers and work_mem in postgresql.conf, consider enabling connection pooling in Synapse configuration
- Registration failing with 'User already exists': Use register_new_matrix_user command with --admin flag for admin users, or enable open registration in homeserver.yaml
- Slow message delivery in large rooms: Enable worker mode in Synapse configuration and consider implementing Redis for better performance scaling
Community Notes
Loading...
Loading notes...
Download Recipe Kit
Get all files in a ready-to-deploy package
Includes docker-compose.yml, .env template, README, and license
Components
synapseelement-webpostgresqlnginx
Tags
#matrix#synapse#chat#element#federation
Category
Productivity & CollaborationAd Space
Shortcuts: C CopyF FavoriteD Download