Traefik routing to both known and wildcard subdomain on a single domain

Jason Raimondi picture Jason Raimondi · Sep 19, 2018 · Viewed 9.3k times · Source

Is it possible to have a wildcard subdomain that does not include a specific subdomain?

*.mydomain.com OK
login.mydomain.com SKIP

I cannot access my login container when using a wildcard on my app container. Below is an image of what I am trying to accomplish. (the traffic logo should technically be between the list of routes and the containers)

Traefik Example Image

The following configuration does not work if the rule HostRegexp:{subdomain:[a-z]+}.${HOST_DOMAIN} is included.

This configuration successfully works after removing the host regex for everything EXCEPT the wildcard subdomains.

services:
    traefik:
        image: traefik
        volumes:
        - /var/run/docker.sock:/var/run/docker.sock:ro
        - .traefik.toml:/etc/traefik/traefik.toml:ro
        ports:
        - "80:80"
        - "443:443"

    api:
        image: my-api-image
        labels:
        - "traefik.enable=true"
        - "traefik.port=80"
        - "traefik.frontend.rule=Host:app.${HOST_DOMAIN}; PathPrefix: /api"

    app:
        image: my-app-image
        labels:
        - "traefik.enable=true"
        - "traefik.port=80"
        - "traefik.frontend.rule=Host:app.${HOST_DOMAIN}"
        - "traefik.frontend.rule=HostRegexp:{subdomain:[a-z]+}.${HOST_DOMAIN}" # this second rule overwrites the first rule and I am aware of that, I am just showing what rules i've tried :)

    login:
        image: my-login-image
        labels:
        - "traefik.enable=true"
        - "traefik.port=80"
        - "traefik.frontend.rule=Host:login.${HOST_DOMAIN}"

My problem is currently with the app container. I am getting a bad gateway if I have the following included as a frontend rule:

"traefik.frontend.rule=HostRegexp:{subdomain:[a-z]+}.${HOST_DOMAIN}"

I also tried leaving the above under app, and removing the following without any luck:

"traefik.frontend.rule=Host:app.${HOST_DOMAIN}"

Any suggestions or ideas would be appreciated. Thanks.

Edit:

Rewording this a bit.

Answer

Andrew Savinykh picture Andrew Savinykh · Sep 20, 2018

So this is what worked for me:

version: '2'

services:
    traefik:
        image: traefik
        volumes:
        - /var/run/docker.sock:/var/run/docker.sock:ro
        # I removed your traefik.toml as you did not specify what is in it, so it's irrelevant
        ports:
        - "80:80"
        - "443:443"
        # Very helpful for debugging dashboard can be seen at http://localhost:8080 if the port is exposed
        - "8080:8080"
        labels:
        # You don't want traefik trying to create proxy for itself
        - "traefik.enable=false"
        # Since we have no traefik.toml any longer, let's put the essentials on the command line
        command: ["--api","--docker"]
    app:
        # this is my test image of a web server that dumps request back to the caller
        image: andrewsav/talkback
        # the hostname is a part of the dump, so let's specify something that we can relate to
        hostname: "app"
        labels:
        # note that you want this frontened to match the last. otherwise it will match login.${HOST_DOMAIN}"
        - "traefik.frontend.priority=1"
        - "traefik.enable=true"
        - "traefik.port=80"
        - "traefik.frontend.rule=HostRegexp:{subdomain:[a-z]+}.${HOST_DOMAIN}"
    api:
        image: andrewsav/talkback
        hostname: "api"
        labels:
        # this frontend needs to match before the one above
        - "traefik.frontend.priority=2"
        - "traefik.enable=true"
        - "traefik.port=80"
        - "traefik.frontend.rule=Host:app.${HOST_DOMAIN}; PathPrefix: /api"
    login:
        image: andrewsav/talkback
        hostname: "login"
        labels:
        - "traefik.frontend.priority=3"
        - "traefik.enable=true"
        - "traefik.port=80"
        - "traefik.frontend.rule=Host:login.${HOST_DOMAIN}"

A few notes:

  • Bad Gateway indicates that the endpoint you told traefik to talk to is not listening. Look at at the dashboard and find out which backend is used and double check that ip/port is correct.
  • You have to use priorities for matching order. Please refer to the documentation on how it works.