Skip to content

Instantly share code, notes, and snippets.

@russelldavies
Last active January 10, 2023 02:28
Show Gist options
  • Save russelldavies/4e12ef3e0ef94207a732a2d063ba903c to your computer and use it in GitHub Desktop.
Save russelldavies/4e12ef3e0ef94207a732a2d063ba903c to your computer and use it in GitHub Desktop.
Matrix homeserver setup with Docker and Traefik

This guide assumes that example.com is your server name, so user IDs will in the format @user:example.com, and that matrix.example.com is the domain name of your actual server.

Requirements

At least 512 MB memory. Approximate memory usage of services:

  • Traefik: 20 MB
  • Postgres: 70 MB
  • Synapse: 150 MB

Inbound traffic on port 443/tcp.

Setup

  1. Copy the docker-compose.yaml file to your server. Look for the TODO comments and edit as necessary.
  2. Create a Docker network for external services: docker network create proxy.
  3. Configure DNS A and AAAA records to your server's IP address. This is absolutely necessary so that Traefik can get a TLS certificate.
  4. Generate a Synapse configuration file: docker-compose run --rm -e SYNAPSE_SERVER_NAME=example.com -e SYNAPSE_REPORT_STATS=yes matrix_synapse generate
  5. Edit the Synapse configuration file at synapse/homeserver.yaml and set the following values:
  • server_name: set this to example.com not matrix.example.com.
  • public_baseurl: set this to https://matrix.example.com.
  • use_presence: set to true
  • database: should be like:
  database:
  name: psycopg2
  args:
    user: synapse
    # TODO: change to what you previously set
    password: asdf
    database: synapse
    host: matrix_db
  • enable_registration: set to true if you don't want to manually register users.
  1. Start services: docker-compose up -d
  2. Register new user: docker exec -it matrix_synapse register_new_matrix_user -c /data/homeserver.yaml http://localhost:8008.

Federation

Well-Known URIs are to facilitate automatic setup for clients and federation between servers.

The URL https://example.com/.well-known/matrix/client should return JSON in the following format:

{
  "m.homeserver": {
    "base_url": "https://matrix.example.com"
  }
}

To work in browser based clients, the file must be served with the appropriate Cross-Origin Resource Sharing (CORS) headers. A recommended value would be Access-Control-Allow-Origin: * which would allow all browser based clients to view it.

The URL https://example.com/.well-known/matrix/server should return JSON in the following format:

{
  "m.server": "matrix.example.com:443"
}

Test that federation is setup properly using the federation tester. Use example.com not matrix.example.com.

References:

version: "3"
services:
traefik:
# TODO: change to the latest stable version (e.g. v2.3)
image: traefik:latest
container_name: traefik
restart: unless-stopped
command:
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.websecure.address=:443
- --certificatesresolvers.default.acme.tlschallenge=true
# TODO: change email
- [email protected]
- --certificatesresolvers.default.acme.storage=/letsencrypt/acme.json
- --serversTransport.insecureSkipVerify=true
networks:
- proxy
ports:
- 443:443
volumes:
# TODO: change if desired
- ./letsencrypt:/letsencrypt
- /var/run/docker.sock:/var/run/docker.sock:ro
matrix_db:
image: postgres:13-alpine
container_name: matrix_db
restart: unless-stopped
networks:
- matrix
volumes:
# TODO: change if desired
- ./postgres:/var/lib/postgresql/data
environment:
- POSTGRES_USER=synapse
# TODO: Change this password
- POSTGRES_PASSWORD=asdf
- POSTGRES_INITDB_ARGS=--encoding=UTF-8 --lc-collate=C --lc-ctype=C
healthcheck:
interval: 5s
timeout: 3s
retries: 5
matrix_synapse:
# TODO: change to latest stable version, e.g. v1.24.0
image: matrixdotorg/synapse:latest
container_name: matrix_synapse
restart: unless-stopped
depends_on:
- matrix_db
networks:
- matrix
- proxy
volumes:
# TODO: change if desired
- ./synapse:/data
labels:
- traefik.enable=true
# TODO: Change hostname
- traefik.http.routers.synapse.rule=Host(`matrix.example.com`)
- traefik.http.routers.synapse.entrypoints=websecure
- traefik.http.routers.synapse.tls.certresolver=default
- traefik.http.services.synapse.loadbalancer.server.port=8008
networks:
proxy:
external: true
matrix:
internal: true
@russelldavies
Copy link
Author

If you want to use Cloudflare Tunnels, replace the Traefik service with a cloudflared image. Or if you don't want to run cloudflared in Docker then remove the Traefik service and make configure matrix_synapse so it's on an external network and configure cloudflared to point to it.

@BettyNutz
Copy link

BettyNutz commented Jan 10, 2023

If you want to use Cloudflare Tunnels, replace the Traefik service with a cloudflared image. Or if you don't want to run cloudflared in Docker then remove the Traefik service and make configure matrix_synapse so it's on an external network and configure cloudflared to point to it.

thanks for the reply - 2 questions if you can give me a bit more help - thanks

"replace the Traefik service with a cloudflared image" - is that a yml file with traefik preconfigured with cf settings? (or 'just' set it up with something like this? https://www.smarthomebeginner.com/cloudflare-settings-for-traefik-docker/)

"Traefik service and make configure matrix_synapse so it's on an external network and configure cloudflared to point to it" - i just created a cftunnel container and joined it to both the docker networks that your yml file spins up. I must be missing something - as it didnt work. Maybe 'matrix_synapse so it's on an external network' is adding a 2nd tunnel on this network?

thanks for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment