无法通过Traefik以URL方式暴露Portainer服务问题求助
问题描述
在Docker Swarm模式的虚拟机上部署Portainer后,可通过IP+端口正常访问。后续通过Portainer UI部署Traefik及其他应用,其他应用均能通过Traefik配置的通配符域名正常访问,但为Portainer配置Traefik路由后出现以下问题:
- 访问
https://portainer.mydomain.com时,域名可解析,但页面空白并提示Gateway Timeout - 使用HTTP访问(忽略证书警告)页面可正常加载
- 通过IP+9443端口仍能正常访问Portainer
- Traefik UI中可看到Portainer服务条目,路由无报错信息
现有配置
Portainer服务配置(修改后)
labels: # Frontend - "traefik.enable=true" - "traefik.http.routers.frontend.rule=Host(`portainer.mydomain.com`)" - "traefik.http.routers.frontend.entrypoints=websecure" - "traefik.http.services.frontend.loadbalancer.server.port=9000" - "traefik.http.routers.frontend.service=frontend" # Edge - "traefik.http.routers.edge.rule=Host(`edge.mydomain.com`)" - "traefik.http.routers.edge.entrypoints=websecure" - "traefik.http.services.edge.loadbalancer.server.port=8000" - "traefik.http.routers.edge.service=edge" ports: - "9000:9000" - "8000:8000" - "9443:9443" networks: public: external: true agent_network: external: true
Traefik服务配置
version: '3.2' services: traefik: image: traefik:latest environment: ACME_DNS_API_BASE: https://auth.acme-dns.io ACME_DNS_STORAGE_PATH: /acme-dns.json command: - --entrypoints.web.http.redirections.entryPoint.to=websecure - --entrypoints.web.http.redirections.entryPoint.scheme=https - --entrypoints.web.http.redirections.entrypoint.permanent=true - --entrypoints.web.address=:80 - --entrypoints.websecure.address=:443 - --entrypoints.websecure.http.tls.certResolver=leresolver - --entrypoints.websecure.http.tls.domains[0].main=mydomain.com - --entrypoints.websecure.http.tls.domains[0].sans=*mydomain.com - --providers.docker=true - --providers.swarm.endpoint=unix:///var/run/docker.sock - --providers.docker.exposedbydefault=false - --providers.docker.network=public - --api=true - --log.level=DEBUG - --certificatesResolvers.leresolver.acme.email=me@mydomain.com - --certificatesResolvers.leresolver.acme.storage=/acme.json - --certificatesResolvers.leresolver.acme.keyType=EC384 - --certificatesResolvers.leresolver.acme.dnsChallenge=true - --certificatesResolvers.leresolver.acme.dnsChallenge.provider=acme-dns - --certificatesResolvers.leresolver.acme.dnsChallenge.resolvers=1.1.1.1:53,8.8.8.8:53 ports: - "80:80" - "443:443" networks: - public volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - /obtools-drive/traefik_data/acme.json:/acme.json - /obtools-drive/traefik_data/acme-dns.json:/acme-dns.json deploy: mode: replicated replicas: 1 placement: constraints: [ node.role == manager ] labels: - "traefik.enable=true" #dashboard - "traefik.http.routers.dashboard.rule=Host(`traefik.mydomain.com`)" - "traefik.http.routers.dashboard.entrypoints=websecure" - "traefik.http.routers.dashboard.service=dashboard@internal" - "traefik.http.routers.dashboard.middlewares=traefik-auth" #api - "traefik.http.routers.api.rule=Host(`traefik.mydomain.com`) && PathPrefix(`/api`)" - "traefik.http.routers.api.entrypoints=websecure" - "traefik.http.routers.api.service=api@internal" - "traefik.http.routers.api.middlewares=traefik-auth" #general - "traefik.http.services.traefik.loadbalancer.server.port=80" - "traefik.http.middlewares.traefik-auth.basicauth.users=admin:$$2y$$05$$q0t44et4tg4ete4t4t4tUufaziferwerw" networks: public: external: true
解决方案
核心问题定位
- 协议不匹配:Portainer默认的HTTPS端口是9443,而当前Traefik配置中指向了Portainer的HTTP端口9000。当Traefik通过HTTPS(websecure入口)转发请求到Portainer的HTTP端口时,协议不兼容导致网关超时;而HTTP访问时,Traefik的web入口会直接转发到9000端口,因此能正常加载。
- 未指定后端协议:Traefik默认会用HTTP协议转发请求到后端,需要明确告知Portainer后端使用HTTPS协议。
具体修正步骤
1. 更新Portainer的Traefik标签
修改标签,将后端端口指向9443,并添加协议声明:
labels: # Frontend (HTTPS) - "traefik.enable=true" - "traefik.http.routers.frontend.rule=Host(`portainer.mydomain.com`)" - "traefik.http.routers.frontend.entrypoints=websecure" - "traefik.http.services.frontend.loadbalancer.server.port=9443" - "traefik.http.services.frontend.loadbalancer.server.scheme=https" # 关键:指定后端为HTTPS协议 - "traefik.http.routers.frontend.service=frontend" # Edge - "traefik.http.routers.edge.rule=Host(`edge.mydomain.com`)" - "traefik.http.routers.edge.entrypoints=websecure" - "traefik.http.services.edge.loadbalancer.server.port=8000" - "traefik.http.routers.edge.service=edge"
2. 移除不必要的端口映射(可选)
既然通过Traefik暴露Portainer服务,无需再将Portainer的端口直接映射到宿主机,可删除以下配置:
# 移除这些端口映射,避免端口冲突 # ports: # - "9000:9000" # - "8000:8000" # - "9443:9443"
3. 验证网络连通性
确保Traefik和Portainer所在的public网络是可附加的:
docker network inspect public
如果Attachable字段为false,重新创建网络:
docker network rm public docker network create --driver overlay --attachable public
4. 重启Portainer服务
更新配置后,强制重启Portainer服务:
docker service update portainer_portainer --force
验证
- 访问
https://portainer.mydomain.com,确认页面正常加载 - 查看Traefik UI的路由状态,确认无报错
- 检查Traefik日志排查潜在问题:
docker service logs traefik_traefik
内容的提问来源于stack exchange,提问作者Deirdre Rodgers
相关产品推荐
相关产品推荐

