You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Traefik反向代理:HTTPS带端口请求转对应HTTP服务配置求助

问题与解决方案

问题背景

已将www.example.com指向后端公网IP,后端配置NAT转发规则到不同服务。需求是:处理https://www.example.com:<端口>/health请求,将其路由到对应端口的/health路径。

尝试用Traefik RedirectRegex中间件实现失败,容器构建正常但SSL验证不通过——http://www.example.com:7001/health可正常访问,https://www.example.com:7001/health无法访问。因服务端口动态变化且数量多,不想为每个端口单独建容器(此前方案管理成本高,不利于SSL问题排查),需通用容器处理所有这类请求。

现有配置

.env 文件

REGEX_PATTERN=^(https://[^/]+):([^/]+)/?(.*)$
REGEX_REPLACEMENT=$${1}/$${3}:$${2}

docker-compose.yml 文件

services:
  whoami:
    image: "traefik/whoami"
    container_name: "simple-service"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami-rule1.rule=Host(`www.example.com`)"
      - "traefik.http.routers.whoami-rule1.entrypoints=websecure"
      - "traefik.http.routers.whoami-rule1.tls.certresolver=myresolver"
      - "traefik.http.routers.whoami-rule1.middlewares=whoami-rule1-port-redirect"
      - "traefik.http.middlewares.whoami-rule1-port-redirect.redirectregex.regex=${REGEX_PATTERN}"
      - "traefik.http.middlewares.whoami-rule1-port-redirect.redirectregex.replacement=${REGEX_REPLACEMENT}"
      - "traefik.http.middlewares.whoami-rule1-port-redirect.redirectregex.permanent=true"

解决方案

1. 修复SSL验证失败问题

当前Traefik仅监听websecure入口点(默认443端口),https://www.example.com:7001这类自定义端口的HTTPS请求未被Traefik处理,直接到达后端但后端未配置对应SSL证书,导致验证失败。

解决步骤:

  • 在Traefik静态配置中添加覆盖服务端口范围的入口点,比如在Traefik的traefik.yml或docker-compose的Traefik服务配置中:
    entryPoints:
      websecure:
        address: ":443"
      service-ports:
        address: ":7000-8000" # 替换为你的实际服务端口范围
    
  • 在路由规则中将entrypoints改为websecure,service-ports,让Traefik监听这些端口并提供TLS证书:
    - "traefik.http.routers.whoami-rule1.entrypoints=websecure,service-ports"
    
  • 确保Traefik容器映射了这些端口到主机:
    在Traefik服务的ports字段添加:
    - "7000-8000:7000-8000"
    

2. 修正重定向/路由逻辑

原正则规则逻辑错误,会将https://www.example.com:7001/health转换为https://www.example.com/health:7001,这不符合需求。根据你的场景,反向代理比重定向更合适(无需修改URL,直接转发请求到后端对应端口):

调整为反向代理配置

修改whoami服务的Traefik标签,去掉重定向中间件,添加服务转发配置:

labels:
  - "traefik.enable=true"
  - "traefik.http.routers.health-proxy.rule=Host(`www.example.com`) && Path(`/health`)"
  - "traefik.http.routers.health-proxy.entrypoints=websecure,service-ports"
  - "traefik.http.routers.health-proxy.tls.certresolver=myresolver"
  # 转发到主机对应端口的/health(依赖后端NAT规则)
  - "traefik.http.services.health-proxy.loadbalancer.server.url=http://host.docker.internal:{{range $p, $conf := .ContainerConfig.ExposedPorts}}{{$p | splitSlice ":" | first}}{{end}}/health"

如果你的服务端口是动态的,也可以通过标签指定端口,或者利用Traefik的动态配置能力自动发现端口。

3. 简化通用配置建议

如果需要一个完全通用的容器处理所有/health请求,可以创建一个专门的代理容器,配置Traefik路由匹配所有带端口的www.example.com的/health路径,然后转发到主机对应端口:

services:
  health-proxy:
    image: nginx:alpine # 或用traefik/whoami测试
    container_name: health-proxy
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.health-proxy.rule=Host(`www.example.com`) && Path(`/health`)"
      - "traefik.http.routers.health-proxy.entrypoints=websecure,service-ports"
      - "traefik.http.routers.health-proxy.tls.certresolver=myresolver"
      # 动态获取请求端口并转发到主机对应端口
      - "traefik.http.middlewares.health-proxy-add-port.addprefix.prefix=http://host.docker.internal:{{index .Request.Port}}/"
      - "traefik.http.routers.health-proxy.middlewares=health-proxy-add-port"
      - "traefik.http.services.health-proxy.loadbalancer.server.port=80"

(注:{{index .Request.Port}}是Traefik的模板变量,需确保Traefik启用模板支持)

内容的提问来源于stack exchange,提问作者Saksham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 00:28:12