There are already quite a few threads on this. Here is one of them: A global http -> https redirection?
@ldez Is there a github issue for that, since you said, that you are aware / want to improve this?
There are already quite a few threads on this. Here is one of them: A global http -> https redirection?
@ldez Is there a github issue for that, since you said, that you are aware / want to improve this?
@ldez Thank you for this, someone came up with this workaround:
# Global http to https redirect
traefik.http.routers.http-catchall.rule: "hostregexp(`{host:.+}`)"
traefik.http.routers.http-catchall.entrypoints: web
traefik.http.routers.http-catchall.middlewares: redirect-to-https
It seems to work, any downsides of this solution?
And an awesome solution it was !
On a side note, I noticed you created a posting on GItHub regarding (or someone did) and I didn't notice the CLI version on there. Should it be on there as well to make sure if they use it they post up both version, does it not make a difference or did I just completely miss it (highly likely)?
Thanks again.
To answer to original question, a global approach can be:
version: '3.7'
services:
traefik:
image: traefik:v2.1.3
command:
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --log.level=INFO
ports:
- 80:80
- 443:443
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
labels:
traefik.enable: true
# Global redirection: http to https
traefik.http.routers.http-catchall.rule: HostRegexp(`{host:(www\.)?.+}`)
traefik.http.routers.http-catchall.entrypoints: web
traefik.http.routers.http-catchall.middlewares: wwwtohttps
# Global redirection: https (www.) to https
traefik.http.routers.wwwsecure-catchall.rule: HostRegexp(`{host:(www\.).+}`)
traefik.http.routers.wwwsecure-catchall.entrypoints: websecure
traefik.http.routers.wwwsecure-catchall.tls: true
traefik.http.routers.wwwsecure-catchall.middlewares: wwwtohttps
# middleware: http(s)://(www.) to https://
traefik.http.middlewares.wwwtohttps.redirectregex.regex: ^https?://(?:www\.)?(.+)
traefik.http.middlewares.wwwtohttps.redirectregex.replacement: https://$${1}
traefik.http.middlewares.wwwtohttps.redirectregex.permanent: true
whoami:
image: containous/whoami
labels:
traefik.enable: true
traefik.http.routers.whoami.rule: Host(`whoami.localhost`)
traefik.http.routers.whoami.entrypoints: websecure
traefik.http.routers.whoami.tls: true
traefik.toml
(static configuration)[entryPoints.web]
address = ":80"
[entryPoints.websecure]
address = ":443"
[providers.file]
directory = "/dyn/"
[log]
level = "INFO"
/dyn/global_redirection.toml
(dynamic configuration)# Global redirection: http to https
[http.routers.http-catchall]
rule = "HostRegexp(`{host:(www\\.)?.+}`)"
entryPoints = ["web"]
middlewares = ["wwwtohttps"]
service = "noop"
# Global redirection: https (www.) to https
[http.routers.wwwsecure-catchall]
rule = "HostRegexp(`{host:(www\\.).+}`)"
entryPoints = ["websecure"]
middlewares = ["wwwtohttps"]
service = "noop"
[http.routers.wwwsecure-catchall.tls]
# middleware: http(s)://(www.) to https://
[http.middlewares.wwwtohttps.redirectregex]
regex = "^https?://(?:www\\.)?(.+)"
replacement = "https://${1}"
permanent = true
# NOOP service
[http.services.noop]
[[http.services.noop.loadBalancer.servers]]
url = "http://192.168.0.1:666"
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: http_catchall
namespace: bar
spec:
entryPoints:
- web
routes:
- match: 'HostRegexp(`{host:(www\.)?.+}`)'
kind: Rule
middlewares:
- name: wwwtohttps
services:
- name: foo-svc
port: 666
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: wwwsecure_catchall
namespace: bar
spec:
entryPoints:
- websecure
routes:
- match: 'HostRegexp(`{host:(www\.).+}`)'
kind: Rule
middlewares:
- name: wwwtohttps
services:
- name: foo-svc
port: 666
tls: {}
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: wwwtohttps
namespace: bar
spec:
redirectRegex:
regex: '^https?://(?:www\.)?(.+)'
replacement: 'https://${1}'
permanent: true
Results:
Request | Redirection | |
---|---|---|
http://whoami.localhost | -> | https://whoami.localhost |
http://www.whoami.localhost | -> | https://whoami.localhost |
https://www.whoami.localhost | -> | https://whoami.localhost |
version: '3.7'
services:
traefik:
image: traefik:v2.1.3
command:
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --log.level=INFO
ports:
- 80:80
- 443:443
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
labels:
traefik.enable: true
# Global redirection: http to https
traefik.http.routers.http_catchall.rule: HostRegexp(`{host:.+}`)
traefik.http.routers.http_catchall.entrypoints: web
traefik.http.routers.http_catchall.middlewares: tohttps
# middleware: http:// to https://
traefik.http.middlewares.tohttps.redirectscheme.scheme: https
traefik.http.middlewares.tohttps.redirectscheme.permanent: true
# middleware: https://www. to https://
traefik.http.middlewares.trim_www.redirectregex.regex: ^https://www\.(.+)
traefik.http.middlewares.trim_www.redirectregex.replacement: https://$${1}
traefik.http.middlewares.trim_www.redirectregex.permanent: true
whoami:
image: containous/whoami
labels:
traefik.enable: true
traefik.http.routers.whoami.rule: Host(`whoami.localhost`, `www.whoami.localhost`)
traefik.http.routers.whoami.entrypoints: websecure
traefik.http.routers.whoami.middlewares: trim_www
traefik.http.routers.whoami.tls: true
Note: the redirections are made by routers, the routers are a part of the dynamic configuration, so a CLI flags version is not possible because flags handle the static configuration.
Hi Idez,
This is what I'm looking for as I have spent countless hours trying to figure out how to do the www to http redirect to no avail... EXCEPT... I can't get it to work. I'm close but having Let's Encrypt issues (at least that's what I think my issue is).
What's happening:
Not sure why when I enter https://www... it doesn't work. I'm assuming it's trying to check the certificate before it does a redirect (URL remains at https://www.traefik-whoami.creativesandbox.dev). Same result in both Safari and Firefox though warnings are worded differently.
I tried adding and extra rule to the whoami service so that it read "Host(traefik-whoami.creativesandbox.dev
) || Host(https://www.traefik-whoami.creativesandbox.dev
)" but that didn't make any difference... and now I'm out of ideas.
Maybe I'm searching for the wrong things but all my searches for www to non-www have not helped me (until you came along with this).
Thanks for all the work so far, here's hoping you can help with this last little bit. Current code below:
# Based on https://blog.containo.us/traefik-2-0-docker-101-fc2893944b9d
# Global redirection incl. www to https [Global redirect www to non-www with HTTPS redirection](https://community.containo.us/t/global-redirect-www-to-non-www-with-https-redirection/2313/9?u=mindgonemad)
# Swarm Mode [How to install Traefik 2.x on a Docker Swarm](https://creekorful.me/how-to-install-traefik-2-docker-swarm/)
version: "3.7"
services:
traefik:
image: traefik:2.0.2
networks:
- traefik-public
command:
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --providers.docker.exposedbydefault=false
# Swarm
- --providers.docker.swarmMode=true
# Enables web UI and tells Traefik to listen to docker
- --providers.docker
- --api
# Let's Encrypt
- --certificatesresolvers.leresolver.acme.email=myemail@email.com
- --certificatesresolvers.leresolver.acme.storage=/letsencrypt/acme.json
- --certificatesresolvers.leresolver.acme.tlschallenge=true
# Logging
- --log.level=DEBUG # DEBUG, ERROR, INFO???
- --log.filePath=/traefik.log
- --log.format=json
ports:
- "80:80"
- "443:443"
volumes:
- ./letsencrypt:/letsencrypt
- ./logs/traefik.log:/traefik.log
# So that Traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock:ro
deploy:
placement:
constraints:
- node.role == manager
labels:
traefik.enable: "true"
# Dashboard
traefik.http.routers.traefik.rule: "Host(`traefik.creativesandbox.dev`)"
traefik.http.routers.traefik.service: api@internal
traefik.http.routers.traefik.tls.certresolver: leresolver
traefik.http.routers.traefik.entrypoints: websecure
traefik.http.routers.traefik.middlewares: auth-traefik
# Swarm Mode
traefik.http.services.traefik.loadbalancer.server.port: 80
# Basic Auth
traefik.http.middlewares.auth-traefik.basicauth.users: "user:reallylongcodegoeshere"
# Global redirection - http to https
traefik.http.routers.http-catchall.rule: "hostregexp(`{host:(www\\.)?.+}`)"
traefik.http.routers.http-catchall.entrypoints: web
traefik.http.routers.http-catchall.middlewares: redirect-to-https
# Global redirection - https://www to https
traefik.http.routers.https-catchall.rule: "hostregexp(`{host:(www\\.).+}`)"
traefik.http.routers.https-catchall.entrypoints: websecure
traefik.http.routers.https-catchall.tls: "true"
traefik.http.routers.https-catchall.middlewares: redirect-to-https
# Middleware redirection
traefik.http.middlewares.redirect-to-https.redirectregex.regex: "^https?://(?:www\\.)?(.+)"
traefik.http.middlewares.redirect-to-https.redirectregex.replacement: "https://$${1}"
traefik.http.middlewares.redirect-to-https.redirectregex.permanent: "true"
#traefik.http.middlewares.redirect-to-https.redirectscheme.scheme: https
whoami:
image: containous/whoami:v1.3.0
networks:
- traefik-public
deploy:
labels:
traefik.enable: "true"
traefik.http.routers.whoami.rule: "Host(`traefik-whoami.creativesandbox.dev`)"
traefik.http.routers.whoami.middlewares: auth-whoami
traefik.http.routers.whoami.entrypoints: websecure
traefik.http.routers.whoami.tls: "true"
traefik.http.routers.whoami.tls.certresolver: leresolver
# Swarm Mode
traefik.http.services.whoami.loadbalancer.server.port: 80
# Basic Auth
traefik.http.middlewares.auth-whoami.basicauth.users: "user:reallylongcodegoeshere"
networks:
traefik-public:
external: true
You need to make sure that the cert matches all the domains https connection can come to. I do not see you configuring any sans so that could be the reason.
I'll be honest, I'm struggling to wrap my head around this. So far I have done everything use CLI (labels) but I only see examples for SAN using yaml or toml files? Does this mean I need to create now or those? And/or do I need to switch back to DNS challenge instead of TLS because I must say the DNS challenge was a pain in the proverbial as every time I created a service I had to wait for it to propagate (and remember too)?
CLI and labels is not the same. CLI refer to static configuration and labels refer to dynamic one, these are not to be mixed. I'm assuming you don't actually mean CLI, but labels.
The labels reference is here: https://docs.traefik.io/reference/dynamic-configuration/docker/ Search for tls.domains
Thanks. It took me ages to learn/wrap my head around SANs but managed to get it working with two additional lines per service.
traefik.http.routers.whoami.rule: "Host(`traefik-whoami.craighofman.art`)"
traefik.http.routers.whoami.tls.domains[0].main: traefik-whoami.craighofman.art
traefik.http.routers.whoami.tls.domains[0].sans: www.traefik-whoami.craighofman.art
Tried leaving out the main but that didn't work.
I experienced the same problem: https://www.domain.tld was not redirected to https://domain.tld. The other two global redirects worked.
In my case I could solve it with adding the wwwtohttps
middleware to the whoami
container as well:
services:
whoami:
image: containous/whoami
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`domain.tld`, `www.domain.tld`)"
- "traefik.http.routers.whoami.entrypoints=websecure"
- "traefik.http.routers.whoami.tls.certresolver=httpchallenge"
- "traefik.http.routers.whoami.middlewares=wwwtohttps@docker"
networks:
- traefik
networks:
traefik:
external:
name: traefik_default
But this is probably not a recommended solution. I will have to get into SANs as well
Hi idez,
I have updated my .toml file but only https redirection is working and the remaining ones are not working.
My toml file:
[entryPoints]
[entryPoints.web]
address= ":80"
[entryPoints.web-secure]
address = ":443"
[entryPoints.dashboard]
address = ":8080"
[api]
dashboard=true
[certificatesResolvers.default.acme]
email = "cbtu44@gmail.com"
storage = "acme.json"
[certificatesResolvers.default.acme.dnsChallenge]
provider = "gcloud"
delayBeforeCheck = 0
[providers.docker]
exposedByDefault = false
endpoint = "unix:///var/run/docker.sock"
watch = "true"
network = "proxy"
[traefik.http.routers.http-catchall]
rule = "HostRegexp(`{host:(www\\.)?.+}`)"
entryPoints = ["web"]
middlewares = ["wwwtohttps"]
# Global redirection: https (www.) to https
[traefik.http.routers.wwwsecure-catchall]
rule = "HostRegexp(`{host:(www\\.).+}`)"
entryPoints = ["websecure"]
middlewares = ["wwwtohttps"]
[traefik.http.routers.wwwsecure-catchall.tls]
# middleware: http(s)://(www.) to https://
[traefik.http.middlewares.wwwtohttps.redirectregex]
regex = "^https?://(?:www\\.)?(.+)"
replacement = "https://${1}"
permanent = true
in the v2, the dynamic configuration and the static configuration must be defined in separated files:
and like in the v1 the file provider must be enabled to use dynamic configuration from file.
@ldez have defined the dynamic config in docker-compose file.
I am sorry if i didn't understand your question.
version: '3.3'
services:
traefik:
image: traefik:v2.0
restart: always
ports:
- 80:80
- 8080:8080
- 443:443
networks:
- proxy
- internal
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- $PWD/traefik.toml:/traefik.toml
- $PWD/acme.json:/acme.json
container_name: traefik
labels:
- traefik.enable=true
#- traefik.http.routers.web.rule=Host(`stats.prision-aiop.com`)
#- traefik.http.routers.web.entrypoints=web
#- traefik.http.middlewares.web-https-redirects.redirectscheme.scheme=https
#- traefik.http.routers.web.middlewares=web-https-redirects
#- traefik.http.middlewares.web-https-redirects.redirectscheme.permanent=true
- traefik.http.routers.api.entrypoints=web-secure
- traefik.http.routers.api.rule=Host(`stats.domain.com`,`www.stats.domain.com`)
- traefik.http.routers.api.service=api@internal
- traefik.http.routers.api.middlewares=auth
- traefik.http.middlewares.auth.basicauth.users=codebreaker:$$2y$$n6
- traefik.http.routers.api.tls=true
- traefik.http.routers.api.tls.certresolver=default
- traefik.http.routers.api.tls.domains[0].main=domain.com
- traefik.http.routers.api.tls.domains[0].sans=*.domain.com
- traefik.http.routers.api.tls.domains[1].main=domain1.com
- traefik.http.routers.api.tls.domains[1].sans=*.domain1.com
- traefik.docker.network=proxy
#- traefik.http.routers.api.middlewares=wwwtohttps
# global redirections http to https
- "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
- "traefik.http.routers.http-catchall.entrypoints=web"
- "traefik.http.routers.http-catchall.middlewares=web-https-redirect"
# Global redirection: https (www.) to https
- "traefik.http.routers.wwwsecure-catchall.rule=hostregexp(`{host:(www\\.).+}`)"
- "traefik.http.routers.wwwsecure-catchall.entrypoints=web-secure"
- "traefik.http.routers.wwwsecure-catchall.tls=true"
- "traefik.http.routers.wwwsecure-catchall.middlewares=web-https-redirect"
# middleware: http(s)://(www.) to https://
- "traefik.http.middlewares.web-https-redirect.redirectregex.regex=^https?://(?:www\\.)?(.+)"
- "traefik.http.middlewares.web-https-redirect.redirectregex.replacement=https://$${1}"
- "traefik.http.middlewares.web-https-redirect.redirectregex.permanent=true"
I updated/edited my previous answer:
@ldez can you post an example of yaml that would work in kubernetes. Mostly docker examples. Need kubernetes example
i have been back and forth trying to get @ldez solution to work but to no avail
i am using labels in two docker compose files, a main traefik file that also defines the dashboard.${DOMAIN}
the http -> https redirection for dashboard works fine
when i add lighttpd to handle the host={DOMAIN} , www.{DOMAIN} the strip www part doesn't work, it does strip it and redirect but i get a connection error
is it possible to get a complete example vs having snippets?
thanks for the help
I provided complete examples in my answer, you just have to click on items:
Hello @ldez, I tried to implement this improvement to include www to non-www redirecting on top of my http to https redirect using your previous method (that worked perfectly)
# 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"
# middleware redirect
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
Unfortunately, after replacing it with the code for docker provider (both the global and less global approach) to my docker-compose file, the opposite thing happened and when surfing to my domain.eu I got redirected to www.domain.eu
I reverted to the previous situation and had all the trouble in hell to remove the permanent redirects from browser caches. Do you have an idea as to why I got the reversed redirect?
Also, can we set the "redirectregex.permanent: true" to false (or something else), in order to test/debug without using 301 redirects ?