如何使用 Traefik 2.0 和 Docker Compose 标签将 http 重定向到 https?

Xii*_*ryo 43 docker docker-compose traefik

请注意,这是一个 Traefik V2 问题。我在 V1 上有一个解决方案,但 V2 是一个彻底的重整。

以上应该将http://whoami.mysite.com重定向到 http s ://whoami.mysite.com。

  • 在HTTP小号工作很好。
  • http 不会重定向到 https 并引发错误 404。

没有其他文件。一切都在这个 Docker-compose.yml 中,因为它是准备进一步部署的测试。

version: "3.3"

services:

  traefik:
    image: "traefik:v2.0"
    container_name: "traefik"
    command:
      - "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.web-secure.address=:443"
      - "--certificatesresolvers.myhttpchallenge.acme.httpchallenge=true"
      - "--certificatesresolvers.myhttpchallenge.acme.httpchallenge.entrypoint=web-secure"
      #- "--certificatesresolvers.myhttpchallenge.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
      - "--certificatesresolvers.myhttpchallenge.acme.email=me@mail.com"
      - "--certificatesresolvers.myhttpchallenge.acme.storage=/letsencrypt/acme.json"
    labels:
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - "./letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

  whoami:
    image: "containous/whoami"
    container_name: "whoami"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`whoami.mysite.com`)"
      - "traefik.http.routers.whoami.entrypoints=web"
      - "traefik.http.routers.whoami.middlewares=redirect-to-https@docker"
      - "traefik.http.routers.whoami-secured.rule=Host(`whoami.mysite.com`)"
      - "traefik.http.routers.whoami-secured.entrypoints=web-secure"
      - "traefik.http.routers.whoami-secured.tls=true"
      - "traefik.http.routers.whoami-secured.tls.certresolver=myhttpchallenge"
Run Code Online (Sandbox Code Playgroud)

小智 46

我建议在这里查看文档Entrypoint redirect 80 > 443

这对我有用,如果您希望所有流量从端口 80 重定向到 443,这是最好的解决方案。

--entrypoints.web.address=:80
--entrypoints.web.http.redirections.entryPoint.to=websecure
--entrypoints.web.http.redirections.entryPoint.scheme=https
--entrypoints.web.http.redirections.entrypoint.permanent=true
--entrypoints.websecure.address=:443
Run Code Online (Sandbox Code Playgroud)

笔记:

周围有很多例子。只需看看 websecure。

有时它被编写为网络安全的。

