我尝试配置我的注册表服务以拦截主机+路径
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
知道如何解决这个问题吗?
只有当您尝试启动的应用程序不将自定义 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"
我花了几个小时寻找重定向问题的解决方案并在 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
就太好了,这样一个中间件就可以应用于不同的路由器。