Skip to content

Instantly share code, notes, and snippets.

@matusnovak
Last active March 22, 2024 08:31
Show Gist options
  • Star 68 You must be signed in to star a gist
  • Fork 16 You must be signed in to fork a gist
  • Save matusnovak/37109e60abe79f4b59fc9fbda10896da to your computer and use it in GitHub Desktop.
Save matusnovak/37109e60abe79f4b59fc9fbda10896da to your computer and use it in GitHub Desktop.
Matrix (Synapse + Riot) in Docker with Traefik and federation

Matrix

matrix.org chat is split into two parts, the server and the client. The server we are going to use is called Synapse and the client is Riot.im. The Synapse will also need Postgres database and Redis for caching.

0. Folders

Make sure your folder structure looks like this.

example/
  data/
    postgres/
      data/
        (empty)
    traefik/
      (empty)
    matrix/
      nginx/
        (empty)
      synapse/
        (empty)
      riot/
        (empty)
  docker-compose.yml

You can generate them via:

mkdir -p data/postgres/data
mkdir -p data/traefik
mkdir -p data/matrix/{nginx,synapse,riot}
touch docker-compose.yml

1. Traefik

Create your basic Traefik configuration. The following should work out of the box, if you change your email in the ACME section.

# data/traefik/traefik.yml
entryPoints:
  web:
    address: ":80"
  web-secure:
    address: ":443"

api:
  dashboard: true
  insecure: true

providers:
  file:
    directory: "/config"
    watch: true
  docker:
    endpoint: "unix:///var/run/docker.sock"
    network: "example_default"
    watch: true
    exposedByDefault: false

certificatesResolvers:
  letsencrypt:
    acme:
      email: "your_name@example.com"
      storage: "/acme.json"
      httpChallenge:
        entryPoint: "web"

The following additional Traefik config is useful for http to https automatic redirection. This is purely optional, you don't need these two files.

# data/traefik/config/routers.yml
http:
  routers:
    redirecttohttps:
      entryPoints:
        - "web"
      middlewares:
        - "httpsredirect"
      rule: "HostRegexp(`{host:.+}`)"
      service: "noop@internal"
# data/traefik/config/middlewares.yml
http:
  middlewares:
    httpsredirect:
      redirectScheme:
        scheme: https
        permanent: true

One more thing, you will have to create an empty JSON file for the acme.json. This file will store Let's Encrypt certificates. Simply create a file data/traefik/acme.json with an empty JSON object such as the following:

{}

Finally, the most importing part, you will have to use the following Docker compose config to run Traefik:

services:
  traefik:
    image: "traefik:latest"
    restart: "unless-stopped"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./data/traefik/traefik.yml:/etc/traefik/traefik.yml:ro"
      - "./data/traefik/config:/config:ro"
      - "./data/traefik/acme.json:/acme.json"
    # The following labels are optional. If you keep them, you will be able to
    # access Traefik dashboard via https://traefik.example.com/
    labels:
      - "traefik.enable=true"
      - "traefik.http.services.traefik.loadbalancer.server.port=8080"
      - "traefik.http.routers.traefik.rule=Host(`traefik.example.com`)"
      - "traefik.http.routers.traefik.entrypoints=web-secure"
      - "traefik.http.routers.traefik.tls.certresolver=letsencrypt"

2. Postgres

Make sure you have a postgres database with a login for the Synapse server.

The following is a sample docker-compose config for Postgres.

# docker-compose.yml
services:
  traefik:
    ...
  postgres:
    image: "postgres:9.6"
    restart: "unless-stopped"
    environment:
      POSTGRES_PASSWORD: "admin"
    volumes:
      - "./data/postgres/data:/var/lib/postgresql/data"

The following code will create a database synapse with user synapse and password password. Make sure that your database has the correct encoding!

CREATE ROLE synapse;
ALTER ROLE synapse WITH PASSWORD 'password';
ALTER ROLE synapse WITH LOGIN;
CREATE DATABASE synapse ENCODING 'UTF8' LC_COLLATE='C' LC_CTYPE='C' template=template0 OWNER synapse;
GRANT ALL PRIVILEGES ON DATABASE synapse TO synapse;

