能否通过Traefik 2实现容器多端口转发并避免路由冲突?
问题描述
我在容器的docker-compose.yml里配置了Traefik 2规则,实现通过airt.localhost访问容器内监听88端口的Nginx服务,配置如下:
labels: # traefik v2 - "traefik.http.routers.airt.rule=HostRegexp(`airt.localhost`, `{subdomain:[a-z]+}.airt.localhost`)" - "traefik.http.routers.airt.service=airt" #assign to a specific service in order to have multiple services on the same host - "traefik.http.services.airt.loadbalancer.server.port=88" - "traefik.docker.network=proxy"
现在想同时转发容器内Vite服务的默认5173端口,让airt.localhost:5173的请求能转发到Vite。我尝试了以下配置但无法正常工作:
labels: # traefik v2 - "traefik.http.routers.airt.rule=HostRegexp(`airt.localhost`, `{subdomain:[a-z]+}.airt.localhost`)" - "traefik.http.routers.airt.service=airt" #assign to a specific service in order to have multiple services on the same host - "traefik.http.services.airt.loadbalancer.server.port=88" - "traefik.tcp.routers.airt-vite.rule=HostSNI(`*`)" # the wildcard is required for non-tls, this is the only supported rule - "traefik.tcp.routers.airt.service=airt-vite" - "traefik.tcp.services.airt-vite.loadbalancer.server.port=5173" - "traefik.docker.network=proxy"
我认为这条TCP规则traefik.tcp.routers.airt-vite.rule=HostSNI()会匹配所有请求,导致原HTTP规则失效。尝试把规则改成HostSNI(:5173),但这不是有效规则。请问这种配置是否可行?
更新:我已经找到临时解决办法,在vite.config.js中添加server.hmr.host指令(配合server.host指令),可以设置Vite生成链接的正确主机名,同时保持监听所有端点IP。不过原使用场景可能对他人仍有帮助。
解决方案
这种配置是可行的,只需修正TCP路由器的配置逻辑,避免和HTTP规则冲突:
1. 修正docker-compose.yml中的容器标签配置
需要给TCP路由器指定专属的Traefik入口端口,同时修正配置中的笔误(路由器和服务的名称要对应):
labels: # traefik v2 # Nginx HTTP服务配置 - "traefik.http.routers.airt.rule=HostRegexp(`airt.localhost`, `{subdomain:[a-z]+}.airt.localhost`)" - "traefik.http.routers.airt.service=airt" - "traefik.http.services.airt.loadbalancer.server.port=88" # Vite TCP服务配置 - "traefik.tcp.routers.airt-vite.entrypoints=vite" # 绑定专属入口点 - "traefik.tcp.routers.airt-vite.rule=HostSNI(`*`)" # 非TLS场景仅支持该规则 - "traefik.tcp.routers.airt-vite.service=airt-vite" # 修正路由器与服务的关联 - "traefik.tcp.services.airt-vite.loadbalancer.server.port=5173" - "traefik.docker.network=proxy"
2. 配置Traefik静态入口点
在Traefik的静态配置文件(如traefik.yml)或启动命令中,新增一个监听5173端口的入口点vite:
# traefik.yml示例 entryPoints: web: address: ":80" # 原HTTP服务入口 vite: address: ":5173" # Vite服务专属入口
配置逻辑说明
- Traefik的TCP规则本身无法直接筛选端口,但通过绑定专属入口点,可以让
vite入口点只处理5173端口的请求,不会干扰80端口的HTTP规则。 - 之前的配置失效有两个原因:一是TCP路由器未指定入口点,会抢占所有端口的流量;二是笔误导致路由器和服务不匹配。
补充你的临时解决办法示例
修改vite.config.js的方式适合开发环境,无需额外配置Traefik TCP规则:
// vite.config.js export default { server: { host: '0.0.0.0', hmr: { host: 'airt.localhost' } } }
内容的提问来源于stack exchange,提问作者Valentino
相关产品推荐
相关产品推荐

