Traefik v2: 404 while routing HTTP traffic globally to HTTPS

This is for those who are trying Global HTTP to HTTPS redirection on Traefik 2. Some of you might be getting 404 on the http endpoints. After literal hours spending on the different forums. This works for me. This applies for people who want to use pre-signed ssl certificates as well.

As most of us are using config provided in the traefik blogs and many dont contain the command section of traefik container where we declared for security purpose

"--providers.docker.exposedbydefault=false"

This prevents the global https redirector to work if we dont give

"traefik.enable=true"

here is the full file

version: "3.8"
services:
  traefik:
    image: "traefik:v2.2.1"
    container_name: "traefik"
    command:
      - "--log.level=DEBUG"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--providers.docker.watch=true"
      - "--providers.file.directory=/conf/"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
    ports:
      - "80:80"
      - "443:443"
    networks:
      - somenetwork
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - ./certs:/certs
      - ./conf:/conf
    labels:
      # this is needed as we did the --providers.docker.exposedbydefault=false
      - "traefik.enable=true"
      # middleware redirect
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
      # global redirect to https
      - "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
      - "traefik.http.routers.http-catchall.entrypoints=web"
      - "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
  whoami:
    image: "containous/whoami"
    container_name: "simple-service"
    networks:
      - somenetwork
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami-secure.entrypoints=websecure"
      - "traefik.http.routers.whoami-secure.tls=true"
      - "traefik.http.routers.whoami-secure.rule=Host(`test.traefik.localhost`)"

I am also adding the certificates.toml inside conf directory. If you are working on localhost then you can add this using mkcert openssl etc. For production you need to need to get this from certificate providers. And you need to add the certificates in the certs folder.

[[tls.certificates]] #first certificate
   certFile = "/certs/_wildcard.traefik.localhost.pem"
   keyFile = "/certs/_wildcard.traefik.localhost-key.pem"

And of course you can use lets encrypt. There are a lot of blogs on that topic.

Hope this saves your times. :)


You don't need to configure the Traefik service itself. On Traefik you only need to have entrypoints to :443 (websecure) and :80 (web)

Because Traefik only acts as entryPoint and will not do the redirect, the middleware on the target service will do that.

Now configure your target service as the following:

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

So basically the flow goes like this:

Request: http://sub.domain.com:80 --> traefik (service) --> mywebserver-web (router, http rule) --> mywebserver-redirect-websecure (middleware, redirect to https) --> mywebserver-websecure (router, https rule) --> mywebserver (service)