3. Redis

Make sure you have redis running. Example docker-compose configuration:

# docker-compose.yml
services:
  traefik:
    ...
  postgres:
    ...
  redis:
    image: "redis:latest"
    restart: "unless-stopped"

4. Synapse

Note: You will have two sub-domains for Synapse via Traefik. One matrix.example.com which will be handled by Nginx and a second one synapse.example.com which will point directly into your Synapse server. It will be explained in a later section below.

First create a sample config. This will also create your signing key and bunch of other secrets.

docker run -it --rm \
    -v $(pwd)/data/matrix/synapse:/data \
    -e SYNAPSE_SERVER_NAME=matrix.example.com \
    -e SYNAPSE_REPORT_STATS=yes \
    -e UID=1000 \
    -e GID=1000 \
    matrixdotorg/synapse:latest generate

This will create the following files:

example/
  data/
    ...
    matrix/
      nginx/
        (empty)
      synapse/
        homeserver.yaml
        matrix.example.com.log.config
        matrix.example.com.signing.key
      riot/
        (empty)

Edit the homeserver.yaml so you end up with something like the config below. (notice the enable_registration!)

# data/matrix/synapse/homeserver.yaml
server_name: "matrix.example.com"

pid_file: /data/homeserver.pid

web_client_location: https://riot.example.com/

public_baseurl: https://synapse.example.com/

report_stats: true

enable_registration: true

listeners:
  - port: 8008
    tls: false
    type: http
    x_forwarded: true

    resources:
      - names: [client, federation]
        compress: false

retention:
  enabled: true

federation_ip_range_blacklist:
  - '127.0.0.0/8'
  - '10.0.0.0/8'
  - '172.16.0.0/12'
  - '192.168.0.0/16'
  - '100.64.0.0/10'
  - '169.254.0.0/16'
  - '::1/128'
  - 'fe80::/64'
  - 'fc00::/7'

database:
  name: psycopg2
  args:
    user: synapse
    password: password
    database: synapse
    host: postgres   
    cp_min: 5
    cp_max: 10

log_config: "/data/matrix.example.com.log.config"

media_store_path: "/data/media_store"

registration_shared_secret: "abc"

macaroon_secret_key: "abc"

form_secret: "abc"

signing_key_path: "/data/matrix.example.com.signing.key"

trusted_key_servers:
  - server_name: "matrix.org"

redis:
  enabled: true
  host: redis
  port: 6379

Now add your docker-compose config for Synapse:

# docker-compose.yml
services:
  traefik:
    ...
  postgres:
    ...
  redis:
    ...
  synapse:
    image: "matrixdotorg/synapse:latest"
    restart: "unless-stopped"
    environment:
      SYNAPSE_CONFIG_DIR: "/data"
      SYNAPSE_CONFIG_PATH: "/data/homeserver.yaml"
      UID: "1000"
      GID: "1000"
      TZ: "Europe/London"
    volumes:
      - "./data/matrix/synapse:/data"
    labels:
      - "traefik.enable=true"
      - "traefik.http.services.synapse.loadbalancer.server.port=8008"
      - "traefik.http.routers.synapse.rule=Host(`synapse.example.com`)"
      - "traefik.http.routers.synapse.entrypoints=web-secure"
      - "traefik.http.routers.synapse.tls.certresolver=letsencrypt"

Now when you go to https://synapse.example.com/ you should be redirected to https://synapse.example.com/_matrix/static/ and you should see It works! Synapse is running.

5. Nginx

So the Synapse server is running, but this is not everything you need for federation. You may have noticed that we have used two domains: synapse.example.com and matrix.example.com.

The federation documentation is bit configusing if you don't know enough about how Matrix works internally. Hopefully this example below will explain it.

Create the following files:

The Nginx configuration file at data/matrix/nginx/matrix.conf relative to your docker-compose.yml with the following contents:

server {
  listen         80 default_server;
  server_name    matrix.example.com;

 # Traefik -> nginx -> synapse
 location /_matrix {
    proxy_pass http://synapse:8008;
    proxy_set_header X-Forwarded-For $remote_addr;
    client_max_body_size 128m;
  }

  location /.well-known/matrix/ {
    root /var/www/;
    default_type application/json;
    add_header Access-Control-Allow-Origin  *;
  }
}

