A global http -> https redirection?

Thanks for your work on this great project. I like a lot the new features of traefik 2.

I'm currently migrating a v1 configuration to a v2 one.
From what I gather if I want an http -> https redirection I have to add a RedirectScheme middleware to a router. The issue is that I'd prefer not to add that particular configuration to all of my services manually. I feel like the https decision doesn't belong to the service.

Is there any way or any plan to achieve this globally? Maybe a concept of global middleware that would apply to all routers?


1 Like


I faced same issue when I first tried v2 on a project.

On v1, it was simply defined:

  address = ":80"
    entryPoint = "https"
  address = ":443"

On v2, with middlewares, we got more flexibility but we lost (basic) simple features.

Tried to find a way for this but with no success.

The only way that should work, is to add a middleware at EntryPoints level (similar to v1), but as I see, RedirectScheme is available only at HTTP level.

(EntryPoints have only: transport,proxyProtocol and forwardHeaders).

Any workaround for this?

1 Like


On my side I defined a router on the traefik container itself, attached to entry point "web", catching all hosts and redirecting to https.
And then I only define TLS router attached only to "websecure" entry point on the services themselves.

This way, only one router listen on "web" entry point, and it redirect everything on https. And the services only listen on "websecure" entry point.
Downsides I see for now:

  • As I have a catch all on http, I'm not sure I could easily expose something else on http if needed
  • when requesting a specific host which is not defined, you get an SSL error instead of standard 404 default backend

With the following example, when you go to http://localhost, you're redirected to https.

docker-compose example:

version: "3.3"


    image: "traefik:v2.0.0-alpha8-alpine"
      - "traefik.enable=true"
      - "traefik.http.routers.http-catchall.rule=hostregexp(`{host:[a-z-.]+}`)"
      - "traefik.http.routers.http-catchall.entrypoints=web"
      - "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
      - "80:80"
      - "443:443"
      - "8080:8080"
      - "./traefik.toml:/etc/traefik.toml"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

    image: containous/whoami
      - "80"
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`localhost`)"
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.routers.whoami.tls=true"


  sendAnonymousUsage = true

  exposedByDefault = false

    address = ":80"
    address = ":443"

Not sure it's the best way to do this, but it seems to work.


Interesting. So from the way things look, it seems these "names" are global. So if there's a large team they need to watch out to make sure there are name clashes.

Thank you, this was pretty helpful!

I did this in my docker-compose to redirect, but this need to be done on every service to be exposed. this is no a catch all solution but you will get more controll over what is exposed on http and https.

    image: containous/whoami
      # listen for http request and redirect to https
      - "traefik.http.routers.whoami-http.middlewares=https-redirect@file"
      - "traefik.http.routers.whoami-http.rule=Host(`whoami.example.test`)"

      # listen for https requests and use forward auth.
      # Terminate SSL, whoami doesnt listen on SSL traffic, whoami is listening on plain text unencrypted http connections.
      # https://docs.traefik.io/v2.0/routing/routers/#tls
      - "traefik.http.routers.whoami.tls"
      - "traefik.http.routers.whoami.rule=Host(`whoami.example.test`)"
      - "traefik.http.routers.whoami.middlewares=forward-auth@file"

seems overly complicated and verbose, is it really needed to create two routers for each service?

Yes you need to read 2 routers for each redirection.

We know the problem and we plan to think about a new redirection system.

I link another thread to this thread, because it's the same subject:

1 Like

I ran into this problem on a kubernets,

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
  name: admin
    - web
    - websecure
  - match: Host(`pwjtest.zhixueyun.com`) && PathPrefix(`/`)
    kind: Rule
    - name: traefik
      port: 18080
    #  scheme: https
    - name: admin-https
    - name: admin-auth
    #- name: admin-header
    secretName: supersecret
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
  name: admin-https
    scheme: https
    permanent: true
    port: 443
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
  name: admin-auth
    secret: authsecret

访问http://domain 会出现404,并不会重定向http://domain.访问http://domain是正常的.

With two routers, write HTTP as one router and HTTPS as one router, and successfully redirect HTTPS with the following configuration.

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
  name: test-redirectregex
    regex: ^http://localhost/(.*)
    replacement: https://mydomain/${1}

I don't know if this is my own configuration problem or a bug.

I tried to solve this by using the file backend so that the number of labels in my docker-compose.yml will be reduced. In my setup I used my own traefik Docker container that already ships with the configuration. I don't know if this is useful or not (and may or may not be included in the documentation) but I wanted to share it anyway:

  • static configuration
  address = ":80"
  address = ":443"
  • dynamic configuration
# dummy service
    url = "http://localhost/"

# router with PathPrefix /, so everything will be matched
  entryPoints = [ "http" ]
  rule = "PathPrefix(`/`)"
  middlewares = [ "DefaultHTTPSRedirect" ]
  service = "DefaultHTTPSRedirect"
  # lowest possible priority so that the match can be overwritten by anyone
  priority = 1

  scheme = "https"
  permanent = true

It's a bit of traefik idiosyncrasy, is not it? That one has to specify http.services.DefaultHTTPSRedirect.loadBalancer.servers.url which is never used because of the middleware, but traefik would error out if you omit.

Yes, it is :smiley:

You can define everything also inside of a docker-compose.yml with labels and then can omit the service part, because that is autogenerated, but in the file case - as you wrote - you'll run into an error. Maybe using an internal redirecting to api@internal as a service (so something like this) will help to reduce the amount of unnecessary configuration, but the service attribute must unfortunately be set.