Search code examples
traefik

How to make content to show on both www and non-www urls using traefik


Thank you for showing interest and I was in a hurry. Any help would be great. At present users were not able to reach www.example.com but they can reach example.com.

Either one of them is fine:

1) Accepts all traffic from WWW and non-www urls and serve same content.

2) Redirect users from WWW to non-www url to display content.

Note: Let's Encrypt is used

My present config is

traefik.toml

defaultEntryPoints = ["http", "https"]

[entryPoints]
  [entryPoints.dashboard]
    address = ":8080"
    [entryPoints.dashboard.auth]
      [entryPoints.dashboard.auth.basic]
        users = ["admin:key"]
  [entryPoints.http]
    address = ":80"
      [entryPoints.http.redirect]
      regex = "^https://www.(.*)"
      replacement = "https://$1"
      permanent=true
        entryPoint = "https"
  [entryPoints.https]
    address = ":443"
      [entryPoints.https.tls]

[api]
entrypoint="dashboard"

[acme]
email = "[email protected]"
storage = "acme.json"
entryPoint = "https"
onHostRule = true
  [acme.httpChallenge]
  entryPoint = "http"
[[acme.domains]]
  main = "*.example.com"
  sans = ["example.com"]
[[acme.domains]]
  main = "*.example1.com"
  sans = ["example1.com"]
[docker]
domain = "example.com"
watch = true
network = "proxy"`

docker-compose.yml:

 version: '2'
services:
  traefik:
    image: traefik
    restart: always
    command: --docker
    ports:
      - 80:80
      - 443:443
    networks:
      - proxy
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - $PWD/traefik.toml:/traefik.toml
      - $PWD/acme.json:/acme.json
    container_name: trefik
    environment:
      DO_AUTH_TOKEN: TOKEN
    labels:
      - traefik.frontend.rule=Host:monitor.example.com
      - traefik.port=8080
  example1:
    image: wordpress:4.7.5-apache
    restart: always
    environment:
      WORDPRESS_DB_PASSWORD: something
    labels:
      - traefik.backend=example1
      - traefik.frontend.rule=Host:example1.com
      - traefik.docker.network=proxy
      - traefik.port=80
    networks:
      - internal
      - proxy
    depends_on:
      - mysql
  example:
   image: tutum/apache-php
   restart: always
   labels:
     - traefik.backend=example
     - traefik.frontend.rule=Host:example.com, www.example.com
     - traefik.docker.network=proxy
     - traefik.port=80
   networks:
     - internal
     - proxy

Edit #1:

Your config Redirects:

http://example.com => [no redirect]

https://www.example.com => [timeout]

http://www.example.com => [timeout]

http://example.com => [no redirect]

My Config Redirects:

http://example.com => https://example.com:443/

https://www.example.com => [timeout]

http://www.example.com => [timeout]

http://example.com => https://example.com:443/

Solution

    1. You cannot use redirect entrypoint and regex at the same on the same entrypoint.

    Please note that regex and replacement do not have to be set in the redirect structure if an entrypoint is defined for the redirection (they will not be used in this case).

    https://docs.traefik.io/v1.7/configuration/entrypoints/#redirect-http-to-https

    1. The wildcard certficates cannot be obtain with the HTTP challenge: https://docs.traefik.io/v.7/configuration/acme/#wildcard-domains
      You have to use the DNS challenge https://docs.traefik.io/v1.7/configuration/acme/#dnschallenge (edited) and before you ask: you cannot use both (HTTP challenge and DNS challenge) at the same time.

    Edit

    I will illustrate the redirections with 2 simple configurations (self-signed certificates instead of acme but it's the same thing).

    Those 2 configurations works without any changes, you only need to do docker-compose up.

    Note that redirection has no influence on the HTTP challenge (ACME).

    Strip www and HTTPS redirection

    The goal:

    $ curl --insecure -L http://www.whoami.docker.localhost
    # http://www.whoami.docker.localhost -> https://whoami.docker.localhost
    
    $ curl --insecure -L https://www.whoami.docker.localhost
    # https://www.whoami.docker.localhost -> https://whoami.docker.localhost
    
    $ curl --insecure -L http://whoami.docker.localhost
    # http://whoami.docker.localhost -> https://whoami.docker.localhost
    
    $ curl --insecure -L https://whoami.docker.localhost
    # https://whoami.docker.localhost -> https://whoami.docker.localhost
    

    I. Example without TOML: (docker-compose.yml)

    version: "3"
    
    services:
      reverseproxy:
        image: traefik:v1.7.8
        command:
          - --logLevel=INFO
          - --defaultentrypoints=http,https
          - --entrypoints=Name:http Address::80 Redirect.Regex:^http://(?:www\.)?(.+) Redirect.Replacement:https://$$1 Redirect.Permanent:true
          - --entrypoints=Name:https Address::443 TLS Redirect.Regex:^https://www\.(.+) Redirect.Replacement:https://$$1 Redirect.Permanent:true
          - --docker
          - --docker.domain=docker.localhost
        ports:
          - "80:80"
          - "443:443"
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock
    
      whoami:
        image: containous/whoami
        labels:
          - "traefik.frontend.rule=Host:whoami.docker.localhost"
    

    II. Example with TOML: (docker-compose.yml + traefik.toml)

    version: "3"
    
    services:
      reverseproxy:
        image: traefik:v1.7.8
        ports:
          - "80:80"
          - "443:443"
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock
          - ./traefik.toml:/traefik.toml
    
      whoami:
        image: containous/whoami
        labels:
          - "traefik.frontend.rule=Host:whoami.docker.localhost"
    
    defaultEntryPoints = ["http", "https"]
    
    [entryPoints]
      [entryPoints.http]
        address = ":80"
        [entryPoints.http.redirect]
          regex = "^http://(?:www\.)?(.+)"
          replacement = "https://$1"
          permanent = true
      [entryPoints.https]
        address = ":443"
        [entryPoints.https.redirect]
          regex = "^https://www\\.(.+)"
          replacement = "https://$1"
          permanent = true
        [entryPoints.https.tls]
    
    [api]
    
    [docker]
    domain = "docker.localhost"