Rule to route /api/v1 and api/v2 rather than using subdomains

I find myself always using subdomains because this makes routing really easy.

For example, let's say I have two versions of an API service

  apiv1:
    depends_on:
      - traefik
    networks:
      - traefik-public
    labels:
      - traefik.enable=true
      - traefik.docker.network=traefik-public
      - traefik.http.routers.apiv1-http.entrypoints=http
      - traefik.http.routers.apiv1-http.rule=Host(`apiv1.example.com`)
      - traefik.http.services.apiv1-http.loadbalancer.server.port=8000

  apiv2:
    depends_on:
      - traefik
    networks:
      - traefik-public
    labels:
      - traefik.enable=true
      - traefik.docker.network=traefik-public
      - traefik.http.routers.apiv2-http.entrypoints=http
      - traefik.http.routers.apiv2-http.rule=Host(`apiv2.example.com`)
      - traefik.http.services.apiv2-http.loadbalancer.server.port=8000

So I access the API documentation web server for each on http://apiv1.example.com/docs and http://apiv2.example.com/docs and a GET request http://apiv1.example.com/ping and http://apiv2.example.com/ping

How do I re-write these rules so that I can instead access the documentation at http://example.com/apiv1/docs and http://example.com/apiv2/docs and the GET request http://example.com/apiv1/ping and http://example.com/apiv2/ping.

Sorry, I don't have a specific error to report right now, as this is a contrived example. I've tried these in the past but could never manage it!

Hi @danieljfarrell,

Thanks for your interest in Traefik!

You can do that by combining Host and PathPrefix rules in your router as explained here: https://doc.traefik.io/traefik/routing/routers/#rule

Therefore, your router could have the following label rules:

apiv1:
traefik.http.routers.apiv1-http.rule=Host(`example.com`) && PathPrefix(`/apiv1`)

apiv2:
traefik.http.routers.apiv2-http.rule=Host(`example.com`) && PathPrefix(`/apiv2`)

Hope this helps!

1 Like