How to redirect http to https with Traefik 2.0 and Docker Compose labels?
DockerDocker ComposeTraefikDocker Problem Overview
Please note that it is a Traefik V2 question. I had a solution on V1 but V2 is a total rewamp.
This above is supposed to redirect http://whoami.mysite.com to https://whoami.mysite.com.
- The https is working nicely.
- The http don't redirect to https and raise an error 404.
There is no other file. All is in this Docker-compose.yml for the moment since it is a test to prepare further deployement.
version: "3.3"
services:
traefik:
image: "traefik:v2.0"
container_name: "traefik"
command:
- "--log.level=DEBUG"
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.web-secure.address=:443"
- "--certificatesresolvers.myhttpchallenge.acme.httpchallenge=true"
- "--certificatesresolvers.myhttpchallenge.acme.httpchallenge.entrypoint=web-secure"
#- "--certificatesresolvers.myhttpchallenge.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
- "[email protected]"
- "--certificatesresolvers.myhttpchallenge.acme.storage=/letsencrypt/acme.json"
labels:
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "./letsencrypt:/letsencrypt"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
whoami:
image: "containous/whoami"
container_name: "whoami"
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.mysite.com`)"
- "traefik.http.routers.whoami.entrypoints=web"
- "traefik.http.routers.whoami.middlewares=redirect-to-https@docker"
- "traefik.http.routers.whoami-secured.rule=Host(`whoami.mysite.com`)"
- "traefik.http.routers.whoami-secured.entrypoints=web-secure"
- "traefik.http.routers.whoami-secured.tls=true"
- "traefik.http.routers.whoami-secured.tls.certresolver=myhttpchallenge"
Docker Solutions
Solution 1 - Docker
I suggest to take a look here at the docs Entrypoint redirect 80 > 443
This worked for me and is the best solution if you want all traffic redirected from port 80 to 443.
--entrypoints.web.address=:80
--entrypoints.web.http.redirections.entryPoint.to=websecure
--entrypoints.web.http.redirections.entryPoint.scheme=https
--entrypoints.web.http.redirections.entrypoint.permanent=true
--entrypoints.websecure.address=:443
> NOTE: > > there are so many examples around. Just take a look at websecure. > > Sometimes it is written web-secure.
Hope that helps ;o)
Solution 2 - Docker
There is now a working solution in a tutorial from Gérald Croës at:
https://blog.containo.us/traefik-2-0-docker-101-fc2893944b9d
services:
traefik:
image: "traefik:v2.0.0"
# ...
labels:
# ...
# middleware redirect
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
# global redirect to https
- "traefik.http.routers.redirs.rule=hostregexp(`{host:.+}`)"
- "traefik.http.routers.redirs.entrypoints=web"
- "traefik.http.routers.redirs.middlewares=redirect-to-https"
Solution 3 - Docker
You don't need to configure the Traefik service itself. On Traefik you only need to have entrypoints to :443 (web-secure) 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-web-secure.redirectscheme.scheme=https
- traefik.http.routers.mywebserver-web.middlewares=mywebserver-redirect-web-secure
- traefik.http.routers.mywebserver-web.rule=Host(`sub.domain.com`)
- traefik.http.routers.mywebserver-web.entrypoints=web
- traefik.http.routers.mywebserver-web-secure.rule=Host(`sub.domain.com`)
- traefik.http.routers.mywebserver-web-secure.tls.certresolver=mytlschallenge
- traefik.http.routers.mywebserver-web-secure.tls=true
- traefik.http.routers.mywebserver-web-secure.entrypoints=web-secure
# if you have multiple ports exposed on the service, specify port in the web-secure service
- traefik.http.services.mywebserver-web-secure.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-web-secure (middleware, redirect to https) --> mywebserver-web-secure (router, https rule) --> mywebserver (service)
Solution 4 - Docker
You just need to add the following to the traefik config, not application;
- "--entrypoints.websecure.address=:443"
- "--entrypoints.web.address=:80"
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
- "--entrypoints.web.http.redirections.entryPoint.scheme=https"
- "--entrypoints.web.http.redirections.entrypoint.permanent=true"
Here is the full yaml config of the traefik
version: "3.3"
services:
traefik:
image: "traefik:v2.5"
container_name: "traefik"
command:
# - "--log.level=DEBUG"
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.web.address=:80"
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
- "--entrypoints.web.http.redirections.entryPoint.scheme=https"
- "--entrypoints.web.http.redirections.entrypoint.permanent=true"
- "--certificatesresolvers.myresolver.acme.tlschallenge=true"
#- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
- "[email protected]"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
ports:
- "443:443"
- "80:80"
- "8080:8080"
volumes:
- "./letsencrypt:/letsencrypt"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
Example application
whoami:
image: "traefik/whoami"
container_name: "simple-service"
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`subdomain.domain.com`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
- "traefik.http.routers.whoami.tls.certresolver=myresolver"
Solution 5 - Docker
I was searching for this answer when I was looking how to redirect everything to HTTPS via Traefik v2.2 and the best option for me was adding this ENV variables to Traefik and it automatically redirects all traffic to HTTPS.
TRAEFIK_ENTRYPOINTS_WEB_ADDRESS=:80
TRAEFIK_ENTRYPOINTS_WEBSECURE_ADDRESS=:443
TRAEFIK_ENTRYPOINTS_WEB_HTTP_REDIRECTIONS_ENTRYPOINT_TO=websecure
With this I have no need to add anything to the middleware. More information about that feature can be found in the official documentation.
Solution 6 - Docker
Ok, found... I assumed that middlewares could be declared at Traefik level but these have to be declared at service level.
This line :
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
Has to be in the labels of the whoami service.
Another point, that is not related to the problem described, is that the http challenge has to be done on port 80.
- "--certificatesresolvers.myhttpchallenge.acme.httpchallenge.entrypoint=web-secure"
Remove the "secure" in "web-secure".
Solution 7 - Docker
It seems like the global setting is not being done with labels, but with the traefik command arguments. Your question is about labels, but maybe this solution will work for you too?
Here's what to do, according to the official docs under: https://docs.traefik.io/migration/v1-to-v2/#http-to-https-redirection-is-now-configured-on-routers
What used to be in v1:
# static configuration
defaultEntryPoints = ["web", "websecure"]
[entryPoints]
[entryPoints.web]
address = ":80"
[entryPoints.web.redirect]
entryPoint = "websecure"
[entryPoints.websecure]
address = ":443"
[entryPoints.websecure.tls]
Now appears to be:
--entrypoints.web.address=:80
--entrypoints.web.http.redirections.entrypoint.to=websecure
--entrypoints.web.http.redirections.entrypoint.scheme=https
--entrypoints.websecure.address=:443
--providers.docker=true
Solution 8 - Docker
For kubernetes helm chart users on a recent version of traefik, you can use this in your traefik values file (tested on chart version 10.3.2 / traefik 2.5) to redirect ALL traffic to httpS
# values.yaml
ports:
web:
redirectTo: websecure
In case you need CRD updates (traefik 2.4 -> 2.5) use this gist