How to redirect an entire domain to another in Traefik

How to redirect an entire domain to another in Traefik
Photo by Nick Fewings / Unsplash

Redirecting an entire domain is a common requirement that is surprisingly not straight forward in Traefik. When updating this blog to use Traefik instead of Nginx I spent too many hours scouring documentation and Stack Overflow trying to determine how to redirect all of nicholashairs.com to https://www.nicholashairs.com.

I hope this short guide makes it's way to your screen when it's needed.

Configuration

Our base configuration is straight forward. We define the standard HTTP and HTTPS listeners, our TLS configuration using Lets Encrypt, and the location of our site specific configuration files.

providers:
  file:
    directory: /etc/traefik/config
    watch: true

entrypoints:
  http:
    address: ":80"
  https:
    address: ":443"

certificatesResolvers:
  default:
    acme:
      storage: /etc/traefik/acme.json
      email: youremail@example.com
      tlsChallenge: {}
      httpChallenge:
        entryPoint: http

/etc/traefik/traefik.yml

For our site config we actually need to define 4 different routers.

  • HTTP nicholashairs.com
  • HTTPS nicholashairs.com
  • HTTP www.nicholashairs.com
  • HTTPS www.nicholashairs.com
http:
  routers:
    naked-http:
      rule: "Host(`nicholashairs.com`)"
      middlewares:
        - www-redirect
      service: noop@internal

    naked:
      rule: "Host(`nicholashairs.com`)"
      tls:
        certResolver: default
      middlewares:
        - www-redirect
      service: noop@internal

    blog-http:
      rule: "Host(`www.nicholashairs.com`)"
      service: noop@internal
      middlewares:
        - redirect-https

    blog:
      rule: "Host(`www.nicholashairs.com`)"
      tls:
        certResolver: default
      service: ghost

  services:
    ghost:
      loadBalancer:
        servers:
          - url: "http://127.0.0.1:8080"

  middlewares:
    redirect-https:
      redirectScheme:
        scheme: https
        permanent: true
    www-redirect:
      redirectRegex:
        regex: "^.*$"
        replacement: "https://www.nicholashairs.com/"
        permanent: false

/etc/traefik/config/blog.yml

Although almost identical, we need both a HTTP and a HTTPS router for nicholashairs.com as despite what it may appear (including in the Traefik Dashboard), a router with a TLS configuration will only ever listen using HTTPS, if you need both HTTP and HTTPS you will need two routers.

Although we could re-use the redirect-https middleware on the naked-http router, our www-redirect middleware will already redirect to HTTPS saving us an extra trip when navigating to http://nicholashairs.com.

All routers require a service but since we are redirecting all requests on the naked domain routers, we can simply use the noop@internal router.

Similar to the naked domain, the blog domain needs to routers in order to be able to redirect HTTP to HTTPS. However this time we use the redirectScheme middleware instead of the redirectRegex middleware as we wish to preserve the entire URL when making the redirect.


That's it. That's the guide. I hope it helps.