The data/matrix/nginx/www/.well-known/matrix/client with the following contents:

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

And the data/matrix/nginx/www/.well-known/matrix/server with the following contents:

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

And the docker-compose config for Nginx:

# docker-compose.yml
services:
  traefik:
    ...
  postgres:
    ...
  redis:
    ...
  synapse:
    ...
  nginx:
    image: "nginx:latest"
    restart: "unless-stopped"
    volumes:
      - "./data/matrix/nginx/matrix.conf:/etc/nginx/conf.d/matrix.conf"
      - ./data/matrix/nginx/www:/var/www/
    labels:
      - "traefik.enable=true"
      - "traefik.http.services.matrix.loadbalancer.server.port=80"
      - "traefik.http.routers.matrix.rule=Host(`matrix.example.com`)"
      - "traefik.http.routers.matrix.entrypoints=web-secure"
      - "traefik.http.routers.matrix.tls.certresolver=letsencrypt"

After you start the container, you should be able to access https://matrix.example.com/.well-known/matrix/client which gives you "base_url": "https://matrix.example.com".

And also you should be able to access https://matrix.example.com/.well-known/matrix/server which gives you "m.server": "synapse.example.com:443".

And also accessing https://matrix.example.com/_matrix/static/ should show you the exact same page as shown at https://synapse.example.com/_matrix/static/.

The Nginx simply acts as a proxy in this case, with two additional files.

6. Federation tester

Now, when you go to https://federationtester.matrix.org/ and type in your domain name, in this case matrix.example.com (without https) you should get all green checks.

7. Riot Web UI

The last thing is to set up the Riot Web UI which will be used to send the messages.

Create a new file at data/matrix/riot/config.json with the following contents:

{
  "default_server_config": {
    "m.homeserver": {
      "base_url": "https://matrix.example.com",
      "server_name": "matrix.example.com"
    },
    "m.identity_server": {
      "base_url": "https://vector.im"
    }
  },
  "disable_custom_urls": false,
  "disable_guests": false,
  "disable_login_language_selector": false,
  "disable_3pid_login": false,
  "brand": "Element",
  "integrations_ui_url": "https://scalar.vector.im/",
  "integrations_rest_url": "https://scalar.vector.im/api",
  "integrations_widgets_urls": [
    "https://scalar.vector.im/_matrix/integrations/v1",
    "https://scalar.vector.im/api",
    "https://scalar-staging.vector.im/_matrix/integrations/v1",
    "https://scalar-staging.vector.im/api",
    "https://scalar-staging.riot.im/scalar/api"
  ],
  "bug_report_endpoint_url": "https://riot.im/bugreports/submit",
  "defaultCountryCode": "GB",
  "showLabsSettings": false,
  "features": {
    "feature_new_spinner": "labs",
    "feature_pinning": "labs",
    "feature_custom_status": "labs",
    "feature_custom_tags": "labs",
    "feature_state_counters": "labs"
  },
  "default_federate": true,
  "default_theme": "light",
  "roomDirectory": {
    "servers": [
      "matrix.org"
    ]
  },
  "welcomeUserId": "@riot-bot:matrix.org",
  "piwik": {
    "url": "https://piwik.riot.im/",
    "whitelistedHSUrls": [
      "https://matrix.org"
    ],
    "whitelistedISUrls": [
      "https://vector.im",
      "https://matrix.org"
    ],
    "siteId": 1
  },
  "enable_presence_by_hs_url": {
    "https://matrix.org": false,
    "https://matrix-client.matrix.org": false
  },
  "settingDefaults": {
    "breadcrumbs": true
  },
  "jitsi": {
    "preferredDomain": "jitsi.riot.im"
  }
}

And add Riot to your docker-compose file:

