Redirect all URLs without path to the same version with path included

Hi there,

We have recently migrated our sites to docker swarm using Traefik as our reverse proxy. I have gotten the site working on the typical root domain www.example.com. However for legacy and SEO reasons, our site needs to sit in a /fr subfolder with the exception of the assets folder and the robots.txt file.

I have been trying to configure traefik to redirect all URLs with the exception of the assets folder and the robots.txt to the equivalent version under /fr

so examples of the redirections will be

www.example.com => www.example.com/fr
www.example.com/test => www.example.com/fr/test
www.example.com/page => www.example.com/fr/page
www.example.com/assets/image.png => www.example.com/assets/image.png
www.example.com/robots.txt => www.example.com/robots.txt

This is my current working traefik config

labels:
        - traefik.enable=true
        - traefik.http.routers.whoami.entrypoints=https
        - traefik.http.services.whoami.loadbalancer.server.port=5143
        - traefik.http.routers.whoami.rule=Host(`www.example.com`)

I have tried using AddPrefix, and RedirectRegex but I couldn't get it to work properly, just tended to get redirect loops.

Is this possible using traefik?

Many thanks for your time.

You can define 2 routers on your service/container:

services:

  whoami:
    image: traefik/whoami:v1.8
    networks:
      - proxy
    labels:
      - traefik.enable=true
      - traefik.http.routers.whoami.entrypoints=websecure
      - traefik.http.routers.whoami.rule=Host(`example.com`) && (PathPrefix(`/assets`) || Path(`/robots.txt`))
      - traefik.http.routers.whoami.tls.certresolver=myresolver
      - traefik.http.routers.whoami.service=whoami
      - traefik.http.services.whoami.loadbalancer.server.port=80

      - traefik.http.routers.whoami2.entrypoints=websecure
      - traefik.http.routers.whoami2.rule=Host(`example.com`)
      - traefik.http.routers.whoami2.tls.certresolver=myresolver
      - traefik.http.routers.whoami2.service=whoami2
      - traefik.http.services.whoami2.loadbalancer.server.port=80

      - traefik.http.middlewares.myprefix.addprefix.prefix=/foo
      - traefik.http.routers.whoami2.middlewares=myprefix

The first one is checked first, because the rule is longer. If it doesn't match, it will default to the second router, which will add the prefix when forwarding to the service.

Thanks a lot for this. While it didn't exactly work the way I wanted it to (probably my explanation was a bit off), it did point me in the right direction. Here is my the first working code which handles the redirects properly without looping.

labels:
        - traefik.enable=true
        - traefik.http.routers.whoami.entrypoints=https
        - traefik.http.services.whoami.loadbalancer.server.port=5143
        - traefik.http.routers.whoami.rule=Host(`www.example.com`)
        - traefik.http.routers.whoami.service=whoami
        - traefik.http.middlewares.fr-redirectregex.redirectregex.regex=^https:\/\/([^\/]+)\/?(.*)$$
        - traefik.http.middlewares.fr-redirectregex.redirectregex.replacement=https://$${1}/fr/$${2}
        - traefik.http.routers.whoami.middlewares=fr-redirectregex
        
        - traefik.http.routers.whoami2.rule=Host(`www.example.com`) && PathPrefix(`/fr`)