Traefik routed requests to second container are rejected

A flask app consists of two docker containers, app-frontend & app-backend (these are the actual container names), behind a traefik v2 rev proxy. URL https://app.com is routed to app-frontend, and https://app.com/api is routed to app-backend. app-frontend makes requests to app-backend via https://app.com/api. The rev-proxy & both app containers are all within the same docker network.

Replacing the rev proxy with apache, the following vhosts config works as expected:

ProxyPass "/api" "http://app-backend:5000/"
ProxyPassReverse "/api" "http://app-backend:5000/"
ProxyPass "/" "http://app-frontend:80/"
ProxyPassReverse "/" "http://app-frontend:80/"

Running with this traefik config in docker-compose.yml labels:

    # app-backend labels:
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.app-backend-https.rule=Host(`app.com`) && PathPrefix(`/api`)"
      - "traefik.http.routers.app-backend-https.entryPoints=web-secure"
      - "traefik.http.routers.app-backend-https.tls=true"
      - "traefik.http.routers.app-backend-https.service=app-backend"
      - "traefik.http.services.app-backend.loadbalancer.server.scheme=http"
      - "traefik.http.services.app-backend.loadbalancer.server.port=5000"
    # app-frontend labels:
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.app-frontend-https.rule=Host(`app.com`) && !PathPrefix(`/api`)"
      - "traefik.http.routers.app-frontend-https.entryPoints=web-secure"
      - "traefik.http.routers.app-frontend-https.tls=true"
      - "traefik.http.routers.app-frontend-https.service=app-frontend"
      - "traefik.http.services.app-frontend.loadbalancer.server.port=80"

With this configuration, requests to app-frontend work as expected.
Requests to app-backend appear to be routed to the correct container:

app-backend | 172.18.0.2 - - [09/Oct/2022 13:01:18] "GET /api/config HTTP/1.1" 404 -

but it always respands with status 404 and the message:

The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.

I've not been able to intercept the processing in the backend as this seems to be handled by flask, the destination function is never reached.

I have a suspition that apache may be passing the host as name app-backend:5000 in the request while traefik's docker provider is passing it using the equivlent IP, and that flask is rejecting requests with the IP - but this is a stab in the dark. I'm not aware of any way of overriding the docker IP with the container name in traefik - but as already mentioned - this may not be the issue....

Does anyone have suggestions / ideas why the traefik config would fail when the apache proxy config succeeds?

Hello @Fred and thanks for your interest in Traefik,

I have a suspition that apache may be passing the host as name app-backend:5000 in the request while traefik's docker provider is passing it using the equivlent IP, and that flask is rejecting requests with the IP - but this is a stab in the dark. I'm not aware of any way of overriding the docker IP with the container name in traefik - but as already mentioned - this may not be the issue....

By default, Traefik is forwarding the request Hosts (in your case app.com) to the backend. In case one wants to change that behavior the passHostHeader option can be disabled as explained in the following documentation: Traefik Services Documentation - Traefik. Therefore, the forwarded Host will be app-backend:5000.

Hope this helps!

Problem solved: What I had missed was that the apache line:

`ProxyPass "/api" "http://app-backend:5000/"`

actually removes the /api prefix, whereas traefik was correctly matching it but forwarding the request with the prefix still present. So, added the following lines to strip the prefix, and everything started working:

   - "traefik.http.middlewares.test-stripprefix.stripprefix.prefixes=/api"
   - "traefik.http.routers.app-backend-https.middlewares=test-stripprefix"
1 Like