# docker-compose.yml
services:
  traefik:
    ...
  postgres:
    ...
  redis:
    ...
  synapse:
    ...
  nginx:
    ...
  riot:
    image: "vectorim/riot-web:latest"
    volumes:
      - "./data/matrix/riot/config.json:/app/config.json:ro"
    labels:
      - "traefik.enable=true"
      - "traefik.http.services.riot.loadbalancer.server.port=80"
      - "traefik.http.routers.riot.rule=Host(`riot.example.com`)"
      - "traefik.http.routers.riot.entrypoints=web-secure"
      - "traefik.http.routers.riot.tls.certresolver=letsencrypt"

8. Logging in

Go to https://riot.example.com and click register and select "Advanced" and enter the Homeserver URL as https://matrix.example.com (NOT https://synapse.example.com!).

After creating an account, simply log in. That's it.

9. Testing federation by joinin public room

Navigate to https://riot.example.com/#/room/#hello-matrix:matrix.org This will join you to #hello-matrix:matrix.org room on <matrix.org>.

If you get 401 unauthorized error in your logs (Synapse logs), check the SVR DNS record below.

10. SVR DNS record

Note: This may not be needed!

Add the following SVR record to your DNS server:

_matrix._tcp.matrix.example.com

With value of:

1 10 443 synapse.example.com

After it is done, you should be able to test if it is correct via dig or similar CLI tool:

dig -t SRV _matrix._tcp.matrix.example.com @8.8.8.8

And should print the following:

;; ANSWER SECTION:
_matrix._tcp.matrix.example.com. 299 IN SRV 1 10 443 synapse.example.com.

Optional OpenLDAP

It is possible to integrate Synapse with OpenLDAP. In this case you don't need to create any user from the Riot Web UI. All authentication will be handled by OpenLDAP server.

Add this into your homeserver.yml file:

password_providers:
  - module: "ldap_auth_provider.LdapAuthProvider"
    config:
      enabled: true
      uri: "ldap://openldap:389"
      start_tls: false
      base: "ou=users,dc=example,dc=com"
      attributes:
         uid: "uid"
         mail: "email"
         name: "cn"
      bind_dn: cn=admin,dc=example,dc=com
      bind_password: password
      filter: "(memberOf=cn=matrix,ou=groups,dc=example,dc=com)"

Assuming that:

  • Your OpenLDAP server can be accessed via Docker network at openldap:389.
  • You have domain of dc=example,dc=com.
  • You have admin (or any user for bind) cn=admin,dc=example,dc=com.
  • You have an organization unit of users at ou=users,dc=example,dc=com.
  • You have a groupOfUniqueNames as cn=matrix,ou=example,dc=example,dc=com.
  • Your users are added into the group cn=matrix so they have a property memberOf.

I recommend using OpenLDAP as the following:

services:
  openldap:
    image: "osixia/openldap:latest"
    restart: "unless-stopped"
    environment:
      LDAP_ORGANISATION: "Homelab"
      LDAP_DOMAIN: "dc=example,dc=com"
      LDAP_ADMIN_PASSWORD: "password"
      LDAP_REMOVE_CONFIG_AFTER_SETUP: "false"
    volumes:
      - "./data/ldap/data:/var/lib/ldap"
      - "./data/ldap/config:/etc/ldap/slapd.d"

Optional Turn Server (video calls)

You will need to do this if you want to enable VoIP. This guide will not explain what a Turn server is. First, create a data/matrix/coturn/turnserver.conf file with the following contents.

use-auth-secret
static-auth-secret=SomeSecretPasswordForMatrix
realm=matrix.example.com
listening-port=3478
tls-listening-port=5349
min-port=49160
max-port=49200
verbose
allow-loopback-peers
cli-password=SomePasswordForCLI
external-ip=192.168.0.2/123.123.123.123

You will have to replace the SomeSecretPasswordForMatrix and SomePasswordForCLI with your own password. You can generate a random password by using the following command:

openssl rand -hex 32

You will also have to modify your external-ip! This is a two part value divided by a slash /. The left part is your local IP address allocated to your server. You can find it by executing ip route get 1 (for example, src 192.168.0.2 uid 1000). The right part is your public IP address, you can find it here: https://whatismyipaddress.com/

You will then have to edit your Matrix yml configuration, found in data/matrix/synapse/homeserver.yaml and add the following lines at the bottom:

