For anyone who is looking for a solution, to determine per domain whether it should be www or without www. I made 2 middlewares, which can be set per domain. I was looking after this. but couldn't find a quick answer. That's why i'm sharing my solution here:
Part of my global traefik labels (v2.1)
labels:
# global redirect to https
- traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)
- traefik.http.routers.http-catchall.entrypoints=http
- traefik.http.routers.http-catchall.middlewares=redirect-to-https
# middleware redirect
- traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https
- traefik.http.middlewares.redirect-to-https.redirectscheme.permanent=true
# middleware redirect to www
- traefik.http.middlewares.redirect-to-www.redirectregex.regex=(https|http)://(?:www.)?(.*)
- traefik.http.middlewares.redirect-to-www.redirectregex.replacement=https://www.$${2}
# middleware redirect to non-www
- traefik.http.middlewares.redirect-to-nonwww.redirectregex.regex=(https|http)://(www\.(.*))
- traefik.http.middlewares.redirect-to-nonwww.redirectregex.replacement=https://$${3}
Your solution certainly looks good too. And is the answer to the original post. My swarm environment has multiple domains, with different wishes to www or non www and don't want people to go to the wrong url. But they will been forced to the correct www or non www environment.
Please, don't hate me Just to grasp better how v.2 works under the hood, I'm trying to mix redirections up and I moved http > https rule at the entry point level. This is my example:
command:
- --entrypoints.webinsecure.address=:80
- --entrypoints.webinsecure.http.redirections.entrypoint.to=websecure
- --entrypoints.webinsecure.http.redirections.entrypoint.scheme=https
- --entrypoints.websecure.address=:443
labels:
# Global redirection: http to https (no more necessary now)
# traefik.http.routers.http-catchall.rule: HostRegexp(`{host:(www\.)?.+}`)
# traefik.http.routers.http-catchall.entrypoints: webinsecure
# 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
Sorry, I do not understand. No? Why do you expect it to? 404 means that no rules match and indeed in this case you wonβt have a tls router with a matching rule.
Sorry, my bad. I do not want to take advantage of your time. The thing is that from these previous posts:
Big thanks for the code! But... why this? [http.routers.wwwsecure-catchall.tls]
Could be because traefik 2.2 was not there back then.
Isn't it a valid configuration for Traefik v.2.2.x?
I was referring to the fact that the entry point redirection was added in that version
I erroneously understood that http.routers.wwwsecure-catchall.tls could have been avoided when you use the entry point redirection... but it is exactly the contrary.
As the doc says, you need to explicitly dedicate the router to HTTPS. So, my example could work iif traefik.http.routers.wwwsecure-catchall.tls is there.
Yes! It could! you do not need the middleware for redirecting from http to https, if you apply entry point redirection. But in your last example when you get 404 at https://www.foo.com you are already at https, that is the redirection has already happened, and there is no router rule to match.
So, I'm afraid I'm misunderstanding the rule of HostRegexp or the role of wwwsecure-catchall.
The http -> https redirection is made at the entry point level, and it's great! So all routers have just to deal with https. In my initial idea, the router rule HostRegexp(`{host:(www\.).+}`) should catch urls like https://www.foo.com and then the router should pass them to the middleware wwwtohttps in order to remove the www and to pass forward the request https://foo.com. But this happens only if I specify the option wwwsecure-catchall.tls.