Different services paths with one route

Hello
This is my first time posting
I am grateful to friends who can help me
I wrote a configuration that I wanted to design a service failover that consists of two services
One services for main and one service for backup.
This is fine and works well.
The problem is now in my subpathes. My problem is here
My backup service, i.e. web3, does not have any /rpc
This config puts /rpc for it and I don't want that.
i think treafik do not see any path prefix that you write for services and it just see the prefixes that you write for routes.
i use middleware, but what happens is that it applies to all services related to the respective route.

http:
  routers:
    web-router:
      service: web-service
      rule: "Host(`sample.com`) && PathPrefix(`/rpc`)"
  
  
  services:
    web-service:
      failover:
        healthcheck: {}
        service : main
        fallback: backup

    main:
      loadBalancer:
        servers:
          - url: "http://web1"  # it should routed to http://web1/rpc
         - url: "http://web2" # it should routed to http://web2/rpc

        healthcheck:
          path: "/healthcheck"
          interval: 10s
          timeout: 2s
    backup:
      loadbalancer:
        servers:
          - url: "http://web3" # but it should routed to http://web3 only and without PathPrefix
        healthcheck:
          path: "https://google.com"
          interval: 10s
          timeout: 3s

The standard process is router -> middleware -> service. So I would expect that you can’t use a middleware for just one service.

thanks
Do you have any suggestion for my situation?

No, sorry. Setup all primary and backup servers the same way.

Update: you can probably create two routers, middlewares and services (with different names), use the same rule, have a lower priority (smaller number) for the backup router.

1 Like

thanks
Using priority is not the right way, because it cannot act as a fallback

If the regular router has no more targets, it should become inactive. Then requests should go to lower priority router. But I admit I haven't tested this, just theory for now. Did you test it?

yes i test it,
it doesn t work, if the rule of routers are same, it cant work as fallback.
http:
routers:
a-router:
service: main
rule: "Host(37.32.11.217) && PathPrefix(/rpc)"
priority: 2

b-router:
  middlewares:
  - del-rpc
  service: backup
  rule: "Host(`37.32.11.217`) && PathPrefix(`/rpc`)"
  priority: 1

middlewares:
del-rpc:
stripPrefix:
prefixes:
- "/rpc"
forceSlash: false

services:
main:
loadBalancer:
servers:
- url: "http://web1"
- url: "http://web2"
healthcheck:
path: "/healthcheck"
interval: 10s
timeout: 2s

backup:
  loadbalancer:
    servers:
      - url: "http://web3"
    healthcheck:
      path: "https://google.com"
      interval: 10s
      timeout: 3s

Works for me.

services:
  traefik:
    image: traefik:latest
    ports:
      - 80:80
      - 443:443
    networks:
      - proxy
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - letsencrypt:/letsencrypt
      #- /var/log:/var/log
    command:
      - --api.dashboard=true
      - --log.level=INFO
      #- --log.filepath=/var/log/traefik.log
      - --accesslog=true
      #- --accesslog.filepath=/var/log/traefik-access.log
      #- --accesslog.bufferingsize=1000
      - --providers.docker.network=proxy
      - --providers.docker.exposedByDefault=false
      - --entrypoints.web.address=:80
      - --entrypoints.web.http.redirections.entrypoint.to=websecure
      - --entryPoints.web.http.redirections.entrypoint.scheme=https
      - --entrypoints.websecure.address=:443
      - --entrypoints.websecure.http.tls.certresolver=myresolver
      - --certificatesresolvers.myresolver.acme.email=mail@example.com
      - --certificatesresolvers.myresolver.acme.tlschallenge=true
      - --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json
    labels:
      - traefik.enable=true
      - traefik.http.routers.mydashboard.rule=Host(`traefik.example.com`)
      - traefik.http.routers.mydashboard.service=api@internal
      - traefik.http.routers.mydashboard.middlewares=myauth
      - traefik.http.middlewares.myauth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/

  whoami:
    image: traefik/whoami:v1.10
    networks:
      - proxy
    hostname: primary
    labels:
      - traefik.enable=true
      - traefik.http.routers.mywhoami.priority=2 # higher
      - traefik.http.routers.mywhoami.rule=Host(`whoami.example.com`)
      - traefik.http.services.mywhoami.loadbalancer.server.port=80

  whoami-backup:
    image: traefik/whoami:v1.10
    networks:
      - proxy
    hostname: backup
    labels:
      - traefik.enable=true
      - traefik.http.routers.mywhoami-backup.priority=1 # lower
      - traefik.http.routers.mywhoami-backup.rule=Host(`whoami.example.com`)
      - traefik.http.services.mywhoami-backup.loadbalancer.server.port=80

networks:
  proxy:
    name: proxy

volumes:
  letsencrypt:
    name: letsencrypt

Requests to whoami.example.com show primary. When I stop primary container, it shows backup. When I start primary container again, it shows primary.

Thank you for your answer.
I think I did not convey my meaning correctly.
For failover, it is not the right way to use the same routes with different priorities, because when the priority of our main route is high, the traffic always sends requests to that route first, and when that route fails, we receive a 503 error And traefik doesn't understand that now it should send request to route with lower priority.
Thank you again.

I don’t think that works with Traefik the way you want.

Failover (service)

A failover service job is to forward all requests to a fallback service when the main service becomes unreachable.

As far as I understand, Traefik will only failover and use a backup when the initial target service is not available, meaning Traefik can’t connect to it.

When the service is reachable and Traefik sends a request to it, then there is no turning back. Traefik will send the response to the client, even if it has an error code.

As far as I understand the reason is that Traefik does not cache the request. Traefik reads the header, matches the router, and sends/streams the data to the target service. If the target service responds with error, Traefik simply can not repeat the request, as the (POST) data is not available anymore.