turn_uris: 
  - "turn:matrix.example.com:3478?transport=udp"
  - "turn:matrix.example.com:3478?transport=tcp"
  - "turns:matrix.example.com:3478?transport=udp"
  - "turns:matrix.example.com:3478?transport=tcp"

turn_shared_secret: "SomeSecretPasswordForMatrix"
turn_user_lifetime: 86400000
turn_allow_guests: True

You will have to match the password you have set for static-auth-secret.

Note: Changing Synapse's homeserver.yml file requires a service restart. Do it via docker restart example_matrix_synapse_1 command.

Next, add the Coturn server into the docker-compose.yml file:

# docker-compose.yml
services:
  traefik:
    ...
  postgres:
    ...
  redis:
    ...
  synapse:
    ...
  nginx:
    ...
  riot:
    ...
  coturn:
    image: "instrumentisto/coturn:latest"
    restart: "unless-stopped"
    volumes:
      - "./data/matrix/coturn/turnserver.conf:/etc/coturn/turnserver.conf"
    ports:
      - "49160-49200:49160-49200/udp"
      - "3478:3478"
      - "5349:5349"

Next, you will have to enable these ports in your firewall, if you are using one. In case of ufw on Ubuntu server, the following commands will be sufficient:

sudo ufw allow from 0.0.0.0/0 to any port 5349
sudo ufw allow from 0.0.0.0/0 to any port 3478
sudo ufw allow from 0.0.0.0/0 to any port 49160:49200 proto udp

Next, you will have to allow these ports (5349 udp+tcp, 3478 udp+tcp, and 49160-49200 udp) in your router and forward them to your server! This is specific to your router and I can not provide a guide for all of the routers that exists, you will have to find out on your own. You probably already did this for your HTTP+HTTPS anyway.

If you are using EC2, all you have to do is to modify the security group of your EC2 instance that is running your Matrix, and allow traffic from anywhere to ports 5349/tcp, 5349/udp, 3478/tcp, 3478/udp, and 49160-49200/udp.

Next, deploy the Coturn server by running docker-compose up -d. You will also have to restart your Synapse (because the config has changed) via docker restart example_matrix_synapse_1. You can find the name of your Synapse container by simply running docker ps | grep synapse.

That is all, you should be now be able to make calls.

Note: I highly recommend testing this on two separate ISP networks! If your Coturn or the port-forwarding is misconfigured, you will very likely be able to make calls within your local network, and you will not realise that there is a problem. The best way to test is that you create two accounts on your Matrix and call each other from different ISP networks. Perhaps try using your 4G connection on your phone with the Riot app?

Note: If you do not have a public IP and you are using some kind of VPN, then the allow-loopback-peers in Coturn config file is required! Also, the external-ip= becomes your local VPN IP address (the address of your tun0 interface) followed by / followed by the external VPN IP address that is accessible from the internet. Do not use your LAN IP address and do not use 127.0.0.1.

The end

In the end, your files should look like this:

example/
  data/
    postgres/
      data/
        ... stuff ...
    traefik/
      config/
        middlewares.yml
        routers.yml
      traefik.yml
      acme.json
    matrix/
      coturn/ (optional)
        turnserver.conf
      nginx/
        www/
          .well-known/
            matrix/
              server
              client
        matrix.conf
      synapse/
        media_store/
          ... stuff ...
        homeserver.yml
        matrix.example.com.log.config
        matrix.example.com.signing.key
      riot/
        config.json
  docker-compose.yml
@TekExplorer
Copy link

could i not do away with the synapse subdomain and just set the _matrix pathprefix to it? or am i not seeing something?

@BOZG
Copy link

BOZG commented Feb 7, 2021

@TekExplorer

couldn't i do this for all of it? and whats the .well-known bit for? i have an SRV record (mispelled in the gist btw) so do i need it at all? or can i just add the /_matrix/ path to synapse directly?
- "traefik.http.routers.matrix.rule=(Host(`$DOMAIN`) && PathPrefix(`/.well-known/matrix/`, `/_matrix/`))"
if i dont need the nginx container i'd rather not have it.

