Search code examples
dockerconfigurationmiddlewaretraefik

traefik / ProxyPass: using stripprefix, I get a 404 for sub queries


I try to configure my registry service to intercep host+path https://my-dns.org/registry and redirect to the service http://registry-ui

here is configured my compose :

...

  registry-ui:
    image: joxit/docker-registry-ui:latest
    container_name: registry-ui
    restart: unless-stopped
    environment:
      - REGISTRY_TITLE=My registry
      - NGINX_PROXY_PASS_URL=http://registry:5000
      - SINGLE_REGISTRY=true
      - DELETE_IMAGES=true
    depends_on:
      - registry
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.registry-ui.entrypoints=https"
      - "traefik.http.routers.registry-ui.rule=Host(`my-dns.org`) && PathPrefix(`/registry`)"
      - "traefik.http.routers.registry-ui.middlewares=test-stripprefix"
      - "traefik.http.routers.registry-ui.tls.certresolver=myresolver"
      - "traefik.http.middlewares.test-stripprefix.stripprefix.prefixes=/registry"
      - "traefik.http.middlewares.test-stripprefix.stripprefix.forceSlash=false"
      - "traefik.http.services.registry-ui.loadbalancer.server.port=80"
...

As a result, the index page works fine, but css, js and favicon are lost because the requests look like :

  • https://my-dns.org/docker-registry-ui.css instead of
  • https://my-dns.org/registry/docker-registry-ui.css

Any idea on how to fix that ?


Solution

  • This will only work as long as the app you are trying to start does NOT set a custom html <base> to something hardcoded like root /.

    If this is not the case you might be in luck!

    Your links to sub resources are probably defined relative something like this.

    <link rel="stylesheet" type="text/css" href="docker-registry-ui.css" />
    

    So when you enter into the browser https://my-dns.org/registry your page opens but all links and subsequently css, js is completely broken because the base directory the relative links are based on is still the directory https://my-dns.org/ because you did not enter a subdirectory. The /registry is handled like it is a file and is ignored for relative links.

    • URL: https://my-dns.org/registry
    • Base: https://my-dns.org/
    • Relative Link: docker-registry-ui.css
    • Result: https://my-dns.org/docker-registry-ui.css ⇒ HTTP 404 not found

    For your path prefix to work you need to enter a trailing slash / to access your service. Then the relative links will work as expected.

    • URL: https://my-dns.org/registry/
    • Base: https://my-dns.org/registry/
    • Relative Link: docker-registry-ui.css
    • Result: https://my-dns.org/registry/docker-registry-ui.css ⇒ Link working as expected

    Try to access your service with https://my-dns.org/registry/ (trailing slash) for your links to work as expected.

    If you really must use the link without the trailing slash / to work, you need a path rewrite step to add the trailing slash or alternatively a redirection from https://my-dns.org/registry to https://my-dns.org/registry/.

    Adjust your configuration to add add the trailing slash:

        labels:
          - "traefik.enable=true"
          - "traefik.http.routers.registry-ui.entrypoints=https"
          - "traefik.http.routers.registry-ui.rule=Host(`my-dns.org`) && PathPrefix(`/registry/`)"
          - "traefik.http.routers.registry-ui.middlewares=test-stripprefix"
          - "traefik.http.routers.registry-ui.tls.certresolver=myresolver"
          - "traefik.http.middlewares.test-stripprefix.stripprefix.prefixes=/registry/"
          - "traefik.http.services.registry-ui.loadbalancer.server.port=80"