如何用单个Traefik服务实现不同EntryPoint与Host规则组合配置
问题描述
现有Docker Compose配置通过my_api和abcxyz两个独立服务,实现了容器分别通过example.com:8080和api.example.com:443访问的需求。现希望合并为单个服务,同时满足以下限制:
- 仅允许通过
example.com:8080访问容器,禁止example.com:443(该端口将用于部署WordPress) - 仅允许通过
api.example.com:443访问容器,禁止api.example.com:8080
此前尝试的配置会导致example.com:443也能访问容器,不符合需求:
labels: - "traefik.http.routers.my_api.entrypoints=spiderman,web-secure" - "traefik.http.routers.my_api.rule=Host(`example.com`,`api.example.com`)" - "traefik.http.routers.my_api.tls=true"
原完整Docker Compose配置:
version: "3" services: traefik: image: traefik command: - --api.dashboard=false - --api.insecure=false - --providers.docker - --entrypoints.web.address=:80 - --entrypoints.web.http.redirections.entrypoint.to=web-secure - --entrypoints.web.http.redirections.entrypoint.scheme=https - --entrypoints.web.http.redirections.entrypoint.permanent=true - --entrypoints.web-secure.address=:443 - --entrypoints.spiderman.address=:8080 - --providers.file.directory=/configuration/ - --providers.file.watch=true ports: - 80:80 - 443:443 - 8080:8080 volumes: - ./certificates.yml:/configuration/certificates.yml:ro - /etc/letsencrypt:/letsencrypt:ro - /var/run/docker.sock:/var/run/docker.sock my_api: image: traefik/whoami deploy: replicas: 5 labels: - "traefik.http.routers.my_api.entrypoints=spiderman" - "traefik.http.routers.my_api.rule=Host(`example.com`)" - "traefik.http.routers.my_api.tls=true" abcxyz: image: traefik/whoami deploy: replicas: 5 labels: - "traefik.http.routers.abcxyz.entrypoints=web-secure" - "traefik.http.routers.abcxyz.rule=Host(`api.example.com`)" - "traefik.http.routers.abcxyz.tls=true"
解决方案
可以通过给单个服务配置两个独立的Traefik路由器实现需求,每个路由器绑定对应的Host和Entrypoint,确保访问路径完全符合限制。修改后的Docker Compose如下:
version: "3" services: traefik: image: traefik command: - --api.dashboard=false - --api.insecure=false - --providers.docker - --entrypoints.web.address=:80 - --entrypoints.web.http.redirections.entrypoint.to=web-secure - --entrypoints.web.http.redirections.entrypoint.scheme=https - --entrypoints.web.http.redirections.entrypoint.permanent=true - --entrypoints.web-secure.address=:443 - --entrypoints.spiderman.address=:8080 - --providers.file.directory=/configuration/ - --providers.file.watch=true ports: - 80:80 - 443:443 - 8080:8080 volumes: - ./certificates.yml:/configuration/certificates.yml:ro - /etc/letsencrypt:/letsencrypt:ro - /var/run/docker.sock:/var/run/docker.sock my_api: image: traefik/whoami deploy: replicas: 5 labels: # 第一个路由器:绑定example.com到8080端口(spiderman入口) - "traefik.http.routers.my_api_web.entrypoints=spiderman" - "traefik.http.routers.my_api_web.rule=Host(`example.com`)" - "traefik.http.routers.my_api_web.tls=true" # 第二个路由器:绑定api.example.com到443端口(web-secure入口) - "traefik.http.routers.my_api_api.entrypoints=web-secure" - "traefik.http.routers.my_api_api.rule=Host(`api.example.com`)" - "traefik.http.routers.my_api_api.tls=true" # 统一服务名称,让两个路由器指向同一个服务实例 - "traefik.http.services.my_api.loadbalancer.server.port=80"
关键说明
- 为单个服务创建两个不同名称的路由器(
my_api_web和my_api_api),分别对应不同的Host和Entrypoint,避免交叉访问 - 通过
traefik.http.services.my_api.loadbalancer.server.port指定服务的内部端口,确保两个路由器都能正确路由到服务 - 该配置严格限制了访问路径:
- 只有
example.com:8080能访问容器 - 只有
api.example.com:443能访问容器 example.com:443和api.example.com:8080均无法访问容器,满足WordPress端口预留需求
- 只有
内容的提问来源于stack exchange,提问作者user18511546
相关产品推荐
相关产品推荐