.well-known is necessary for Federation server discovery I believe. I presume if you just want a standalone chat server, you wouldn't need it?

Traefik isn't able to serve static resources (.well-known/matrix/server and .well-known/matrix/client) as it's not a web server so you need Nginx (or any form of web server) to handle that bit.

@matusnovak
Copy link
Author

@BOZG

Yes, from inside a temporary container on the same Docker network as the rest (Nginx, Synapse, etc.). By executing that command, using correct IP address of the Nginx container, you bypass the Traefik completely. The header Host: example.com is necessary for Nginx to know what to do next. (I am not 99% sure if that header is necessary). The docker network name should be your stack name followed by _default unless you have explicitly changed it. docker inspect <name of nginx container> should tell you exactly.

@TekExplorer

As BOZG explained, it's for federation.

@BOZG
Copy link

BOZG commented Feb 7, 2021

@matusnovak

Adding a traefik.docker.network label to the container seems to have resolved the issue. I had just use networks: previously which apparently just wasn't enough.

Once again, thanks for the guide! I've made a couple of half-hearted attempts at trying to get Matrix up and running over the past few years and there's always been some issue. Right now everything is working perfectly and I have a functional Facebook Messenger bridge for the first time ever!

@matusnovak
Copy link
Author

@BOZG

Awesome! I am glad it works for you.

@TekExplorer
Copy link

im not sure whats broken now... i got rid of the matrix subdomain and redid things with just the domain. im not sure why but registration isnt working? i can do it, but it breaks on sending the email

@matusnovak
Copy link
Author

@TekExplorer

Sorry, I am using LDAP and never enabled the registration via email. I am not sure what might be the cause.

@TekExplorer
Copy link

looks like more than just email is broken.... what do you recommend for trying to set this up without telling users to use a subdomain?

@majso
Copy link

majso commented Feb 8, 2021

Could you add Turn server as well? It would be great.

@matusnovak
Copy link
Author

@TekExplorer

What happens when you do not use a subdomain? Also, do you mean telling users to use a subdomain for Riot Web?

@matusnovak
Copy link
Author

@majso

Done, it's the optional last section. It's the exact setup I use myself and works without an issue.

@TekExplorer
Copy link

TekExplorer commented Feb 10, 2021

@matusnovak
it seems to sort of work. i cant add an email with the following error: request failed: CORS request rejected: https://<redacted_domain>.com/_matrix/client/r0/account/3pid/email/requestToken and adding a phone number doesn't work? I'm not sure how to correct that.

and yeah, for riot web, and for users to be @user:domain.com instead of @user:matrix.domain.com

edit: looking at the network tab in my browser, looks to actually be a 504 gateway timeout 🤔
edit2: and the response is CORS Missing Allow Origin

@TekExplorer
Copy link

also, is the synapse subdomain even needed? whats it used for?

@matusnovak
Copy link
Author

@TekExplorer

The synapse domain is needed for the SVR DNS record. I am not 100% sure this is really required by Synapse. I got only confusing answers when searching for that on Matrix forums. I would advise to ask someone from the Matrix team to confirm this.

That CORS error sounds to me that it is expecting a different domain based on the configuration. Seems like the issue is due to this: matrix-org/synapse#1595 That CORS is triggered from your browser, from Riot trying to contact Synapse when you are adding a user, right?

What are the CORS headers sent back to you from Synapse? Mine look like this:

access-control-allow-headers: Origin, X-Requested-With, Content-Type, Accept, Authorization, Date
access-control-allow-methods: GET, HEAD, POST, PUT, DELETE, OPTIONS
access-control-allow-origin: *

Have you modified the domain you want your users to access after you have set up the synapse configuration? (First part of the step 4. from above). If yes, this is a big no-no. You can't modify your domain after you have run that generate command.

About the 504 gateway timeout, this may be due to misconfigured Traefik, labels in the Docker Compose, or misconfigured Nginx. I would double check that all of the Docker containers are on the same network (it should be your_stack_name + _default). It is possible you may have encountered the same issue as BOZG in here. You may need to add traefik.docker.network label to your containers. All of this is just a theory, this really depends on how have you set it up and what have you changed.

