添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

If you followed the Traefik docs you would have expected that it's going to work, but as it goes, it's never that straightforward. Let's go over the additional sneaky steps we have to do.

Configuration Confusion

I don't know about you, but the first time I read their docs I was confused about the different configurations Traefik offers. It basically boils down to the following.

Traefik has two types of configurations :

  • Static configuration which is read at startup and defines entry points and provider data for the dynamic configuration.
  • Dynamic configuration which is read runtime and handles everything else: Routers, Services, Middlewares, and Certificates
  • Static configuration can be in the form of a Yaml/Toml file, ENV arguments, or CLI parameters passed in your docker-compose.yml to your Traefik service.

    Dynamic configuration can be in many forms depending on which provider you are using, for the full list you can read the Supported Providers section of the docs.

    It is also possible to cross-reference configurations from different providers or from static to dynamic but let's leave that for another day, if you're keen on reading up on it, you can read the section about Provider Namespaces in the official docs.

    Now that we have this out of the way, let's get to the problem at hand.

    Entrypoint global redirect from HTTP to HTTPS

    In the examples, in this article, we're going to be using the Docker provider for the dynamic configuration and a Yaml file for the static configuration parts. The docs say we should add the following rules under our entryPoints key:

    entryPoints:
            address:  :80
            http:
                redirections:
                    entryPoint:
                        to: web-secure
                        scheme: https
                        permanent: true
        web-secure:
            address:  :443

    web and web-secure keys can be anything, that's user-defined not to be confused like I was the first time I used it. This looks simple enough, and when you run it you would expect it is going to work as I did and then I had an open HTTP port in production for almost a year now for my personal website, which thankfully returned nothing, but still.

    The catch is when you define your routing rules in your provider dynamic config, for this global redirect to work, you need to have two routers for the same domain, one for HTTP listening on port 80 and one for HTTPS listening on port 443 with the TLS config enabled.

      backend:
        labels:              
          # sasablagojevic.com web (Entrypoint global scheme redirect requires web router definitions)
          traefik.http.routers.sasablagojevic-http.entrypoints: web  
          traefik.http.routers.sasablagojevic-http.rule: "Host(`sasablagojevic.com`, `www.sasablagojevic.com`)"
          # sasablagojevic.com web-secure
          traefik.http.routers.sasablagojevic.entrypoints: web-secure
          traefik.http.routers.sasablagojevic.rule: "Host(`sasablagojevic.com`, `www.sasablagojevic.com`)"
          traefik.http.routers.sasablagojevic.tls: true
          traefik.http.routers.sasablagojevic.tls.certresolver: myresolver
          traefik.http.routers.sasablagojevic.tls.domains[0].main: sasablagojevic.com
          traefik.http.routers.sasablagojevic.tls.domains[0].sans: www.sasablagojevic.com

    This is required by Traefik to be able to catch the requests on port 80 and redirect them to port 443.

    You can validate if the entry point global scheme redirect is working by looking in the Traefik admin panel, you should see the item underlined with a red line from the screenshot:


    Middleware redirect from HTTP to HTTPS

    There is also a different approach you can take and instead of a global redirect which redirects all traffic from port 80 to port 443, you can define, a per-service redirect with middlewares. Traefik gives us a middleware for that out of the box, we just need to wire it up in our docker-compose.yml

      backend:
        labels:
          # www -> non-www redirect middleware declaration
          traefik.http.middlewares.www-redirect.redirectregex.regex: "^https://www.(.*)"
          traefik.http.middlewares.www-redirect.redirectregex.replacement: "https://$${1}"
          traefik.http.middlewares.www-redirect.redirectregex.permanent: true
          # http -> https redirect middleware declaration
          traefik.http.middlewares.http-redirect.redirectscheme.scheme: https
          traefik.http.middlewares.http-redirect.redirectscheme.permanent: true
          # sasablagojevic.com web 
          traefik.http.routers.sasablagojevic-http.entrypoints: "web"  
          traefik.http.routers.sasablagojevic-http.rule: "Host(`sasablagojevic.com`, `www.sasablagojevic.com`)"
          traefik.http.routers.sasablagojevic-http.middlewares: "http-redirect"
          # sasablagojevic.com web-secure
          traefik.http.routers.sasablagojevic.entrypoints: web-secure
          traefik.http.routers.sasablagojevic.rule: "Host(`sasablagojevic.com`, `www.sasablagojevic.com`)"
          traefik.http.routers.sasablagojevic.tls: true
          traefik.http.routers.sasablagojevic.tls.certresolver: myresolver
          traefik.http.routers.sasablagojevic.tls.domains[0].main: sasablagojevic.com
          traefik.http.routers.sasablagojevic.tls.domains[0].sans: www.sasablagojevic.com
          traefik.http.routers.sasablagojevic.middlewares: "www-redirect"
    

    Once again the .http-redirect. segment of the middleware label is user-defined and can be anything. As you can see from the provided example, each middleware configuration has two parts, the declaration part, and the part where we wire it up with our service.

    Hope this saves you some time, I lost a whole day going in circles with this...

    Last updated: 1 year ago