Cannot reverse Syncthing using path

Hello,

I have a weird problem, I cannot reverse properly Syncthing WebUI using path.

Traefik

My traefik.yaml :

log:
  level: DEBUG

api:
  dashboard: true
  # TODO: make secure
  insecure: true

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
  file:
    directory: /etc/traefik/dynamic
    watch: true

entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure

  websecure:
    address: ":443"

serversTransport:
  # used for Syncthing self-signed certificate
  insecureSkipVerify: true

My dynamic.yaml (I import manually my certs because I'm using them on multiple servers) :

tls:
  # wildcard certificates generated by certbot
  certificates:
    - certFile: /certs/fullchain1.pem
      keyFile: /certs/privkey1.pem
  stores:
    default:
      defaultCertificate:
        certFile: /certs/fullchain1.pem
        keyFile: /certs/privkey1.pem

My compose.yaml :

services:
  traefik:
    restart: unless-stopped
    image: "traefik:v3.1"
    container_name: "traefik"
    ports:
      # HTTP
      - "80:80"
      # HTTPS
      - "443:443"
      # Traefik web interface
      - "8080:8080"
    volumes:
      # Certs generated by external certbot
      - ${DOCKER_VOLUME_STORAGE:-/mnt/docker/volumes}/traefik/certs:/certs
      - ${DOCKER_VOLUME_STORAGE:-/mnt/docker/volumes}/traefik/etc/traefik:/etc/traefik
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - proxy

networks:
  proxy:
    external: true

Syncthing

My compose.yaml :

services:
  syncthing:
    image: syncthing/syncthing
    container_name: syncthing
    hostname: ${DOMAIN}
    environment:
      - PUID=1000
      - PGID=1000
    volumes:
      - ${DOCKER_VOLUME_STORAGE:-/mnt/docker/volumes}/syncthing/var/syncthing:/var/syncthing
    ports:
      - 22000:22000/tcp # TCP file transfers
      - 22000:22000/udp # QUIC file transfers
      - 8384:8384
      # - 21027:21027/udp # Receive local discovery broadcasts
    restart: unless-stopped
    networks:
      - proxy
    labels:
      traefik.enable: "true"
      traefik.docker.network: "proxy"
      traefik.http.services.syncthing.loadbalancer.server.port: 8384
      # apparently not necessary
      # traefik.http.services.syncthing.loadbalancer.server.scheme: https
      traefik.http.routers.syncthing.rule: Host(`${DOMAIN}`) && PathPrefix(`/syncthing`)
      traefik.http.routers.syncthing.entrypoints: websecure
      traefik.http.routers.syncthing.tls: true
networks:
  proxy:
    external: true

traefik.http.routers.syncthing.rule: Host(syncthing.${DOMAIN}) works flawlessly, whereas traefik.http.routers.syncthing.rule: Host(${DOMAIN}) && PathPrefix(/syncthing) does not work.

Apparently Syncthing can properly manage path as stated in the documentation: Reverse Proxy Setup — Syncthing documentation ; but there's no example for Traefik and I couldn't find anything on my search engine related to this.

Does anybody have an idea ?
Thank you
Hug

SyncThing webui seems to be running in root (/, doc), so you can’t just try to route it with a different PathPrefix(), as that will be sent to the target service and that doesn’t know the path.

That’s why sub-domains are best practice.

Hello, mhhh, interesting, thank you for your answer. Didn't know that Syncthing UI is running as root whereas I set uid and gid to another user.

Does someone knows why nginx ou Caddy are able to reverse proxy properly but not traefik ?

Root as in root path /. So you can’t just add a path prefix to it.

You can’t request http://example.com/syncthing when the target service expects http://example.com/.

Enable and check Traefik debug log and access log.