Traefik’s HTTP to HTTPS redirect is actually a feature you enable, not a bug you fix.

Here’s how to set it up for permanent redirects, assuming you’ve already got Traefik running with Let’s Encrypt certificates. This is what you’ll see when a user hits your site over HTTP:

HTTP/1.1 301 Moved Permanently
Location: https://your.domain.com/
Content-Length: 0
Date: Tue, 13 Feb 2024 10:00:00 GMT
Server: Traefik

This is the standard way the web tells browsers, "Hey, this content is permanently at this new HTTPS address, go there instead."

The Core Concept: Middleware

Traefik uses "middleware" to modify requests before they reach your services. The HTTP to HTTPS redirect is just one type of middleware. You define it once and then apply it to any routers that need it.

Setting Up the Redirect

You’ll configure this in your Traefik static configuration (usually traefik.yml or command-line arguments) or, more commonly, in your dynamic configuration (often via Docker labels or a Kubernetes Ingress/CRD). We’ll focus on the dynamic configuration, as it’s more flexible.

Here’s a typical Docker Compose setup for Traefik with a service that needs the redirect:

version: '3.7'

services:
  traefik:
    image: traefik:v2.10 # Use a recent v2.x version
    command:
      - --api.insecure=true # For dashboard access
      - --providers.docker=true
      - --entrypoints.http.address=:80
      - --entrypoints.https.address=:443
      - --certificatesresolvers.myresolver.acme.email=your-email@example.com
      - --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json
      - --certificatesresolvers.myresolver.acme.tlschallenge=true
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./letsencrypt:/letsencrypt # Directory for Let's Encrypt certificates
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.rule=Host(`traefik.your.domain.com`)"
      - "traefik.http.routers.traefik.entrypoints=http,https"
      - "traefik.http.routers.traefik.tls=true"
      - "traefik.http.routers.traefik.certificateresolver=myresolver"
      - "traefik.http.routers.traefik.middlewares=redirect-to-https@docker" # Apply the middleware here

  whoami:
    image: traefik/whoami # A simple demo service
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.whoami.rule=Host(`whoami.your.domain.com`)"
      - "traefik.http.routers.whoami.entrypoints=http,https"
      - "traefik.http.routers.whoami.tls=true"
      - "traefik.http.routers.whoami.certificateresolver=myresolver"
      - "traefik.http.routers.whoami.middlewares=redirect-to-https@docker" # Apply the middleware to this service too

  # Define the middleware itself
  traefik-whoami-redirect: # This service is just to define the middleware
    image: traefik/traefik
    command:
      - --providers.docker.exposedbydefault=false # Important: don't expose this service
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.permanent=true"
      - "traefik.http.routers.traefik-whoami-redirect.rule=Host(`whoami.your.domain.com`)" # This rule is technically not needed for middleware definition, but required by Traefik
      - "traefik.http.routers.traefik-whoami-redirect.service=no-service" # This service is also not needed

Explanation:

  1. Traefik Service: The main traefik service is configured with entrypoints for HTTP (80) and HTTPS (443). It also has Let’s Encrypt configured. Notice how the traefik router itself is also configured to use the redirect-to-https middleware.
  2. whoami Service: This is a dummy service to demonstrate the redirect. It’s also configured to use the redirect-to-https middleware.
  3. Middleware Definition Service (traefik-whoami-redirect): This is the crucial part. We create a separate service that only serves to define Traefik middleware.
    • traefik.enable=true: This tells Traefik to look at the labels on this service.
    • traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https: This defines a middleware named redirect-to-https. The redirectscheme type tells Traefik to change the scheme of the request. We’re setting it to https.
    • traefik.http.middlewares.redirect-to-https.redirectscheme.permanent=true: This is what makes it a "301 Moved Permanently" redirect. If you wanted a temporary redirect (302), you’d omit this or set it to false.
    • The rule and service labels for this middleware definition service are a bit of a hack. Traefik requires routers to have these, but for a service whose sole purpose is defining middleware, they don’t actually do anything. exposedbydefault=false on the Traefik provider for this service is important to prevent it from being accidentally exposed.

Applying the Middleware

Once defined, you apply the middleware to your routers using the traefik.http.routers.<router-name>.middlewares label. In the example above, both the traefik router and the whoami router have traefik.http.routers.whoami.middlewares=redirect-to-https@docker. The @docker part tells Traefik which provider the middleware is coming from.

How it Works Internally

When a request comes in on the http entrypoint (port 80) for whoami.your.domain.com, Traefik’s router for whoami matches the request. It then checks the associated middlewares. It finds redirect-to-https.

The redirectscheme middleware intercepts the HTTP request. It sees scheme=https and permanent=true. It then generates an HTTP 301 response, telling the client’s browser to make a new request to the same host but with the https scheme. The browser automatically does this, and the subsequent HTTPS request will be handled by Traefik’s https entrypoint and its corresponding router, which will then forward it to the whoami service.

The "One Thing" Most People Don’t Know

You can define multiple redirect schemes within a single middleware definition. For instance, if you wanted to redirect both HTTP to HTTPS and also redirect a specific path (/old-path) to a new one (/new-path), you’d configure it like this in your middleware definition service:

      - "traefik.http.middlewares.complex-redirect.redirectscheme.scheme=https"
      - "traefik.http.middlewares.complex-redirect.redirectscheme.permanent=true"
      - "traefik.http.middlewares.complex-redirect.redirectscheme.port=443" # Explicitly define the port if not default
      - "traefik.http.middlewares.complex-redirect.redirectregex.regex=^http://your.domain.com/old-path/(.*)"
      - "traefik.http.middlewares.complex-redirect.redirectregex.replacement=https://your.domain.com/new-path/$1"
      - "traefik.http.middlewares.complex-redirect.redirectregex.permanent=true"

This allows for powerful, chained redirections using a single middleware definition applied to a router.

The next thing you’ll likely want to tackle is securing your Traefik dashboard itself, or understanding how to set up custom error pages.

Want structured learning?

Take the full Traefik course →