特雷菲克 addPrefix/replacePathRegex
Treafik addPrefix/replacePathRegex
我正在尝试使用 docker 设置地理服务器和 traefik,但路径有问题。
Geoserver 的主要入口点在 /geoserver
,但我想让它可以在我的域的根路径上访问,比方说 example.com
。这是我放在一起的 docker-compose
文件:
version: "3"
services:
traefik:
image: traefik:2.4
restart: unless-stopped
networks:
- web
ports:
- 80:80
- 443:443
command:
- --log.level=DEBUG
- --providers=docker
- --providers.docker.network=geoserver_web
- --entrypoints.websecure.address=:443
- --entrypoints.web.address=:80
- --entrypoints.web.http.redirections.entrypoint.to=websecure
- --entrypoints.web.http.redirections.entrypoint.scheme=websecure
# - --api.dashboard=true
- --certificatesresolvers.lets-encrypt.acme.email=admin@example.com
- --certificatesresolvers.lets-encrypt.acme.storage=acme.json
- --certificatesresolvers.lets-encrypt.acme.tlschallenge=true
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./letsencrypt:/letsencrypt
geoserver:
image: oscarfonts/geoserver:latest
restart: unless-stopped
networks:
- web
labels:
- traefik.port=8080
- traefik.http.routers.geoserver.rule=Host(`example.com`)
- traefik.http.routers.geoserver.entrypoints=websecure
- traefik.http.routers.geoserver.tls=true
- traefik.http.routers.geoserver.tls.certresolver=lets-encrypt
- traefik.http.middlewares.geoserver.replacepathregex.regex=(.*)
- traefik.http.middlewares.geoserver.replacepathregex.replacement=/geoserver/$
networks:
web:
在完成 traefik docs 之后,我认为在地理服务器服务上使用 replacepathregex
应该将 /geoserver
添加到传递给地理服务器的所有请求的路径中,并且应该使服务可用example.com
,而不是 example.com/geoserver
,但它没有用。
我也试过addPrefix
,但也没用。
我的配置不正确吗?
或者我对这些中间件做什么的理解?
有没有办法将我的服务配置为可在 example.com
而不是 example.com/geoserver
访问?
关于ReplacePathRegex: Configuration Examples,Docker标签,它提到如下例子:-
# Replace path with regex
labels:
- "traefik.http.middlewares.test-replacepathregex.replacepathregex.regex=^/foo/(.*)"
- "traefik.http.middlewares.test-replacepathregex.replacepathregex.replacement=/bar/$"
连同以下引用
Regular expressions and replacements can be tested using online tools such as Go Playground or Regex101.
我使用Regex101测试并确保上面的示例配置并扩展,以便我们在以下场景中实现我们的需求。
测试用例 1
- 正则表达式:
/foo/(.*)
(注意:这里没有前导插入符^
)
- 测试字符串:
https://my.domain.com/foo/api
- 代入:
/bar/
(注:此处有单元唱$
,稍后说明)
- 结果:
https://my.domain.com/bar/api
测试用例 2
- 正则表达式:
/foo/(.*)
- 测试字符串:
https://my.domain.com/foo/api
- 替换:
/
- 结果:
https://my.domain.com/api
测试用例 3:geoserver 第 1 轮
- 正则表达式:
(.*)/(.*)
- 测试字符串:
https://my.domain.com/api
- 替换:
/geoserver/
- 结果:
https://my.domain.com/geoserver/api
测试用例 4:地理服务器第 2 轮
- 正则表达式:
(.*)/(.*)
- 测试字符串:
https://my.domain.com/api
- 替换:
/geoserver/
- 结果:
/geoserver/api
侧边栏 1:为什么我们需要双美元唱 ($$
)?
因为docker-compose以$VARIABLE
和[的形式提供了变量替换 =33=],则美元符号是 key word / reserved word
,我们必须 转义 它并使我们在 [= 中使用美元符号 ($$
) 36=]。请参阅 Whosebug and 了解更多信息。
边栏 2:前导插入符号 (^
)
经过一段时间的反复试验,我意识到这有点不同,因为 Traefik 需要前导插入符号,而 Regex101 不需要。直到现在,我仍然不知道为什么会这样,并且记得那样 :D
总结
为了按照测试用例 4 实现我们的要求,docker-compose label 应该作为下面的例子
labels:
- traefik.http.middlewares.geoserver.replacepathregex.regex=^(.*)/(.*) # <-- the leading caret
- traefik.http.middlewares.geoserver.replacepathregex.replacement=/geoserver/$
编辑 1
测试用例 5:地理服务器第 3 轮
正则表达式:^(.*:)//([A-Za-z0-9\-\.]+)(:[0-9]+)?/(.*)$
测试字符串:https://my.domain.com/path
- 替换:
/geoserver/
- 结果:
/geoserver/path
测试字符串:https://my.domain.com/path/to
- 替换:
/geoserver/
- 结果:
/geoserver/path/to
测试字符串:https://my.domain.com/path/to/api
- 替换:
/geoserver/
- 结果:
/geoserver/path/to/api
测试字符串:https://my.domain.com/path/to/api?key=value
- 替换:
/geoserver/
- 结果:
/geoserver/path/to/api?key=value
测试字符串:https://my.domain.com/path/to/api?key=value&anotherkey=anothervalue
- 替换:
/geoserver/
- 结果:
/geoserver/path/to/api?key=value&anotherkey=anothervalue
总结
为了按照测试用例 5 实现我们的要求,docker-compose label 应该作为下面的例子
labels:
- traefik.http.middlewares.geoserver.replacepathregex.regex=^(.*:)//([A-Za-z0-9\-\.]+)(:[0-9]+)?/(.*)$$ # <-- the leading caret and double dollar sign at the end
- traefik.http.middlewares.geoserver.replacepathregex.replacement=/geoserver/$
原来问题出在我的 traefik 配置上!我需要将中间件添加到地理服务器路由器。这是更新后的 docker-compose.yml
(我使用 addprefix
而不是 replacepathregex
,因为后者太过分了):
version: "3"
services:
traefik:
image: traefik:2.4
restart: unless-stopped
networks:
- web
ports:
- 80:80
- 443:443
command:
- --log.level=DEBUG
- --providers=docker
- --providers.docker.network=geoserver_web
- --entrypoints.websecure.address=:443
- --entrypoints.web.address=:80
- --entrypoints.web.http.redirections.entrypoint.to=websecure
- --entrypoints.web.http.redirections.entrypoint.scheme=websecure
# - --api.dashboard=true
- --certificatesresolvers.lets-encrypt.acme.email=admin@example.com
- --certificatesresolvers.lets-encrypt.acme.storage=acme.json
- --certificatesresolvers.lets-encrypt.acme.tlschallenge=true
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./letsencrypt:/letsencrypt
geoserver:
image: oscarfonts/geoserver:latest
restart: unless-stopped
networks:
- web
labels:
- traefik.http.middlewares.add-geoserver-prefix.addprefix.prefix=/geoserver
- traefik.port=8080
- traefik.http.routers.geoserver.rule=Host(`example.com`)
- traefik.http.routers.geoserver.entrypoints=websecure
- traefik.http.routers.geoserver.tls=true
- traefik.http.routers.geoserver.tls.certresolver=lets-encrypt
- traefik.http.routers.geoserver.middlewares=add-geoserver-prefix@docker
networks:
web:
我正在尝试使用 docker 设置地理服务器和 traefik,但路径有问题。
Geoserver 的主要入口点在 /geoserver
,但我想让它可以在我的域的根路径上访问,比方说 example.com
。这是我放在一起的 docker-compose
文件:
version: "3"
services:
traefik:
image: traefik:2.4
restart: unless-stopped
networks:
- web
ports:
- 80:80
- 443:443
command:
- --log.level=DEBUG
- --providers=docker
- --providers.docker.network=geoserver_web
- --entrypoints.websecure.address=:443
- --entrypoints.web.address=:80
- --entrypoints.web.http.redirections.entrypoint.to=websecure
- --entrypoints.web.http.redirections.entrypoint.scheme=websecure
# - --api.dashboard=true
- --certificatesresolvers.lets-encrypt.acme.email=admin@example.com
- --certificatesresolvers.lets-encrypt.acme.storage=acme.json
- --certificatesresolvers.lets-encrypt.acme.tlschallenge=true
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./letsencrypt:/letsencrypt
geoserver:
image: oscarfonts/geoserver:latest
restart: unless-stopped
networks:
- web
labels:
- traefik.port=8080
- traefik.http.routers.geoserver.rule=Host(`example.com`)
- traefik.http.routers.geoserver.entrypoints=websecure
- traefik.http.routers.geoserver.tls=true
- traefik.http.routers.geoserver.tls.certresolver=lets-encrypt
- traefik.http.middlewares.geoserver.replacepathregex.regex=(.*)
- traefik.http.middlewares.geoserver.replacepathregex.replacement=/geoserver/$
networks:
web:
在完成 traefik docs 之后,我认为在地理服务器服务上使用 replacepathregex
应该将 /geoserver
添加到传递给地理服务器的所有请求的路径中,并且应该使服务可用example.com
,而不是 example.com/geoserver
,但它没有用。
我也试过addPrefix
,但也没用。
我的配置不正确吗?
或者我对这些中间件做什么的理解?
有没有办法将我的服务配置为可在 example.com
而不是 example.com/geoserver
访问?
关于ReplacePathRegex: Configuration Examples,Docker标签,它提到如下例子:-
# Replace path with regex
labels:
- "traefik.http.middlewares.test-replacepathregex.replacepathregex.regex=^/foo/(.*)"
- "traefik.http.middlewares.test-replacepathregex.replacepathregex.replacement=/bar/$"
连同以下引用
Regular expressions and replacements can be tested using online tools such as Go Playground or Regex101.
我使用Regex101测试并确保上面的示例配置并扩展,以便我们在以下场景中实现我们的需求。
测试用例 1
- 正则表达式:
/foo/(.*)
(注意:这里没有前导插入符^
) - 测试字符串:
https://my.domain.com/foo/api
- 代入:
/bar/
(注:此处有单元唱$
,稍后说明) - 结果:
https://my.domain.com/bar/api
测试用例 2
- 正则表达式:
/foo/(.*)
- 测试字符串:
https://my.domain.com/foo/api
- 替换:
/
- 结果:
https://my.domain.com/api
测试用例 3:geoserver 第 1 轮
- 正则表达式:
(.*)/(.*)
- 测试字符串:
https://my.domain.com/api
- 替换:
/geoserver/
- 结果:
https://my.domain.com/geoserver/api
测试用例 4:地理服务器第 2 轮
- 正则表达式:
(.*)/(.*)
- 测试字符串:
https://my.domain.com/api
- 替换:
/geoserver/
- 结果:
/geoserver/api
侧边栏 1:为什么我们需要双美元唱 ($$
)?
因为docker-compose以$VARIABLE
和[的形式提供了变量替换 =33=],则美元符号是 key word / reserved word
,我们必须 转义 它并使我们在 [= 中使用美元符号 ($$
) 36=]。请参阅 Whosebug
边栏 2:前导插入符号 (^
)
经过一段时间的反复试验,我意识到这有点不同,因为 Traefik 需要前导插入符号,而 Regex101 不需要。直到现在,我仍然不知道为什么会这样,并且记得那样 :D
总结
为了按照测试用例 4 实现我们的要求,docker-compose label 应该作为下面的例子
labels:
- traefik.http.middlewares.geoserver.replacepathregex.regex=^(.*)/(.*) # <-- the leading caret
- traefik.http.middlewares.geoserver.replacepathregex.replacement=/geoserver/$
编辑 1
测试用例 5:地理服务器第 3 轮
正则表达式:
^(.*:)//([A-Za-z0-9\-\.]+)(:[0-9]+)?/(.*)$
测试字符串:
https://my.domain.com/path
- 替换:
/geoserver/
- 结果:
/geoserver/path
- 替换:
测试字符串:
https://my.domain.com/path/to
- 替换:
/geoserver/
- 结果:
/geoserver/path/to
- 替换:
测试字符串:
https://my.domain.com/path/to/api
- 替换:
/geoserver/
- 结果:
/geoserver/path/to/api
- 替换:
测试字符串:
https://my.domain.com/path/to/api?key=value
- 替换:
/geoserver/
- 结果:
/geoserver/path/to/api?key=value
- 替换:
测试字符串:
https://my.domain.com/path/to/api?key=value&anotherkey=anothervalue
- 替换:
/geoserver/
- 结果:
/geoserver/path/to/api?key=value&anotherkey=anothervalue
- 替换:
总结
为了按照测试用例 5 实现我们的要求,docker-compose label 应该作为下面的例子
labels:
- traefik.http.middlewares.geoserver.replacepathregex.regex=^(.*:)//([A-Za-z0-9\-\.]+)(:[0-9]+)?/(.*)$$ # <-- the leading caret and double dollar sign at the end
- traefik.http.middlewares.geoserver.replacepathregex.replacement=/geoserver/$
原来问题出在我的 traefik 配置上!我需要将中间件添加到地理服务器路由器。这是更新后的 docker-compose.yml
(我使用 addprefix
而不是 replacepathregex
,因为后者太过分了):
version: "3"
services:
traefik:
image: traefik:2.4
restart: unless-stopped
networks:
- web
ports:
- 80:80
- 443:443
command:
- --log.level=DEBUG
- --providers=docker
- --providers.docker.network=geoserver_web
- --entrypoints.websecure.address=:443
- --entrypoints.web.address=:80
- --entrypoints.web.http.redirections.entrypoint.to=websecure
- --entrypoints.web.http.redirections.entrypoint.scheme=websecure
# - --api.dashboard=true
- --certificatesresolvers.lets-encrypt.acme.email=admin@example.com
- --certificatesresolvers.lets-encrypt.acme.storage=acme.json
- --certificatesresolvers.lets-encrypt.acme.tlschallenge=true
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./letsencrypt:/letsencrypt
geoserver:
image: oscarfonts/geoserver:latest
restart: unless-stopped
networks:
- web
labels:
- traefik.http.middlewares.add-geoserver-prefix.addprefix.prefix=/geoserver
- traefik.port=8080
- traefik.http.routers.geoserver.rule=Host(`example.com`)
- traefik.http.routers.geoserver.entrypoints=websecure
- traefik.http.routers.geoserver.tls=true
- traefik.http.routers.geoserver.tls.certresolver=lets-encrypt
- traefik.http.routers.geoserver.middlewares=add-geoserver-prefix@docker
networks:
web: