Setting up Conduit Matrix server with Traefik

Hi, I've learned about Traefik from a setup guide in Conduit (matrix server) documentation. I become interested in Traefik and I decided to go with the setup method suggested with Traefik.

However the documentation there seemed a bit outdated and I've failed to setup the server. Here are my settings.

Current configurations

# Conduit - Behind Traefik Reverse Proxy
version: '3'

services:
    homeserver:
        ### If you already built the Conduit image with 'docker build' or want to use the Docker Hub image,
        ### then you are ready to go.
        image: matrixconduit/matrix-conduit:latest
        ### If you want to build a fresh image from the sources, then comment the image line and uncomment the
        ### build lines. If you want meaningful labels in your built Conduit image, you should run docker-compose like this:
        ### CREATED=$(date -u +'%Y-%m-%dT%H:%M:%SZ') VERSION=$(grep -m1 -o '[0-9].[0-9].[0-9]' Cargo.toml) docker-compose up -d
        # build:
        #     context: .
        #     args:
        #         CREATED: '2021-03-16T08:18:27Z'
        #         VERSION: '0.1.0'
        #         LOCAL: 'false'
        #         GIT_REF: origin/master
        restart: unless-stopped
        
        labels:
            - "traefik.enable=true"
            - "traefik.docker.network=proxy"  # Change this to the name of your Traefik docker proxy network

            - "traefik.http.routers.to-conduit.rule=Host(`sub_domain.domain.com`)"  # Change to the address on which Conduit is hosted
            - "traefik.http.routers.to-conduit.tls=true"
            - "traefik.http.routers.to-conduit.tls.certresolver=letsencrypt"
            - "traefik.http.routers.to-conduit.middlewares=cors-headers@docker"

            - "traefik.http.middlewares.cors-headers.headers.accessControlAllowOriginList=*"
            - "traefik.http.middlewares.cors-headers.headers.accessControlAllowHeaders=Origin, X-Requested-With, Content-Type, Accept, Authorization"
            - "traefik.http.middlewares.cors-headers.headers.accessControlAllowMethods=GET, POST, PUT, DELETE, OPTIONS"
        ports:
            - 8448:6167

        volumes:
            - db:/srv/conduit/.local/share/conduit
            ### Uncomment if you want to use conduit.toml to configure Conduit
            ### Note: Set env vars will override conduit.toml values
            - ./conduit.toml:/srv/conduit/conduit.toml
        networks:
            - proxy
        environment:
            CONDUIT_SERVER_NAME: sub_domain.domain.com  # replace with your own name
            CONDUIT_TRUSTED_SERVERS: '["matrix.org"]'
            CONDUIT_ALLOW_REGISTRATION : 'true'
            ### Uncomment and change values as desired
            # CONDUIT_ADDRESS: 0.0.0.0
            # CONDUIT_PORT: 6167
            # CONDUIT_CONFIG: '/srv/conduit/conduit.toml'  # if you want to configure purely by env vars, set this to an empty string ''
            # Available levels are: error, warn, info, debug, trace - more info at: https://docs.rs/env_logger/*/env_logger/#enabling-logging
            # CONDUIT_LOG: info  # default is: "warn,_=off,sled=off"
            CONDUIT_LOG: debug
            # CONDUIT_ALLOW_JAEGER: 'false'
            # CONDUIT_ALLOW_ENCRYPTION: 'false'
            # CONDUIT_ALLOW_FEDERATION: 'false'
            # CONDUIT_DATABASE_PATH: /srv/conduit/.local/share/conduit
            # CONDUIT_WORKERS: 10
            # CONDUIT_MAX_REQUEST_SIZE: 20_000_000  # in bytes, ~20 MB

    # We need some way to server the client and server .well-known json. The simplest way is to use a nginx container
    # to serve those two as static files. If you want to use a different way, delete or comment the below service, here
    # and in the docker-compose override file.
    well-known:
        image: nginx:latest
        restart: unless-stopped
        volumes:
            - ./nginx/matrix.conf:/etc/nginx/conf.d/matrix.conf # the config to serve the .well-known/matrix files
            - ./nginx/www:/var/www/ # location of the client and server .well-known-files

    ### Uncomment if you want to use your own Element-Web App.
    ### Note: You need to provide a config.json for Element and you also need a second
    ###       Domain or Subdomain for the communication between Element and Conduit
    ### Config-Docs: https://github.com/vector-im/element-web/blob/develop/docs/config.md
    # element-web:
    #     image: vectorim/element-web:latest
    #     restart: unless-stopped
    #     volumes:
    #         - ./element_config.json:/app/config.json
    #     networks:
    #         - proxy
    #     depends_on:
    #         - homeserver

    traefik:
        image: "traefik:latest"
        container_name: "traefik"
        restart: "unless-stopped"

        ports:
            - "80:80"
            - "443:443"
        volumes:
            - "/var/run/docker.sock:/var/run/docker.sock"
            - "./traefik_config:/etc/traefik/traefik.toml"
            - "acme:/etc/traefik/acme"
        labels:
            - "traefik.enable=true"

            # middleware redirect
            - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
            # global redirect to https
            - "traefik.http.routers.redirs.rule=hostregexp(`{host:.+}`)"
            - "traefik.http.routers.redirs.entrypoints=http"
            - "traefik.http.routers.redirs.middlewares=redirect-to-https"
            - "traefik.docker.network=proxy"

            - "traefik.http.routers.to-matrix-wellknown.rule=Host(`domain.com`) && PathPrefix(`/.well-known/matrix`)"
            - "traefik.http.routers.to-matrix-wellknown.tls=true"
            - "traefik.http.routers.to-matrix-wellknown.tls.certresolver=letsencrypt"
            - "traefik.http.routers.to-matrix-wellknown.middlewares=cors-headers@docker"

            - "traefik.http.middlewares.cors-headers.headers.accessControlAllowOriginList=*"
            - "traefik.http.middlewares.cors-headers.headers.accessControlAllowHeaders=Origin, X-Requested-With, Content-Type, Accept, Authorization"
            - "traefik.http.middlewares.cors-headers.headers.accessControlAllowMethods=GET, POST, PUT, DELETE, OPTIONS"

        networks:
            - proxy

