DEV Community

Cover image for How to redirect from non-www to www with Traefik
Benjamin Rancourt
Benjamin Rancourt

Posted on • Originally published at benjaminrancourt.ca on <time datetime="2021-09-02T23:15:00Z" class="date-no-year">Sep 2</time>

How to redirect from non-www to www with Traefik

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"

Enter fullscreen mode Exit fullscreen mode

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}"

Enter fullscreen mode Exit fullscreen mode

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"

Enter fullscreen mode Exit fullscreen mode

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. 🤗

Discussion (0)