Search code examples
docker-composetraefik

Traefik docker-compose path based routing


I have two services in a docker containers and I'm using Traefik as a reverse proxy to route requests between the two services. I have the following docker-compose.yml file:

version: "3.9"
services:
  
  api: 
    image: 'juliandimitrov/api-image:latest'
    container_name: 'api'
    expose:
      - "80"
    environment:
      - ASPNETCORE_URLS=http://0.0.0.0:80
    labels:
      - "traefik.enable=true"
      # - "traefik.http.routers.api.entrypoints=web"
      - "traefik.http.routers.api.rule=HostRegexp(`my-site.com/api`) && PathPrefix(`/api`)"
      - "traefik.http.middlewares.api-stripprefix.stripprefix.prefixes=/api"
      - "traefik.http.routers.api.middlewares=myapp-stripprefix@docker"
      - "traefik.http.services.api.loadbalancer.server.port=80"

  web:
    image: 'juliandimitrov/web-image:latest'
    container_name: 'web'
    expose:
      - "80"
    labels:
      - "traefik.enable=true"
      # - "traefik.http.routers.web.entrypoints=web"
      - "traefik.http.routers.web.rule=Host(`my-site.com`)"
      - "traefik.http.services.web.loadbalancer.server.port=80"

  proxy:
    image: "traefik:v2.5"
    container_name: "proxy"
    command:
      - "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - //var/run/docker.sock:/var/run/docker.sock:ro

If I go to my browser and type http://my-site.com it routes the request to the web service. Then I try http://my-site.com/api/users/authenticate it routes it again in the web service, but I want all the requests that are /api to be routed to the api service.

How can I achieve that, because obviously my docker-compose configuration is not right.

Thanks in advance!


Solution

  • After a little bit of digging and trial and errors I managed it working with the following docker-compose.yml:

    version: "3.9"
    services:
      
      api: 
        image: 'juliandimitrov/api-image:latest'
        container_name: 'api'
        expose:
          - "80"
        environment:
          - ASPNETCORE_URLS=http://0.0.0.0:80
        labels:
          - "traefik.enable=true"
          - "traefik.http.routers.api.rule=Host(`my-site.com/api`) && PathPrefix(`/api`)"
          - "traefik.http.routers.api.middlewares=strip-prefix"
          - "traefik.http.middlewares.strip-prefix.stripprefix.prefixes=/api"
          - "traefik.http.services.api.loadbalancer.server.port=80"
    
      web:
        image: 'juliandimitrov/web-image:latest'
        container_name: 'web'
        expose:
          - "80"
        labels:
          - "traefik.enable=true"
          - "traefik.http.routers.web.rule=Host(`my-site.com`)"
          - "traefik.http.services.web.loadbalancer.server.port=80"
    
      proxy:
        image: "traefik:v2.5"
        container_name: "proxy"
        command:
          - "--log.level=DEBUG"
          - "--api.insecure=true"
          - "--providers.docker=true"
        ports:
          - "80:80"
          - "443:443"
          - "8080:8080"
        volumes:
          - //var/run/docker.sock:/var/run/docker.sock:ro
    

    Basicly the problem was in the strip-perfix middleware.