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:
- Traefik Service: The main
traefikservice is configured with entrypoints for HTTP (80) and HTTPS (443). It also has Let’s Encrypt configured. Notice how thetraefikrouter itself is also configured to use theredirect-to-httpsmiddleware. whoamiService: This is a dummy service to demonstrate the redirect. It’s also configured to use theredirect-to-httpsmiddleware.- 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 namedredirect-to-https. Theredirectschemetype tells Traefik to change the scheme of the request. We’re setting it tohttps.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 tofalse.- The
ruleandservicelabels 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=falseon 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.