希望有帮助;o)

  • 这是否[打破了让我们加密“http”挑战](https://community.traefik.io/t/https-redirection-without-breaking-letsencrypt-http-challenge/11215/3)? (3认同)
  • 只是在这里寻求澄清 - 这会重定向所有服务的所有流量,并消除在服务级别声明的重定向中间件的需要?假设我这样做了,然后我想通过纯 http 访问 5 个服务中的一个,所以这里没有重定向。那么我可以“跳过”单个服务的重定向吗? (2认同)
  • 如果此解决方案对您不起作用,结果是 Traefik 容器本身不会开始给出错误:“命令 traefik 错误:无法从标志解码配置:未找到字段,节点:http”,请尝试将 Traefik 版本更新为最新可用的(对我来说 **v2.0 给出了错误**,但 **对 v2.3** 现在 **一切正常**) (2认同)

小智 18

现在在 Gérald Croës 的教程中有一个可行的解决方案:

https://blog.containo.us/traefik-2-0-docker-101-fc2893944b9d

services:  
  traefik:  
    image: "traefik:v2.0.0"  
    # ...  
    labels:  
      # ...        
      # middleware redirect  
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"  
      # global redirect to https  
      - "traefik.http.routers.redirs.rule=hostregexp(`{host:.+}`)"  
      - "traefik.http.routers.redirs.entrypoints=web"  
      - "traefik.http.routers.redirs.middlewares=redirect-to-https"  
Run Code Online (Sandbox Code Playgroud)


Lar*_*ars 14

您不需要配置 Traefik 服务本身。在 Traefik 上,您只需要 :443(网络安全)和 :80(网络)的入口点

因为 Traefik 只作为入口点,不会做重定向,目标服务上的中间件会做。

现在将您的目标服务配置如下:

version: '2'
services:
  mywebserver:
    image: 'httpd:alpine'
    container_name: mywebserver
    labels:
      - traefik.enable=true
      - traefik.http.middlewares.mywebserver-redirect-web-secure.redirectscheme.scheme=https
      - traefik.http.routers.mywebserver-web.middlewares=mywebserver-redirect-web-secure
      - traefik.http.routers.mywebserver-web.rule=Host(`sub.domain.com`)
      - traefik.http.routers.mywebserver-web.entrypoints=web
      - traefik.http.routers.mywebserver-web-secure.rule=Host(`sub.domain.com`)
      - traefik.http.routers.mywebserver-web-secure.tls.certresolver=mytlschallenge
      - traefik.http.routers.mywebserver-web-secure.tls=true
      - traefik.http.routers.mywebserver-web-secure.entrypoints=web-secure
      # if you have multiple ports exposed on the service, specify port in the web-secure service
      - traefik.http.services.mywebserver-web-secure.loadbalancer.server.port=9000
Run Code Online (Sandbox Code Playgroud)

所以基本上流程是这样的:

请求:http ://sub.domain.com : 80 --> traefik(服务)--> mywebserver-web(路由器,http 规则)--> mywebserver-redirect-web-secure(中间件,重定向到 https)- -> mywebserver-web-secure(路由器,https 规则)--> mywebserver(服务)


Tho*_*eer 8

有两种选择:

您可以通过将以下内容添加到Traefik 容器的静态配置来将所有传入流量重定向到 HTTPS:

command:
- "--entrypoints.websecure.address=:443"
- "--entrypoints.web.address=:80"
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
- "--entrypoints.web.http.redirections.entryPoint.scheme=https"
- "--entrypoints.web.http.redirections.entrypoint.permanent=true"
Run Code Online (Sandbox Code Playgroud)

或者,您可以通过将以下内容添加到应用程序容器的动态配置中,将单个容器的流量重定向到 HTTPS:

labels:
- "traefik.enable=true"
- "traefik.http.middlewares.myapp-redirect.redirectscheme.scheme=https"
- "traefik.http.middlewares.myapp-redirect.redirectscheme.permanent=true"
- "traefik.http.routers.myapp.middlewares=myapp-redirect"
- "traefik.http.routers.myapp.rule=Host(`myapp.localhost`)"
- "traefik.http.routers.myapp.entrypoints=web"
- "traefik.http.routers.myapp-secure.rule=Host(`myapp.localhost`)"
- "traefik.http.routers.myapp-secure.entrypoints=websecure"
- "traefik.http.routers.myapp-secure.tls=true"
- "traefik.http.routers.myapp-secure.tls.certresolver=le"
Run Code Online (Sandbox Code Playgroud)


小智 7

您只需将以下内容添加到 traefik 配置中,而不是应用程序中;

- "--entrypoints.websecure.address=:443"
- "--entrypoints.web.address=:80"
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
- "--entrypoints.web.http.redirections.entryPoint.scheme=https"
- "--entrypoints.web.http.redirections.entrypoint.permanent=true"
Run Code Online (Sandbox Code Playgroud)

这是 traefik 的完整 yaml 配置

version: "3.3"

services:

  traefik:
    image: "traefik:v2.5"
    container_name: "traefik"
    command:
      # - "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.websecure.address=:443"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.web.http.redirections.entryPoint.to=websecure"
      - "--entrypoints.web.http.redirections.entryPoint.scheme=https"
      - "--entrypoints.web.http.redirections.entrypoint.permanent=true"
      - "--certificatesresolvers.myresolver.acme.tlschallenge=true"
      #- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
      - "--certificatesresolvers.myresolver.acme.email=user@domain.com"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"

    ports:
      - "443:443"
      - "80:80"
      - "8080:8080"
    volumes:
      - "./letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
Run Code Online (Sandbox Code Playgroud)

应用示例

  whoami:
    image: "traefik/whoami"
    container_name: "simple-service"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`subdomain.domain.com`)"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.routers.whoami.tls.certresolver=myresolver"
Run Code Online (Sandbox Code Playgroud)


小智 5

当我在寻找如何通过 Traefik v2.2 将所有内容重定向到 HTTPS 时,我正在寻找这个答案,对我来说最好的选择是将此 ENV 变量添加到 Traefik,它会自动将所有流量重定向到 HTTPS。

TRAEFIK_ENTRYPOINTS_WEB_ADDRESS=:80
TRAEFIK_ENTRYPOINTS_WEBSECURE_ADDRESS=:443
TRAEFIK_ENTRYPOINTS_WEB_HTTP_REDIRECTIONS_ENTRYPOINT_TO=websecure
Run Code Online (Sandbox Code Playgroud)

这样我就不需要向中间件添加任何内容。有关该功能的更多信息可以在官方文档中找到。


Xii*_*ryo 3

好的,发现...我假设中间件可以在 Traefik 级别声明,但这些必须在服务级别声明。

这一行:

- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
Run Code Online (Sandbox Code Playgroud)

必须位于 whoami 服务的标签中。

与所描述的问题无关的另一点是,http 质询必须在端口 80 上完成。

- "--certificatesresolvers.myhttpchallenge.acme.httpchallenge.entrypoint=web-secure"
Run Code Online (Sandbox Code Playgroud)

删除“web-secure”中的“secure”。