If it helps in any way, here is Synapse+Nginx+Riot+Coturn docker-compose config all in one place: https://github.com/matusnovak/homelab/blob/master/docker-compose.matrix.yml

@urtzai
Copy link

urtzai commented Mar 2, 2021

Hi! I think is the most complete guide I found so far, but could you please write some example of the Traefik docker-compose.yml section? Thank you!!

@matusnovak
Copy link
Author

@urtzai

Whoops, that should have been there. I have updated the guide. Thank you for letting me know.

@RealAkito
Copy link

Good stuff man, thanks!

@jacktheripper19
Copy link

Hi! is there anyway to disable the access to the static page in https://synapse.example.com/_matrix/static/ while keeping the federation ?

@kleo
Copy link

kleo commented Nov 28, 2021

Here's the format for coturn postgres

psql-userdb="host=postgres dbname=turn user=turn password=password connect_timeout=30"

And add this to docker-entrypoint-initdb.d on your postgres volumes https://github.com/coturn/coturn/blob/master/docker/postgresql/schema.sql

And init.sql

CREATE ROLE turn;
ALTER ROLE turn WITH PASSWORD 'password';
ALTER ROLE turn WITH LOGIN;
CREATE DATABASE turn OWNER turn;
GRANT ALL PRIVILEGES ON DATABASE turn TO turn;

docker-compose.yml

[...]
  postgres:
    image: postgres:11
    restart: unless-stopped
    environment:
      POSTGRES_PASSWORD: "password"
    volumes:
      - ./data/postgres/data:/var/lib/postgresql/data
      - ./data/postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
[...]

ref: https://github.com/coturn/coturn/blob/master/INSTALL#L868

@ivvil
Copy link

ivvil commented Dec 1, 2021

Thanks for the how to, I'm trying to set this up myself, but could someone explain what are you supposed to do with the Traefik docker config? I'm new to docker.

@abyssmemes
Copy link

Thanks for guide! Well may i can do this without traefik? Just with Ngnix reverse proxy?

@TekExplorer
Copy link

TekExplorer commented Dec 26, 2021 via email

@anoadragon453
Copy link

Note that the vectorim/riot-web docker image has been replaced by vectorim/element-web. The former no longer receives updates.

@pnposch
Copy link

pnposch commented Jan 5, 2022

@abyssmemes Not sure if that helps, but i used the nginx-acme-companion instead of traefik, see my fork for the details.

@Psycho0verload
Copy link

@matusnovak
Thank you for the detailed tutorial. Does the integration server work for you. I have now worked through various tutorials but I always get an error that the integration server is not available when I want to use a sticker, for example.

@sethforprivacy
Copy link

One correction here -- if you do not set the Traefik ports to be exposed using host mode, the X-Forwarded-For IP will be incorrect and will cause issues with Synapse down the line, especially around federation.

The ports should be specified like:

      - target: 80
        published: 80
        mode: host
      - target: 443
        published: 443
        mode: host

@C4tWithShell
Copy link

Hi. Thanks for guide! Can coturn be configured with traefik labels?

@Cheety
Copy link

Cheety commented Mar 2, 2023

If you get 502 Error try to add / at the end of location /_matrix:

 # Traefik -> nginx -> synapse
 location /_matrix/ {
    proxy_pass http://synapse:8008;
    proxy_set_header X-Forwarded-For $remote_addr;
    client_max_body_size 128m;
  }

@trackmastersteve
Copy link

trackmastersteve commented Jan 2, 2024

I am having issues with Traefik using "traefik default cert" instead of generating the correct certs for my domain name. What am I doing wrong?

EDIT: I think I found the issue. The Traefik log shows "...uses non-exsistent resolver: letsencrypt" for each of the sub-domains.

@matusnovak
Copy link
Author

I am having issues with Traefik using "traefik default cert" instead of generating the correct certs for my domain name. What am I doing wrong?

EDIT: I think I found the issue. The Traefik log shows "...uses non-exsistent resolver: letsencrypt" for each of the sub-domains.

Yup, that would be it.

Btw, just to note, for HTTP 404 paths (anything that does not belong to Matrix) will give you the traefik default cert.

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