7

I could not find a question similar to this, there were others mentioning https redirects, but not about minimizing the redirects.

Been looking for a solution, and could not sort it out yet.

We use Docker > Traefik for WordPress and have www as the preferred version for WordPress. There are multiple WP instances. Domains are added dynamically.

However, with this config, I am receiving two redirects, from http to https to https www

http://example.com/
https://example.com/
https://www.example.com/

Is there any way to minimize the redirect?

ideally a 301 redirect from

http://example.com directly to https://www.example.com 

Traefik config file as follows

defaultEntryPoints = ["http", "https"]

[web]
address = ":8080"

[entryPoints]

[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"

[entryPoints.https]
address = ":443"
compress = true
[entryPoints.https.tls]

[acme]
email = "email@domain.com"
storage = "acme.json"
entryPoint = "https"
onDemand = false
OnHostRule = true


[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "traefik.example.com"
watch = true
exposedbydefault = false
BIL Tech
  • 71
  • 1
  • 1
  • 3
  • Just an idea: Start 2 Container.. The Wordpress Container: hostrule www.yourdomain.com https://hub.docker.com/r/chauffer/nginx-301-https/ with hostrule yourdomain.com and redirect to https://wwwyourdomain.com – Berndinox Oct 11 '17 at 11:02

3 Answers3

10

Try replacing your [entryPoints.http.redirect] entry with this:

[entryPoints.http.redirect]
#entryPoint = "https"
regex = "^http:\/\/(www\.)*(example\.com)(.*)"
replacement = "https://www.$2$3"
permanent = true

Regex101

It will not handle the https://example.com/ entry so you need to add:

[entryPoints.https.redirect]
regex = "^https:\/\/(example\.com)(.*)"
replacement = "https://www.$1/$2"
permanent = true

If you have multiple frontedns, the regex can get hard to handle, so instead you can consider having a label on the container, like this:

traefik.frontend.headers.SSLRedirect=true
traefik.frontend.headers.SSLHost=www.example.com

As of 1.7 there is new option SSLForceHost that would force even existing SSL connection to be redirected.

traefik.frontend.headers.SSLForceHost=true
Stoinov
  • 774
  • 12
  • 25
  • 1
    The `SSLRedirect` label doesn't handle the case `https://example.com` => `https://www.example.com`. Any idea how this could be done? – mrtumnus Jul 13 '18 at 15:18
  • The same way I described it in the section before the labels part - by using `[entryPoints.https.redirect]` – Stoinov Jul 13 '18 at 20:12
  • That only works on the entryPoint though (i.e., for all frontends). I was wondering how it could be done on a per-frontend basis. – mrtumnus Jul 23 '18 at 16:19
  • As there aren't any ready to use labels that will do what you want, you either have to make custom configuration, or replace the template file that uses the existing labels. In [this answer](https://stackoverflow.com/questions/48498453/global-configuration-of-security-in-traefik-for-docker/51348868#51348868) I have some more info how to do it properly. – Stoinov Jul 24 '18 at 14:21
  • I ended up just using a redirect via my webserver. – mrtumnus Jul 26 '18 at 13:56
  • They are adding a [new option](https://github.com/containous/traefik/issues/3194) in 1.7 for all providers `SSLForceHost` that you can use to force the redirect even for existing SSL connections. – Stoinov Jul 26 '18 at 16:05
  • In docker-compose you can use env variable in place of the domain to keep config D.R.Y. (I just had to add something as an excuse to say @Stoinov : thank you so much! Great answer) – Tymek Feb 20 '19 at 22:19
  • Using the proposed substitution, you'll end up with one slash too many. See [101 with current substitution](https://regex101.com/r/mLHXkv/9). Instead, use `https://www.$2$3`: [101 with slash removed](https://regex101.com/r/mLHXkv/11). – Tim Nov 18 '19 at 10:08
2

Here's what I had to do. The above answer was helpful, but traefik wouldn't start because you actually need a double \ to escape in the .toml.

Also you still need to make sure you have the normal entry points and ports there. Here's my complete entryPoints section:

[entryPoints]
  [entryPoints.http]
    address = ":80"
  [entryPoints.https]
    address = ":443"
  [entryPoints.http.redirect]
    regex = "^http:\\/\\/(www.)*(example\\.com)(.*)"
    replacement = "https://www.$2/$3"
    permanent = true
  [entryPoints.https.redirect]
    regex = "^https:\\/\\/(example.com)(.*)"
    replacement = "https://www.$1/$2"
    permanent = true
[entryPoints.https.tls]
jacklin
  • 2,739
  • 1
  • 24
  • 31
0

This is how I got it to work with docker provider behind AWS ELB.

traefik container

/usr/bin/docker run --rm \
  --name traefik \
  -p 5080:80 \
  -p 5443:443 \
  -v /etc/traefik/traefik.toml:/etc/traefik/traefik.toml \
  -v /var/run/docker.sock:/var/run/docker.sock \
  traefik

traefik.toml

defaultEntryPoints = ["http", "https"]

[entryPoints]
  [entryPoints.http]
    address = ":80"

  [entryPoints.https]
    address = ":443"

docker labels

  -l traefik.enable=true \
  -l traefik.http.middlewares.redirect.redirectregex.regex="^http://(.*)" \
  -l traefik.http.middlewares.redirect.redirectregex.replacement="https://\$1" \
  -l traefik.http.routers.web-redirect.rule="Host(\`domain.com\`)" \
  -l traefik.http.routers.web-redirect.entrypoints="http" \
  -l traefik.http.routers.web-redirect.middlewares="redirect" \
  -l traefik.http.routers.web-secure.rule="Host(\`domain.com\`)" \
  -l traefik.http.routers.web-secure.entrypoints="https" \

ELB listeners

enter image description here

theRemix
  • 2,154
  • 16
  • 16
  • Seeing your answer, I think you are referring to Traefik 2.0. I think the OP asked his question while using a version of 1.7 or lower. Edit: He asked the question 2 years ago when 2.0 wasn't released. Perhaps, but I don't know, your answer can help feature requests. :) – Kenny Sep 19 '19 at 15:02
  • They're also missing the `www` part of the question. – vhs Dec 17 '20 at 12:59