尝试在 Traefik 上配置 HTTPS 时获取 502 Bad Gateway
Getting 502 Bad Gateway when trying to configure HTTPS on Traefik
我有一个适用于 HTTP 的基本 Traefik 2 设置 ...
现在我正在尝试让 HTTPS 工作,并使用 TLS 和重定向对仪表板进行基本身份验证...
docker_compose.yml:
version: '3.8'
networks:
myweb:
external: true
services:
proxy:
image: traefik:v2.3.0-rc4-windowsservercore-1809
container_name: traefik
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
# Mount the certs drive
- ./traefik-ssl-certs/:c:/certs/
# Mount the config folder
- ./traefik-config/:c:/config/
# Mount the host docker engine pipe ("docker volume ls")
- source: '\.\pipe\docker_engine'
target: '\.\pipe\docker_engine'
type: npipe
command:
- "--api.insecure=true"
# Register the traefik config directory as per: https://docs.traefik.io/providers/file/#directory
- --providers.file.directory=c:/config/
- --providers.file.watch=true
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
# Redirect http to https
- --entrypoints.web.http.redirections.entryPoint.to=websecure
- --entrypoints.web.http.redirections.entryPoint.scheme=https
- --entrypoints.web.http.redirections.entrypoint.permanent=true
# Configure Docker provider
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.endpoint=npipe:////./pipe/docker_engine"
- "--providers.docker.network=myweb"
- "--providers.docker.watch=true"
networks:
- myweb
labels:
- traefik.http.routers.api.service=api@internal
- traefik.enable=true
- traefik.docker.network=myweb
remoteling:
image: remoteling:latest
container_name: remoteling
networks:
- myweb
labels:
- traefik.enable=true
- traefik.docker.network=myweb
- traefik.http.middlewares.http2https.redirectscheme.scheme=https
- traefik.http.routers.remoteling-http.middlewares=http2https
- traefik.http.routers.remoteling-http.rule=Host(`example.com`) || Host(`example.example.com`)
- traefik.http.routers.remoteling-http.entrypoints=web
- traefik.http.services.remoteling.loadbalancer.server.port=443
- traefik.http.routers.remoteling-https.rule=Host(`example.com`) || Host(`example.example.com`)
- traefik.http.routers.remoteling-https.entrypoints=websecure
- traefik.http.routers.remoteling-https.tls=true
depends_on:
- proxy
来自 powershell 我是 运行:
docker network create -d nat myweb
docker-compose -p myweb up
在我的工作目录中,我有以下文件结构:
- ./docker-compose.yml
- ./traefik-config/traefik.yml
- ./traefik-ssl-certs/example.com.crt
- ./traefik-ssl-certs/example.com.key
- ./traefik-ssl-certs/example.例子.com.key
- ./traefik-ssl-certs/example.例子.com.key
traefik.yml 文件如下所示:
tls:
certificates:
- certFile: c:/certs/example.example.com.crt
keyFile: c:/certs/example.example.com.key
- certFile: c:/certs/example.com.crt
keyFile: c:/certs/example.com.key
traefik 仪表板显示我的服务定义为负载均衡器,这很好(除了负载均衡器之外还有其他类型的服务吗?我不确定除了通过负载均衡器之外还有什么其他方式定义端口)。单击该服务会为我提供本地网络 IP - 当我访问该 IP 时,我的网站加载正常(尽管有 SSL 证书不匹配警告 - 预期)。
然而,当我尝试访问 https://example.com or https://example.example.com - 时,我收到了 502 Bad Gateway。知道为什么我会得到这个吗?
浏览器显示 SSL 证书有效,没有警告,所以我认为我的证书配置没问题。
如果我访问 http://example.com it forwards me to https://example.com
,http 到 https 重定向似乎有效
我的路由配置有什么问题导致这些错误的网关?
我的问题解决了!有几个问题:
- 我在我的 Docker 文件中配置了一个 TLS 证书,从我 运行 将图像作为我的服务器上的单个服务开始。所以我的图像已经绑定了 TLS 证书的端口 443。我认为当 Traefik 路由器尝试为服务配置 TLS 时,这会导致问题。所以我不得不重建我的形象,删除 TLS。我也删除了需要 HTTPS 属性的代码,现在由 traefik 负责。
Image只需要暴露1个端口:我现在的理解是我的web应用应该只 运行通过端口80(例如,甚至不需要在图像的防火墙中暴露端口 443)并且 Traefik 路由器通过端口 80 配置和处理 TLS/443 等。
- 我实际上并没有正确定义我的 HTTP 和 HTTPS 服务。我在下面分享了我的 docker-compose.yml 文件——注意 traefik 和我的其他服务,我将标签分成几个部分:定义服务、HTTP 路由、HTTPS 路由、重定向中间件和基本身份验证traefik 仪表板。我找不到任何好的文档或教程来真正分解 traefik 2.0 的必要方面并将它们清楚地分类。
服务定义标签/负载均衡器端口应指向托管图像服务的任何端口,例如在大多数情况下端口 80,或者在 traefik 服务 8080 的情况下。但关键是它不需要 also 指向 443 以获得 https。
总而言之,我的(冗长的)学习笔记毕竟是,你需要:
- 再次将服务定义为标签:没有服务定义标签对我不起作用。我必须添加一个服务标签,指向定义图像的服务名称。
- 为 http 和 https 定义路由器:在 traefik.http.routers.YOUR_ROUTER_NAME 之后放置的任何文本都会成为您的路由器。我不清楚我需要用于 http 和 https 的单独路由器。您必须为每项服务(例如 traefik、whoami、remoteling 等)执行此操作
- 定义路由器的入口点:据我所知,您在 traefik 命令中入口点后面的名称定义了一个可用于其他服务的新入口点。因此,在 traefik 服务定义中,您将拥有 --entrypoints.WEBNAME.address=:80 和 --entrypoints.WEBSECURENAME.address=:443(用您自己的名字替换这些大写字母,以便在 docker-compose.yml 中使用文件。
- 定义要捕获的路由器域名:就像为每个 http 和 https 定义路由器一样,您必须为这两个路由器定义要捕获的域,即使只是相同 domain/path.
- 为 https 路由器添加 tls:对于 https 路由器,您需要 tls.true 标签。
- traefik 和您的每个服务的单独中间件重定向定义:我读过您可以声明一个全局的,但是 AFAIK 每个服务必须 opt-in将中间件分配给 http 路由器。
- 在 Docker 上为 Windows 提供您自己的 SSL 证书:关于 运行ning Docker 的信息很少对于 Windows 使用您自己的 SSL 证书。我的 'traefik' 工作目录中有一个批处理脚本,其中包含一个包含 SSL 证书(crt 和密钥文件)的子文件夹。我将此作为第一卷安装,
- ./traefik-ssl-certs/:c:/certs/
。然后,在我的工作目录中,我有另一个名为 traefik-config
的文件夹,其中包含我的 traefik.yml 文件(上述问题中的详细信息)。在 linux 中,每个人似乎都直接挂载配置文件,但在 Windows 中挂载文件不起作用,所以我不得不作为文件夹挂载,然后我使用了命令 providers.file.directory=c:/config/
,它告诉 traefik 在那里寻找配置文件。配置文件为 traefik 加载提供了 SSL 证书的位置。如果您为路由器启用 TLS,Traefik 将自动使用与您在该路由器上指定的域匹配的任何证书。
- Basic Auth: 必须将中间件定义为一个标签,然后将该中间件分配给您的 https 路由器。我想如果您不使用 HTTPS 重定向,那么您可以将它分配给您的 http 路由器,但它显然不安全。
docker-compose.yml:
version: '3.8'
networks:
myweb:
external: true
services:
proxy:
image: traefik:v2.3.0-rc4-windowsservercore-1809
container_name: traefik
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
# Mount the certs drive
- ./traefik-ssl-certs/:c:/certs/
# Mount the config folder
- ./traefik-config/:c:/config/
# Mount the host docker engine pipe ("docker volume ls")
- source: '\.\pipe\docker_engine'
target: '\.\pipe\docker_engine'
type: npipe
command:
- --api=true
- --api.dashboard=true
- --api.insecure=false
# Register the traefik config directory as per: https://docs.traefik.io/providers/file/#directory
- --providers.file.directory=c:/config/
- --providers.file.watch=true
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
# Configure Docker provider
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --providers.docker.endpoint=npipe:////./pipe/docker_engine
- --providers.docker.network=myweb
- --providers.docker.watch=true
networks:
- myweb
labels:
- traefik.enable=true
- traefik.docker.network=myweb
# Define the service
- traefik.http.services.proxy.loadbalancer.server.port=8080
# Routing for dashboard HTTP
- traefik.http.routers.dash-http.service=api@internal
- traefik.http.routers.dash-http.rule=Host(`example.com`)
- traefik.http.routers.dash-http.entrypoints=web
# Routing for dashboard HTTPS
- traefik.http.routers.dash-https.service=api@internal
- traefik.http.routers.dash-https.rule=Host(`example.com`)
- traefik.http.routers.dash-https.entrypoints=websecure
- traefik.http.routers.dash-https.tls=true
# Http-to-Https redirect Middleware
- traefik.http.middlewares.dash-http2https.redirectscheme.scheme=https
- traefik.http.middlewares.dash-http2https.redirectscheme.permanent=true
- traefik.http.routers.dash-http.middlewares=dash-http2https
# BasicAuth for dashboard
# Windows doesn't have htpasswd command so I generated one here: https://hostingcanada.org/htpasswd-generator/
# As per Traefik documentation, escaped single $ char with $$ for the yml parser
# user/pass = admin/testpassword
- traefik.http.middlewares.api-auth.basicauth.users=admin:$y$$$mfWQ11K16V6gVK.8Y6q1Eeh765NZscmjCrjJlAtaWubEsjU8HLYOO
- traefik.http.routers.dash-https.middlewares=api-auth
remoteling:
image: remoteling:latest
container_name: remoteling
networks:
- myweb
labels:
- traefik.enable=true
- traefik.docker.network=myweb
# Define the service
- traefik.http.services.remoteling.loadbalancer.server.port=80
# Routing for remoteling HTTP
- traefik.http.routers.remoteling-http.service=remoteling
- traefik.http.routers.remoteling-http.entrypoints=web
- traefik.http.routers.remoteling-http.rule=Host(`services.example.com`)
# Routing for remoteling HTTPS
- traefik.http.routers.remoteling-https.service=remoteling
- traefik.http.routers.remoteling-https.entrypoints=websecure
- traefik.http.routers.remoteling-https.rule=Host(`services.example.com`)
- traefik.http.routers.remoteling-https.tls=true
# Http-to-Https redirect Middleware
- traefik.http.middlewares.remoteling-http2https.redirectscheme.scheme=https
- traefik.http.middlewares.remoteling-http2https.redirectscheme.permanent=true
- traefik.http.routers.remoteling-http.middlewares=remoteling-http2https
depends_on:
- proxy
希望其他人觉得有用。
我有一个适用于 HTTP 的基本 Traefik 2 设置
现在我正在尝试让 HTTPS 工作,并使用 TLS 和重定向对仪表板进行基本身份验证...
docker_compose.yml:
version: '3.8'
networks:
myweb:
external: true
services:
proxy:
image: traefik:v2.3.0-rc4-windowsservercore-1809
container_name: traefik
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
# Mount the certs drive
- ./traefik-ssl-certs/:c:/certs/
# Mount the config folder
- ./traefik-config/:c:/config/
# Mount the host docker engine pipe ("docker volume ls")
- source: '\.\pipe\docker_engine'
target: '\.\pipe\docker_engine'
type: npipe
command:
- "--api.insecure=true"
# Register the traefik config directory as per: https://docs.traefik.io/providers/file/#directory
- --providers.file.directory=c:/config/
- --providers.file.watch=true
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
# Redirect http to https
- --entrypoints.web.http.redirections.entryPoint.to=websecure
- --entrypoints.web.http.redirections.entryPoint.scheme=https
- --entrypoints.web.http.redirections.entrypoint.permanent=true
# Configure Docker provider
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.endpoint=npipe:////./pipe/docker_engine"
- "--providers.docker.network=myweb"
- "--providers.docker.watch=true"
networks:
- myweb
labels:
- traefik.http.routers.api.service=api@internal
- traefik.enable=true
- traefik.docker.network=myweb
remoteling:
image: remoteling:latest
container_name: remoteling
networks:
- myweb
labels:
- traefik.enable=true
- traefik.docker.network=myweb
- traefik.http.middlewares.http2https.redirectscheme.scheme=https
- traefik.http.routers.remoteling-http.middlewares=http2https
- traefik.http.routers.remoteling-http.rule=Host(`example.com`) || Host(`example.example.com`)
- traefik.http.routers.remoteling-http.entrypoints=web
- traefik.http.services.remoteling.loadbalancer.server.port=443
- traefik.http.routers.remoteling-https.rule=Host(`example.com`) || Host(`example.example.com`)
- traefik.http.routers.remoteling-https.entrypoints=websecure
- traefik.http.routers.remoteling-https.tls=true
depends_on:
- proxy
来自 powershell 我是 运行:
docker network create -d nat myweb
docker-compose -p myweb up
在我的工作目录中,我有以下文件结构:
- ./docker-compose.yml
- ./traefik-config/traefik.yml
- ./traefik-ssl-certs/example.com.crt
- ./traefik-ssl-certs/example.com.key
- ./traefik-ssl-certs/example.例子.com.key
- ./traefik-ssl-certs/example.例子.com.key
traefik.yml 文件如下所示:
tls:
certificates:
- certFile: c:/certs/example.example.com.crt
keyFile: c:/certs/example.example.com.key
- certFile: c:/certs/example.com.crt
keyFile: c:/certs/example.com.key
traefik 仪表板显示我的服务定义为负载均衡器,这很好(除了负载均衡器之外还有其他类型的服务吗?我不确定除了通过负载均衡器之外还有什么其他方式定义端口)。单击该服务会为我提供本地网络 IP - 当我访问该 IP 时,我的网站加载正常(尽管有 SSL 证书不匹配警告 - 预期)。
然而,当我尝试访问 https://example.com or https://example.example.com - 时,我收到了 502 Bad Gateway。知道为什么我会得到这个吗?
浏览器显示 SSL 证书有效,没有警告,所以我认为我的证书配置没问题。
如果我访问 http://example.com it forwards me to https://example.com
,http 到 https 重定向似乎有效我的路由配置有什么问题导致这些错误的网关?
我的问题解决了!有几个问题:
- 我在我的 Docker 文件中配置了一个 TLS 证书,从我 运行 将图像作为我的服务器上的单个服务开始。所以我的图像已经绑定了 TLS 证书的端口 443。我认为当 Traefik 路由器尝试为服务配置 TLS 时,这会导致问题。所以我不得不重建我的形象,删除 TLS。我也删除了需要 HTTPS 属性的代码,现在由 traefik 负责。
Image只需要暴露1个端口:我现在的理解是我的web应用应该只 运行通过端口80(例如,甚至不需要在图像的防火墙中暴露端口 443)并且 Traefik 路由器通过端口 80 配置和处理 TLS/443 等。
- 我实际上并没有正确定义我的 HTTP 和 HTTPS 服务。我在下面分享了我的 docker-compose.yml 文件——注意 traefik 和我的其他服务,我将标签分成几个部分:定义服务、HTTP 路由、HTTPS 路由、重定向中间件和基本身份验证traefik 仪表板。我找不到任何好的文档或教程来真正分解 traefik 2.0 的必要方面并将它们清楚地分类。
服务定义标签/负载均衡器端口应指向托管图像服务的任何端口,例如在大多数情况下端口 80,或者在 traefik 服务 8080 的情况下。但关键是它不需要 also 指向 443 以获得 https。
总而言之,我的(冗长的)学习笔记毕竟是,你需要:
- 再次将服务定义为标签:没有服务定义标签对我不起作用。我必须添加一个服务标签,指向定义图像的服务名称。
- 为 http 和 https 定义路由器:在 traefik.http.routers.YOUR_ROUTER_NAME 之后放置的任何文本都会成为您的路由器。我不清楚我需要用于 http 和 https 的单独路由器。您必须为每项服务(例如 traefik、whoami、remoteling 等)执行此操作
- 定义路由器的入口点:据我所知,您在 traefik 命令中入口点后面的名称定义了一个可用于其他服务的新入口点。因此,在 traefik 服务定义中,您将拥有 --entrypoints.WEBNAME.address=:80 和 --entrypoints.WEBSECURENAME.address=:443(用您自己的名字替换这些大写字母,以便在 docker-compose.yml 中使用文件。
- 定义要捕获的路由器域名:就像为每个 http 和 https 定义路由器一样,您必须为这两个路由器定义要捕获的域,即使只是相同 domain/path.
- 为 https 路由器添加 tls:对于 https 路由器,您需要 tls.true 标签。
- traefik 和您的每个服务的单独中间件重定向定义:我读过您可以声明一个全局的,但是 AFAIK 每个服务必须 opt-in将中间件分配给 http 路由器。
- 在 Docker 上为 Windows 提供您自己的 SSL 证书:关于 运行ning Docker 的信息很少对于 Windows 使用您自己的 SSL 证书。我的 'traefik' 工作目录中有一个批处理脚本,其中包含一个包含 SSL 证书(crt 和密钥文件)的子文件夹。我将此作为第一卷安装,
- ./traefik-ssl-certs/:c:/certs/
。然后,在我的工作目录中,我有另一个名为traefik-config
的文件夹,其中包含我的 traefik.yml 文件(上述问题中的详细信息)。在 linux 中,每个人似乎都直接挂载配置文件,但在 Windows 中挂载文件不起作用,所以我不得不作为文件夹挂载,然后我使用了命令providers.file.directory=c:/config/
,它告诉 traefik 在那里寻找配置文件。配置文件为 traefik 加载提供了 SSL 证书的位置。如果您为路由器启用 TLS,Traefik 将自动使用与您在该路由器上指定的域匹配的任何证书。 - Basic Auth: 必须将中间件定义为一个标签,然后将该中间件分配给您的 https 路由器。我想如果您不使用 HTTPS 重定向,那么您可以将它分配给您的 http 路由器,但它显然不安全。
docker-compose.yml:
version: '3.8'
networks:
myweb:
external: true
services:
proxy:
image: traefik:v2.3.0-rc4-windowsservercore-1809
container_name: traefik
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
# Mount the certs drive
- ./traefik-ssl-certs/:c:/certs/
# Mount the config folder
- ./traefik-config/:c:/config/
# Mount the host docker engine pipe ("docker volume ls")
- source: '\.\pipe\docker_engine'
target: '\.\pipe\docker_engine'
type: npipe
command:
- --api=true
- --api.dashboard=true
- --api.insecure=false
# Register the traefik config directory as per: https://docs.traefik.io/providers/file/#directory
- --providers.file.directory=c:/config/
- --providers.file.watch=true
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
# Configure Docker provider
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --providers.docker.endpoint=npipe:////./pipe/docker_engine
- --providers.docker.network=myweb
- --providers.docker.watch=true
networks:
- myweb
labels:
- traefik.enable=true
- traefik.docker.network=myweb
# Define the service
- traefik.http.services.proxy.loadbalancer.server.port=8080
# Routing for dashboard HTTP
- traefik.http.routers.dash-http.service=api@internal
- traefik.http.routers.dash-http.rule=Host(`example.com`)
- traefik.http.routers.dash-http.entrypoints=web
# Routing for dashboard HTTPS
- traefik.http.routers.dash-https.service=api@internal
- traefik.http.routers.dash-https.rule=Host(`example.com`)
- traefik.http.routers.dash-https.entrypoints=websecure
- traefik.http.routers.dash-https.tls=true
# Http-to-Https redirect Middleware
- traefik.http.middlewares.dash-http2https.redirectscheme.scheme=https
- traefik.http.middlewares.dash-http2https.redirectscheme.permanent=true
- traefik.http.routers.dash-http.middlewares=dash-http2https
# BasicAuth for dashboard
# Windows doesn't have htpasswd command so I generated one here: https://hostingcanada.org/htpasswd-generator/
# As per Traefik documentation, escaped single $ char with $$ for the yml parser
# user/pass = admin/testpassword
- traefik.http.middlewares.api-auth.basicauth.users=admin:$y$$$mfWQ11K16V6gVK.8Y6q1Eeh765NZscmjCrjJlAtaWubEsjU8HLYOO
- traefik.http.routers.dash-https.middlewares=api-auth
remoteling:
image: remoteling:latest
container_name: remoteling
networks:
- myweb
labels:
- traefik.enable=true
- traefik.docker.network=myweb
# Define the service
- traefik.http.services.remoteling.loadbalancer.server.port=80
# Routing for remoteling HTTP
- traefik.http.routers.remoteling-http.service=remoteling
- traefik.http.routers.remoteling-http.entrypoints=web
- traefik.http.routers.remoteling-http.rule=Host(`services.example.com`)
# Routing for remoteling HTTPS
- traefik.http.routers.remoteling-https.service=remoteling
- traefik.http.routers.remoteling-https.entrypoints=websecure
- traefik.http.routers.remoteling-https.rule=Host(`services.example.com`)
- traefik.http.routers.remoteling-https.tls=true
# Http-to-Https redirect Middleware
- traefik.http.middlewares.remoteling-http2https.redirectscheme.scheme=https
- traefik.http.middlewares.remoteling-http2https.redirectscheme.permanent=true
- traefik.http.routers.remoteling-http.middlewares=remoteling-http2https
depends_on:
- proxy
希望其他人觉得有用。