Routing paths with Traefik

Currently I’m trying set up a loadbalancer/reverse proxy with Traefik for some docker containers. I’m having trouble with configuring Treafik to make my apps available using a some prefix paths. I’m able to get a basic Traefik configuration running using Docker and Docker compose, based on this example. The problem is that I’m able to get the ‘whoamI’ container to be reachable at a path, but not my app and other containers.

For example, I’ve created a docker-compose file (see below) to start the whoamI container, and five Portainer containers (so people can recreate the scenario). I would expect woamI to be available at /wai and Portainer at /portainer1.

  • Using Docker, how do you execute PHP composer commands?
  • How do I create docker image from an existing CentOS?
  • NodeJS: How to do nightmareJS e2e-testing on running docker application
  • How to permanently set an environmental variable in an existing docker container?
  • Docker: communication between web container and php container
  • Run Go app created in windows in Docker container (Ubuntu)
  • Instead, I can reach the whoamI webserver (via /wai) and not Portainer (via /portainer1). However, I am able to reach Portainer at /portainer2. The only difference in Traefik configuration between these two is the use of ‘PathStrip’ instead of ‘Path’. The annoying thing, however, is that I can only obtain a white page when navigating to /portainer2; only the page title and some html is loaded. I have also started a Portainer container which is exposed to the host machine, to verify the expected behavior (a normal Portainer page). See also the attached image below.

    Edit:

    Interestingly, I’m also able to reach Portainer at /portainer4/ (but not /portainer4) resulting in the same white page. The difference between navigating to /portainer2/ and /portainer4/ is that I notice some additional logging in Traefik (see below). When navigating to Portainer via /portainer4/, three extra lines show up in the log indicating a 400 status. After some investigation, I found out that this comes from my browser’s attempt to load additional files (i.e. a javascript file, a favicon and a stylesheet). So, when accessing Portainer at /portainer4/ my browser knows it needs to fetch those extra files and tries to do so (which does not happen when navigating to /portainer2). When trying to access the files myself by, for example, navigating to /portainer4/ico/favicon.ico, I get a 400 Bad Request. Lastly, when navigating to /portainer2/ico/favicon.ico is see a 404 page not found.

    Based on these results I’m wondering:

    • Why I cannot reach Portainer at /portainer1 but instead on
      /portainer2?
    • Why I do not see the full Portainer page when navigating to
      /portainer2?
    • Why there is a difference in behavior between accessing a file (e.g. the favicon) between /portainer2/ and /portainer4/
    • What the 400 Bad Request actually means and if/how this problem this problem can be fixed

    I would really appreciate some pointers in the right direction

    Some screenshots:
    Different Treafik paths

    docker-compose.yml:

    version: '2'
    
    services:   
      traefik:
        container_name: traefik
        image: traefik
        command: --web --docker --docker.domain=docker.localhost --logLevel=DEBUG
        ports:
          - "80:80"
          - "8080:8080"
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock
          - /dev/null:/traefik.toml
        labels:
            - "traefik.enable=false"      
      whoami:
        image: emilevauge/whoami
        labels:
          - "traefik.backend=whoami"
          - "traefik.frontend.rule=Path: /wai/"   
      portainer1:
        image: portainer/portainer
        labels:
          - "traefik.backend=portainer1"
          - "traefik.frontend.rule=Path: /portainer1/"   
      portainer2:
        image: portainer/portainer
        labels:
          - "traefik.backend=portainer2"
          - "traefik.frontend.rule=PathStrip: /portainer2/"      
      portainer:
        image: portainer/portainer
        ports:
          - "9000:9000"
        labels:
            - "traefik.enable=false"
    

    Additional Traefik logging generated after visiting /wai, /portainer1/, <myIP>/portainer2/, /portainer3/ and /portainer4/, respectively:

    time="2017-01-13T14:33:16Z" level=debug msg="Round trip: http://172.19.0.2:80, code: 200, duration: 1.000627ms"
    time="2017-01-13T14:33:22Z" level=debug msg="Round trip: http://172.19.0.7:9000, code: 404, duration: 1.006089ms"
    time="2017-01-13T14:33:24Z" level=debug msg="Round trip: http://172.19.0.3:9000, code: 200, duration: 1.160158ms"
    time="2017-01-13T14:33:26Z" level=debug msg="Round trip: http://172.20.0.5:9000, code: 404, duration: 1.291309ms"
    time="2017-01-13T14:33:29Z" level=debug msg="Round trip: http://172.20.0.4:9000, code: 200, duration: 2.788462ms"
    time="2017-01-13T14:33:29Z" level=debug msg="Round trip: http://172.20.0.4:9000, code: 400, duration: 777.073┬Ás"
    time="2017-01-13T14:33:30Z" level=debug msg="Round trip: http://172.20.0.4:9000, code: 400, duration: 1.780621ms"
    time="2017-01-13T14:33:30Z" level=debug msg="Round trip: http://172.20.0.4:9000, code: 400, duration: 1.780341ms"
    

  • Docker expose link to host machine
  • Connect to HBase running in Docker
  • Unable to run java Program. Error inside docker
  • Override .dockerignore file when using ADD
  • What does the operator $() mean in Docker
  • Can't get Pod info in the kubernetes cluster
  • One Solution collect form web for “Routing paths with Traefik”

    This morning I found the solution. The correct approach in cases like these should be to use the PathPrefixStrip rule. However, as mentioned here, putting a / at the end of the rule will break the setup. I created a working configuration by removing / at the end of the PathPrefixStrip: /portainer4/ rule. So this docker-compose configuration worked for me:

    version: '2'
    
    services:
      traefik:
        container_name: traefik2
        image: traefik
        command: --web --docker --docker.domain=docker.localhost --logLevel=DEBUG
        ports:
          - "80:80"
          - "8081:8080"
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock
          - /dev/null:/traefik.toml
        labels:
            - "traefik.enable=false"
      portainer:
        image: portainer/portainer
        labels:
          - "traefik.backend=portainer"
          - "traefik.frontend.rule=PathPrefixStrip: /portainer"
    

    Now when I navigate to <myIP>/portainer/ I see the portainer page. I do, however, still get the white page as mentioned earlier when I navigate to <myIP>/portainer.

    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.