traefik / ProxyPass:使用 stripprefix,我得到子查询的 404

问题描述 投票:0回答:2

我尝试配置我的注册表服务以拦截主机+路径

https://my-dns.org/registry
并重定向到该服务
http://registry-ui

这里配置了我的撰写:

...

  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"
...

结果,索引页面工作正常,但 css、js 和 favicon 丢失了,因为请求看起来像这样:

  • https://my-dns.org/docker-registry-ui.css
    而不是
  • https://my-dns.org/registry/docker-registry-ui.css

知道如何解决这个问题吗?

docker configuration middleware traefik
2个回答
1
投票

只有当您尝试启动的应用程序将自定义 html

<base>
设置为硬编码的内容(例如 root
/
)时,这才有效。

如果不是这种情况,你可能很幸运!

您到子资源的链接可能是相对这样定义的。

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

因此,当您进入浏览器时

https://my-dns.org/registry
,您的页面会打开,但所有链接以及随后的CSS、JS完全损坏,因为相对链接所基于的基本目录仍然是目录
https://my-dns.org/
,因为您没有进入子目录。
/registry
的处理方式就像是一个文件,并且会忽略相对链接。

  • 网址:
    https://my-dns.org/registry
  • 底座:
    https://my-dns.org/
  • 相关链接:
    docker-registry-ui.css
  • 结果:
    https://my-dns.org/docker-registry-ui.css
    ⇒ 未找到 HTTP 404

要使路径前缀生效,您需要输入尾部斜杠

/
才能访问您的服务。然后相关链接将按预期工作。

  • 网址:
    https://my-dns.org/registry/
  • 底座:
    https://my-dns.org/registry/
  • 相关链接:
    docker-registry-ui.css
  • 结果:
    https://my-dns.org/registry/docker-registry-ui.css
    ⇒ 链接按预期工作

尝试使用

https://my-dns.org/registry/
(尾部斜杠)访问您的服务,以使您的链接按预期工作。

如果您确实必须使用不带尾部斜杠

/
的链接才能工作,则需要路径重写步骤来添加尾部斜杠,或者从
https://my-dns.org/registry
重定向到
https://my-dns.org/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.services.registry-ui.loadbalancer.server.port=80"

0
投票

我花了几个小时寻找重定向问题的解决方案并在 Traefik 中保留 URL 前缀。我终于根据此讨论找到了解决方案。关键是使用 Traefik 的 Rewrite Header 插件

我遇到的问题与在 Web 应用程序发起的重定向期间维护 URL 前缀(例如,

/myapp
)有关。默认情况下,Traefik 不会修改
Location
重定向响应中的
HTTP
标头,导致重定向期间前缀丢失。

适合我的配置。

traefik.yml(添加插件)

experimental:
 plugins:
  traefik-plugin-rewrite-headers:
   moduleName: "github.com/XciD/traefik-plugin-rewrite-headers"
   version: "v0.0.4"

traefik-dynamic.yml(配置服务)

routers:
adguard:
  rule: "Host(`v.my-domain.com`) && PathPrefix(`/agh`)"
  service: "adguard-service"
  entryPoints:
    - "websecure"
  middlewares:
    - "strip-adguard-prefix"
    - "adjust-adguard-redirect"
  tls:
    certResolver: "letsEncrypt"
services:
 adguard-service:
  loadBalancer:
    servers:
      - url: "http://192.168.95.40:9500"
middlewares:
 # plugin rewrite-headers for subpath
 adjust-adguard-redirect:
   plugin:
     traefik-plugin-rewrite-headers:
       rewrites:
         - header: "Location"
           regex: "^/(.*)"
           replacement: "/agh/$1"
 strip-adguard-prefix:
   stripPrefix:
     prefixes:
       - "/agh"

此解决方案使我能够通过在

Location
标头中的路径添加必要的前缀来正确处理重定向,从而在重定向用户时保留 URL 结构。

如果能够将

adh
制作为
variable
就太好了,这样一个中间件就可以应用于不同的路由器。

© www.soinside.com 2019 - 2024. All rights reserved.