I recently switched the hosting provider of my personal blog from Netlify to my custom stack (Docker, Portainer and Traefik) and I quickly noticed that I had forgotten something in my migration: the redirection from benjaminrancourt.ca to www.benjaminrancourt.ca... 😟
Even though my website contains canonical link elements and the same website was served for both domains, it bothered me that I lost this little feature... So naturally, I started searching on the internet for how to implement this redirection with Traefik. 😇
Unfortunately, although the Traefik community has asked similar questions several times in the past (5425, 6458, 6813, 8409, 7428, 8976 and 10711), none of the suggested solutions worked for my environment... 😢
Most of them define a new middleware with labels
, but I was looking for a more global solution that I could apply only to some sites. I considered that it was not very efficient to create a new middleware to resolve the redirect for every website that needs it... 🤔
In particular, the solutions were not all the same, but they were similar to each other:
- "traefik.http.middlewares.wwwtohttps.redirectregex.regex=^https?://(?:www\\.)?(.+)"
- "traefik.http.middlewares.wwwtohttps.redirectregex.replacement=https://$${1}"
- "traefik.http.middlewares.wwwtohttps.redirectregex.permanent=true"
Some of them escape the period twice (\\.
), while others escape it only one (\.
) and others don't escape it (.
)... There were also two variations for the double dollar sign ($${1}
and ${1}
)... Which one is correct? A little bit confusing, right? 😵
So I started trying out several combinations and after breaking my live website a couple of times, I finally got it to work! Below is the solution that works for me with Traefik v2.5.1. 🎉
Solution
As I said above, I define the middlewares only once, in the dynamic configuration file:
# Traefik dynamic configuration file
# See https://doc.traefik.io/traefik/getting-started/configuration-overview/#the-dynamic-configuration
http:
middlewares:
# Redirect non-www URLs to their www equivalent
# Use with traefik.http.routers.myRouter.middlewares: "redirect-non-www-to-www@file"
redirect-non-www-to-www:
# Redirect a request from an url to another with regex matching and replacement
redirectregex:
# Apply a permanent redirection (HTTP 301)
permanent: true
# The regular expression to match and capture elements from the request URL
regex: "^https?://(?:www\\.)?(.+)"
# How to modify the URL to have the new target URL
replacement: "https://www.${1}"
# Redirect www URLs to their non-www equivalent
# Use with traefik.http.routers.myRouter.middlewares: "redirect-www-to-non-www@file"
redirect-www-to-non-www:
# Redirect a request from an url to another with regex matching and replacement
redirectregex:
# Apply a permanent redirection (HTTP 301)
permanent: true
# The regular expression to match and capture elements from the request URL
regex: "^https?://www\\.(.+)"
# How to modify the URL to have the new target URL
replacement: "https://${1}"
You might have already noticed how to use them in my comments, but it only takes to add a new label to your docker-compose.yml
file:
traefik.http.routers.myRouter.middlewares: "redirect-non-www-to-www@file"
And if your router already has a middleware, just add the middleware you want by separating them with a comma (,
) like another-middleware,redirect-non-www-to-www@file
.
So that's it, you can now redirect your websites to www or non-www. 🤗
Top comments (0)