Search code examples
dockerdocker-composetraefik

Traefik 2.0 - Path router rule not working with docker labels


I setup a GraphQL playground listening on port 4000.

So I added the following Traefik labels:

graphql:
  restart: unless-stopped
  labels:
    - traefik.enable=true
    - "traefik.http.routers.${CI_PROJECT_PATH_SLUG}-${CI_ENVIRONMENT_SLUG}-graphql.rule=Host(`graphql.${CI_ENVIRONMENT_HOST}`)"
    - traefik.http.routers.${CI_PROJECT_PATH_SLUG}-${CI_ENVIRONMENT_SLUG}-graphql.tls.certresolver=letsencrypt
    - traefik.http.services.${CI_PROJECT_PATH_SLUG}-${CI_ENVIRONMENT_SLUG}-graphql.loadbalancer.server.port=4000

This is working when I try to get graphql.site.com.

Now I want it to match site.com/graphql, so I changed the router label to this:

"traefik.http.routers.${CI_PROJECT_PATH_SLUG}-${CI_ENVIRONMENT_SLUG}-graphql.rule=Host(`${CI_ENVIRONMENT_HOST}`) && Path(`/graphql`)"

And with this configuration, I have a 404 error on site.com/graphql.

What did I miss?


Solution

  • In my opinion there is no backend application listening on the path /graphql.

    Solution 1:

    Make backend application (GraphQL) listen on path /graphql.

    Probably you should also use PathPrefix(`/graphql`) instead of Path(`/graphql`)

    Solution2:

    Use traefik StripPrefix, which removes prefixes from the path before forwarding the request.

    Use these labels.:

    - "traefik.http.routers.${CI_PROJECT_PATH_SLUG}-${CI_ENVIRONMENT_SLUG}-graphql.rule=Host(`${CI_ENVIRONMENT_HOST}`)"
    - "traefik.http.middlewares.stripprefix-graphql.stripprefix.prefixes=/graphql"
    - "traefik.http.routers.${CI_PROJECT_PATH_SLUG}-${CI_ENVIRONMENT_SLUG}-graphql.middlewares=stripprefix-graphql@docker"
    

    In case the backend is serving assets (e.g., images or Javascript files) you need to implement additional changes on your backend: More info here: https://docs.traefik.io/middlewares/stripprefix/.

    Hope this helps.