5

I have developed several docker-ized full-stack web applications that I am trying to route requests to using Traefik. I want to take advantage of the dynamic configuration via docker-compose labels. I would like to apply the stripPrefix middleware option so I can use the same application routing as if each app were served at the root. However, once these rules are applied it results in a 504 Gateway Timeout response.

Here's my set up:

  • Traefik 2.0.1
  • Docker 19.03.2, Compose 1.24.1
  • NGINX:latest images
  • A global docker network on which the Traefik container runs
  • Multiple multi-container applications, each of which includes an NGINX web server
  • All applications have their own local networks and the NGINX containers are also on the global network.
  • Each application is configured to be listening at /

Here is the docker-compose.yml definition for the offending NGINX container:

nginx:
        image: nginx:latest
        container_name: "mps_nginx"
        volumes:
        - ./nginx/confs/nginx.conf:/etc/nginx/default.conf
        - ./static:/www/static
        restart: "always"
        labels:
            - traefik.http.routers.mps.rule=Host(`localhost`) && PathPrefix(`/mps`)
            - traefik.http.middlewares.strip-mps.stripprefix.prefixes=/mps
            - traefik.http.routers.mps.middlewares=strip-mps@docker
        networks:
        - default
        - mps

The aggravating part is, when I comment out the middlewares labels, it runs just fine but cannot find a matching URL pattern.

Prior to this I tested my approach using the whoami container that is defined in the Traefik Quickstart Tutorial:

# Test service to make sure our local docker-compose network functions
  whoami:
    image: containous/whoami
    labels:
      - traefik.http.routers.whoami.rule=Host(`localhost`) && PathPrefix(`/whoami`)
      - traefik.http.middlewares.strip-who.stripprefix.prefixes=/whoami
      - traefik.http.routers.whoami.middlewares=strip-who@docker

A request to http://localhost/whoami returns (among other things) GET / HTTP/1.1.

This is exactly how I expected my routing approaches to work for all my other applications. The Traefik dashboard shows green all around for every middleware I register and yet all I see is 504 errors.

If anyone has any clues I would sincerely appreciate it.

3 Answers 3

11

To summarize my solution to a similar problem

  my-service:
    image: some/image
    ports: # no need to expose port, just to show that service listens on 8090
      - target: 8090
        published: 8091
        mode: host
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.myservice-router.rule=PathPrefix(`/myservice/`)"
      - "traefik.http.routers.myservice-router.service=my-service"
      - "traefik.http.services.myservice-service.loadbalancer.server.port=8090"
      - "traefik.http.middlewares.myservice-strip.stripprefix.prefixes=/myservice"
      - "traefik.http.middlewares.myservice-strip.stripprefix.forceslash=false"
      - "traefik.http.routers.myservice-router.middlewares=myservice-strip"

Now details

Routing rule

... redirect all calls thats path starts with /myservice/

- "traefik.http.routers.myservice-router.rule=PathPrefix(`/myservice/`)"

... to service my-service

- "traefik.http.routers.myservice-router.service=my-service"``

... to port 8090

- "traefik.http.services.myservice-service.loadbalancer.server.port=8090"

... and uses myservice-strip middleware

- "traefik.http.routers.myservice-router.middlewares=myservice-strip"

... this middleware will strip /myservice from path

- "traefik.http.middlewares.myservice-strip.stripprefix.prefixes=/myservice"

... and will not add trailing slash (/) if path becomes an empty string

- "traefik.http.middlewares.myservice-strip.stripprefix.forceslash=false"
Sign up to request clarification or add additional context in comments.

2 Comments

I have been trying this set up for 2 days and finally after referring your code was finally able to make it work! Thanks a ton for posting this! Was going mad! Just could not figure out why the backend was not redirecting to my other container
ty for you answer! This solve this fastapi.tiangolo.com/advanced/behind-a-proxy/…
1

There is an issue with prefix without ending with '/'. Test your config like this:

      - "traefik.http.routers.whoami.rule=Host(`localhost`) && (PathPrefix(`//whoami/`) || PathPrefix(`/portainer`))"
      - "traefik.http.middlewares.strip-who.stripprefix.prefixes=/whoami"

1 Comment

is || PathPrefix(/portainer) necessary?
0

I had a similar problem that was solved with the addition of

- "traefik.http.middlewares.strip-who.stripprefix.forceslash=true"

It makes sure the strip prefix doesn't also remove the forward slash.

You can read more about the forceslash documentation https://docs.traefik.io/middlewares/stripprefix/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.