Complex routing rule

How to write complex rule for Traefik?
Configuration provider is Docker.

Rule, explained:
if ( cookie contains lang=en ) or ( cookie not contains 'lang' at all and accept-language='en.*')

Hi @aeifn

Without the actual regex:

traefik.http.routers.foo.rule: HeadersRegexp(`Cookie`,``) || (HeadersRegexp(`Cookie`,``) && HeadersRegexp(`accept-language`,``))

Thank you, @cakiwi !
How to write regexp 'cookie not contains "lang=" at all'?
Afaik, golang regexp package does not support negative matching. (https://stackoverflow.com/questions/47211017/regex-expression-negated-set-not-working-golang)

Damn that is a shame.

Would you receive both lang in the cookie and accept-language anyway? I'm not familiar with language requests.

Or design with a preference of over over the other with a simple OR ||

@cakiwi, you are right, pattern with priorities do the job!

But config seems too repetitive, is there any way to refactor?


  frontend_ru:
    image: site/frontend:${TAG}
    networks:
      - traefik-public
    deploy:
      labels:
        # ENABLE TRAEFIK
        - traefik.enable=true
        - traefik.docker.network=traefik-public
        - traefik.constraint-label=traefik-public

        # DEFAULT
        - traefik.http.routers.site-frontend-ru-default.rule=Host(`${DOMAIN}`)&&PathPrefix(`/js`, `/img`, `/style`, `/tpl`)
        - traefik.http.routers.site-frontend-ru-default.entrypoints=https
        - traefik.http.routers.site-frontend-ru-default.tls=true
        - traefik.http.routers.site-frontend-ru-default.tls.certresolver=le
        - traefik.http.routers.site-frontend-ru-default.priority=100

        # COOKIE RU
        - traefik.http.routers.site-frontend-ru-cookie.rule=Host(`${DOMAIN}`)&&PathPrefix(`/js`, `/img`, `/style`, `/tpl`)&&HeadersRegexp(`Cookie`, `past.lang=ru`)
        - traefik.http.routers.site-frontend-ru-cookie.entrypoints=https
        - traefik.http.routers.site-frontend-ru-cookie.tls=true
        - traefik.http.routers.site-frontend-ru-cookie.tls.certresolver=le
        - traefik.http.routers.site-frontend-ru-cookie.priority=400

        # ENABLE LOADBALANCER
        - traefik.http.services.site-frontend-ru.loadbalancer.server.port=80

  frontend_en:
    image: site/frontend:${TAG_EN}
    networks:
      - traefik-public
    deploy:
      labels:
        # ENABLE TRAEFIK
        - traefik.enable=true
        - traefik.docker.network=traefik-public
        - traefik.constraint-label=traefik-public

        # ACCEPT-LANG
        - traefik.http.routers.site-frontend-en-acclang.rule=Host(`${DOMAIN}`)&&PathPrefix(`/js`, `/img`, `/style`, `/tpl`)&&HeadersRegexp(`Accept-Language`, `^en.*`)
        - traefik.http.routers.site-frontend-en-acclang.entrypoints=https
        - traefik.http.routers.site-frontend-en-acclang.tls=true
        - traefik.http.routers.site-frontend-en-acclang.tls.certresolver=le
        - traefik.http.routers.site-frontend-en-acclang.priority=200

        # COOKIE EN
        - traefik.http.routers.site-frontend-en-cookie.rule=Host(`${DOMAIN}`)&&PathPrefix(`/js`, `/img`, `/style`, `/tpl`)&&HeadersRegexp(`Cookie`, `past.lang=en`)
        - traefik.http.routers.site-frontend-en-cookie.entrypoints=https
        - traefik.http.routers.site-frontend-en-cookie.tls=true
        - traefik.http.routers.site-frontend-en-cookie.tls.certresolver=le
        - traefik.http.routers.site-frontend-en-cookie.priority=300

        # ENABLE LOADBALANCER
        - traefik.http.services.site-frontend-en.loadbalancer.server.port=80
1 Like

Surprised emoji

You can loose all three of these or the last two depending on your entrypoints by setting default tls on the entrypoint. https://doc.traefik.io/traefik/routing/entrypoints/#tls
If you have just https entrypoint you can loose the entrypoints label as the router will bind all entrypoints.

        - traefik.http.routers.site-frontend-ru-default.entrypoints=https
        - traefik.http.routers.site-frontend-ru-default.tls=true
        - traefik.http.routers.site-frontend-ru-default.tls.certresolver=le

This sets the address, tls and resolver. Command line argument version.

--entrypoints.https.address=:443
--entrypoints.https.tls.certResolver=leresolver
1 Like

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.