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

求助:使用Traefik配置多Docker容器在自定义域名80端口运行失败

问题描述

我尝试用Traefik和Docker Desktop配置多个容器,让它们通过同一自定义域名dev.mydomain.com的80端口访问,具体需求:

  • 容器content对应访问地址:http://dev.mydomain.com/docs/contents/swagger
  • 容器basket对应访问地址:http://dev.mydomain.com/docs/baskets/swagger

已修改本地hosts文件,将dev.mydomain.com指向127.0.0.0(注:此处为错误配置,正确回环地址应为127.0.0.1)。

当前Traefik运行脚本:

docker run -d --name traefik \
  --network dev-mobile \
  --publish 80:8080 --publish 8099:8099 \
  --volume /var/run/docker.sock:/var/run/docker.sock \
  traefik:v2.10 --api.insecure=true --providers.docker=true --entrypoints.dev-mobile.address=:8080 --entrypoints.traefik.address=:8099

Basket容器的Dockerfile(其他容器配置类似):

FROM mcr.microsoft.com/dotnet/sdk:8.0
ARG VERSION
ENV DD_VERSION=${VERSION}
WORKDIR /app
COPY ./<my files> .
EXPOSE 8080
USER app
ENTRYPOINT ["dotnet", "<my dll entrypoint>"]

构建命令:

docker build -t basket_image -f ./local-docker/Dockerfile.Basket .

运行命令:

docker run -d --name basket \
  --network dev-mobile \
  -e ASPNETCORE_ENVIRONMENT=Local \
  --label "traefik.enable=true" \
  --label "traefik.http.routers.basket.rule=Host(`dev.mydomain.com`)" \
  --label "traefik.http.services.basket.loadbalancer.server.port=80" \
  basket_image

问题现象:直接访问http://dev.mydomain.com/docs/baskets/swagger出现404错误,但如果给容器加端口映射(比如-p 8090:8080),并把Traefik服务端口改成8090,就能通过http://dev.mydomain.com:8090/docs/baskets/swagger正常访问。


错误分析与修正方案

你的配置存在三个核心问题,逐一修正即可解决:

1. Hosts文件地址错误

将dev.mydomain.com指向127.0.0.0是无效的回环地址,必须改成127.0.0.1。修改后刷新DNS缓存:

  • Windows:执行ipconfig /flushdns
  • macOS/Linux:执行sudo killall -HUP mDNSResponder

2. Traefik入口点与容器端口不匹配

  • 你定义了dev-mobile入口点绑定Traefik容器内部的8080端口,但未指定路由器使用该入口点,Traefik默认会尝试使用未定义的web入口点,导致路由失效。
  • .NET容器默认监听8080端口(Dockerfile也声明了EXPOSE 8080),但你在Traefik标签中写了server.port=80,完全不符合容器实际监听端口。

3. 路由规则缺少路径区分

两个容器的路由规则都是Host(dev.mydomain.com),Traefik无法判断请求该转发给哪个容器,必须添加路径前缀匹配规则。同时因为外部访问路径带前缀/docs/baskets,而容器内Swagger路径是/swagger,需要用中间件剥离前缀后再转发。

修正后的完整配置

1. 修正Traefik启动命令

指定路由器默认使用dev-mobile入口点,关闭默认暴露容器,避免干扰:

docker run -d --name traefik \
  --network dev-mobile \
  --publish 80:8080 --publish 8099:8099 \
  --volume /var/run/docker.sock:/var/run/docker.sock \
  traefik:v2.10 \
  --api.insecure=true \
  --providers.docker=true \
  --providers.docker.exposedbydefault=false \
  --entrypoints.dev-mobile.address=:8080 \
  --entrypoints.traefik.address=:8099 \
  --api.dashboard=true

2. 修正Basket容器运行命令

添加路径匹配、入口点绑定、前缀剥离中间件:

docker run -d --name basket \
  --network dev-mobile \
  -e ASPNETCORE_ENVIRONMENT=Local \
  --label "traefik.enable=true" \
  --label "traefik.http.routers.basket.entrypoints=dev-mobile" \
  --label "traefik.http.routers.basket.rule=Host(`dev.mydomain.com`) && PathPrefix(`/docs/baskets`)" \
  --label "traefik.http.services.basket.loadbalancer.server.port=8080" \
  --label "traefik.http.routers.basket.middlewares=basket-stripprefix" \
  --label "traefik.http.middlewares.basket-stripprefix.stripprefix.prefixes=/docs/baskets" \
  basket_image

3. 修正Content容器运行命令

同理配置对应路径规则:

docker run -d --name content \
  --network dev-mobile \
  -e ASPNETCORE_ENVIRONMENT=Local \
  --label "traefik.enable=true" \
  --label "traefik.http.routers.content.entrypoints=dev-mobile" \
  --label "traefik.http.routers.content.rule=Host(`dev.mydomain.com`) && PathPrefix(`/docs/contents`)" \
  --label "traefik.http.services.content.loadbalancer.server.port=8080" \
  --label "traefik.http.routers.content.middlewares=content-stripprefix" \
  --label "traefik.http.middlewares.content-stripprefix.stripprefix.prefixes=/docs/contents" \
  content_image

关键说明

  • 前缀剥离中间件:外部访问路径/docs/baskets/swagger会被剥离/docs/baskets,转发给容器的/swagger路径,匹配容器内的Swagger端点。
  • 端口正确性:严格匹配.NET容器实际监听的8080端口,不能随意填写其他端口。
  • 入口点绑定:明确指定路由器使用dev-mobile入口点,确保Traefik能正确接收并转发宿主机80端口的请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 22:05:54