volumes:
    db:
    acme:

networks:
    proxy:

Here is the matrix.conf for nginx:

server {
    server_name domain.com;
    listen      80 default_server;

    location /.well-known/matrix/server {
       return 200 '{"m.server": "domain.com:443"}';
       types { } default_type "application/json; charset=utf-8";
    }

   location /.well-known/matrix/client {
       return 200 '{"m.homeserver": {"base_url": "https://domain.com"}}';
       types { } default_type "application/json; charset=utf-8";
       add_header "Access-Control-Allow-Origin" *;
   }

   location / {
       return 404;
   }
}

I've learned that for Matrix to work probably I need to have .well-known access from base domain while the homeserver served from own subdomain.

I've adapted it from the following docker compose files in my attempt to make it work, however neither the original settings nor mine worked.

Original configurations

Setup Guide

Here is the setup guide that I've used:

Issues

Currently the well-known server is not reached and I'm getting 404 for all links. SSL certificate is not generated and I'm getting this in traefik log:

time="2023-07-29T15:33:33Z" level=debug msg="No default certificate, fallback to the internal generated certificate" tlsStoreName=default

could you please help me solve the issue. Thank you

Use

networks:
  proxy:
    name: proxy

to ensure the name is not changed by compose to include the project name. Otherwise docker.network=proxy might not work.

Add loadbalancer.server.port to labels so Traefik knows which target port to use for a router and service.

If you want well-known service/container to do anything, you need to add labels, otherwise it is not picked up by Traefik and nothing is served.

Share your static config traefik.yml/.toml with entrypoints.

See simple Traefik example.