skip to Main Content

traefik rule not redirecting requests made to "localhost/api" to backend container

Whenever I change the backend

- "traefik.http.routers.api.rule=Host(`localhost`) && PathPrefix(`/api`)"

to Host(‘localhost’) I can access the application at localhost but after adding this rule, whenever I go to localhost/api , it leads me to frontend and opens html page

version: '3'
volumes:
  myvol2:
    external: false
services:
  traefik:
    image: "traefik:v2.6"
    command:
      #- "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--api.dashboard=true"
      - "--api.debug=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.api.address=:5000"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443" # new
    ports:
      - "80:80"
      - "5000:5000"
      - "443:443" # new
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
  api:
    image: "myimagename"
    ports:
      - '5000'
    scale: 1
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api.rule=Host(`localhost`) && PathPrefix(`/api`)"
      - "traefik.http.routers.api.entrypoints=web"
      - "traefik.http.services.api.loadbalancer.server.port=5000"
    volumes:
      - /app/node_modules
      - ./server:/app
      - myvol2:/resources/static/assets/uploads # Volume
    environment:
      - PORT=5000
  web:
    image: "myfrontendimage"
    stdin_open: true
    scale: 1
    ports:
      - '3000'
    environment:
      - CHOKIDAR_USEPOLLING=true
      - CI=true
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.web.rule=Host(`localhost`)"
      - "traefik.http.routers.web.entrypoints=web"
      - "traefik.http.services.web.loadbalancer.server.port=3000"
    volumes:
      - /app/node_modules
      - ./client:/app

Tried redirecting the Tried almost all combinations of route, even tried adding regexp for matching localhost/api.

With my current nginx setup,
I have :

  location /api{
    rewrite /api/(.*) /$1 break;
    proxy_pass http://api;
  }

in my default.conf,

Trying to migrate to traefik but the requests to localhost/api are not reaching

2

Answers


  1. Chosen as BEST ANSWER

    Finally, got the traefik /api to redirect to the other backend container with the following set up

    The primary issue was that even though it redirects to the container, it did not strip the /api prefix, so the API route was getting messed up

        labels:
          - "traefik.enable=true"
          - "traefik.http.routers.api.rule=PathPrefix(`/api/`)"
          - "traefik.http.routers.api.service=api"
          - "traefik.http.services.api.loadbalancer.server.port=5000"
          - "traefik.http.middlewares.api.stripprefix.prefixes=/api"
          - "traefik.http.middlewares.api.stripprefix.forceSlash=false"
          - "traefik.http.routers.api.middlewares=api"
    

  2. Your configuration seems to be fine. In your question you have a bunch of placeholder values, so it’s not actually possible to test your docker-compose.yaml, but we can produce a runnable version like this:

    services:
    
      traefik:
        image: "traefik:v2.9"
        command:
          - "--api.insecure=true"
          - "--api.dashboard=true"
          - "--api.debug=true"
          - "--providers.docker=true"
          - "--providers.docker.exposedbydefault=false"
          - "--entrypoints.web.address=:80"
          - "--entrypoints.websecure.address=:443"
    
        # The port mappings here are to avoid conflicts with other services
        # on my system
        ports:
          - "7080:80"
          - "7443:443"
          - "7090:8080"
        volumes:
          - "/var/run/docker.sock:/var/run/docker.sock:ro"
      api:
        # Note that we don't need a `ports` configuration here because we're
        # not publish any ports to the host (all access will be via the
        # frontend proxy).
        image: "docker.io/traefik/whoami:latest"
        command:
          - --name=API
          - --port=5000
        labels:
          - "traefik.enable=true"
          - "traefik.http.routers.api.rule=Host(`localhost`) && PathPrefix(`/api`)"
          - "traefik.http.routers.api.entrypoints=web"
          - "traefik.http.services.api.loadbalancer.server.port=5000"
      web:
        image: "docker.io/traefik/whoami:latest"
        command:
          - --name=WEB
          - --port=3000
        labels:
          - "traefik.enable=true"
          - "traefik.http.routers.web.rule=Host(`localhost`)"
          - "traefik.http.routers.web.entrypoints=web"
          - "traefik.http.services.web.loadbalancer.server.port=3000"
    

    The significant changes here are:

    • I’m using Traefik v2.9 (because why use an older release?)
    • I’ve replaced all your images with docker.io/traefik/whoami, which gives us a simple endpoint for testing.

    With the above configuration, a request to http://localhost hits the "web" container:

    $ curl localhost:7080
    Name: WEB
    [...]
    

    Whereas a request to http://localhost/api hits the "api" container:

    $ curl localhost:7080/api
    {...., "name": "API"}
    

    (We’re getting a JSON response in the second case because we’re hitting the /api path on the whoami container.)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search