Route to local IP or DockerHost

I am trying to get Home Assistant setup on my home server. I need it set to network mode Host to allow for auto discovery of services, but I need it on my "proxied" network in order for traefik to proxy to it.

I've seen traefik.docker.network, but I can't get that to work.

So mainly I need to proxy my 'home-assistant.domain.com" to resolve to 192.168.1.250:8000. (192.168.1.250 is my docker hosts address)

I have some other use cases for this too. To basically just tell traefik where to route to, and I feel like I'm just missing something. Hopefully someone can have an easy answer.

Hi @NickBolles, if my understanding of your architecture is correct, by starting the application "home assistant" using Docker's "host" network mode, then Traefik cannot guess the IP to reach the container from the label of the containers.

So you need to fall back on defining the Traefik's frontend and Traefik's backend configuration object using the "file provider". Be aware that you can have both "File" and "Docker" provider enabled at the same time: it means that if you want Traefik to keep routing to other docker containers that are using "labes" for configuration, your setup will still work.

Here is a working example, with an nginx webapp inside docker, and a "whoami" app bound to the host network:

  • docker-compoe.yml:
version: '3.7'

services:
  reverse-proxy:
    image: traefik:1.7.12-alpine
    command:
      - --docker
      - --file
      - --file.filename=/rules.toml
      - --file.watch=true
    ports:
      - "80:80"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./rules.toml:/rules.toml
    labels:
      - "traefik.enable=false" # Traefik WebUI is disabled: no need to configure routing

  webapp-host:
    image: containous/whoami
    # Listen on port 8000 of the Docker Host
    command: --port=8000
    network_mode: host
    labels:
      - "traefik.enable=false" # Disable auto-discovery: rely on file provider instead

  webapp-classic:
    image: nginx:1.10-alpine
    labels:
      - "traefik.frontend.rule=Host:localhost;PathPrefixStrip:/classic"
  • rules.toml:
[frontends]
  [frontends.webapp-host-front]
  backend = "webapp-host-back"
    [frontends.webapp-host-front.routes.webapp-host-hostroute]
    rule = "Host:localhost"
    [frontends.webapp-host-front.routes.webapp-host-pathroute]
    rule = "PathPrefixStrip:/host"


[backends]
  [backends.webapp-host-back]
    [backends.webapp-host-back.servers.host1]
    url = "http://172.17.0.1:8000" # IP come from "docker run --rm -ti alpine ip route | grep -i default"

As the matter of reference, the "File Provider" reference documentation is found here: https://docs.traefik.io/v1.7/configuration/backends/file/.

Wow! Thanks for the detailed response! That looks like it'll work just fine. (Especially because I think I'm going to transition away from the home Assistant docker to a rpi)

I guess my next question is (for future reference), I thought you could enable backends in your rules file and then tell the docker container to use that backend via a label. I was trying to do that and couldn't get it to work.

I lean towards labels because I use unraid, which has a container orchestrator built in, so labels are a little easier to work with.

Oh, I did not know about unraid until today, thanks for this!

I confirm that you can get rid of defining backends and frontends if you have docker containers created with the right labels (except for the edge case of "network mode" :slight_smile: ).

As I understand the uraid doc, you should be able to define labels on their system for the container it's managing, so you can totally benefits from the dynamci configuration I presetned in the earlier docker-compose.yml, as Traefik only watches for the docker engine. So whatever system is used for launching containers (docker CLI, docker-compose CLI, Terraform, Nomad, etc.), labels cans till be used.

Yea, for sure. I'm using labels for a bunch of services. I'm asking specifically about adding a label for the backend to use.

So if I have this in my rules.toml

[backends]
  [backends.webapp-host-back]
    [backends.webapp-host-back.servers.host1]
    url = "http://172.17.0.1:8000"

Can I add a label to a container to use that backend?

So from your example docker.compose

webapp-host:
    image: containous/whoami
    # Listen on port 8000 of the Docker Host
    command: --port=8000
    network_mode: host
    labels:
      - "traefik.enable=true" #change this to true to enable traefik
      -  "traefik.frontend.rule=Host:localhost,PathPrefixStrip:/host" #match routes for localhost/host (can't remember the delim , or ; for and??)
      - "traefik.backend=webapp-host-back"

Even cooler would be to define the backend and the port. So that I could have a generic backend "host" and define the port to route to on a service by service basis.
So home Assistant would have a backend of "host" and a port of 8123, but another service, say webapp-host could have a backend of host and a port of 8080

Hi @NickBolles, Alas with Traefik v1.x, you cannot mix labels and file provider definitions.
For example, the documentation states that the label traefik.backend overrides the generated name of the backend associated to this container (reference: https://docs.traefik.io/v1.7/configuration/backends/docker/#on-containers).

It means that, by watching Docker, Traefik will create the object "backend" and will file it with the IP and port of the container automatically.

However, you might be interested in checking the "Docker template" (e.g. the Go+sprig template used by Traefik to generate the configuration coming from the Docker labels: https://github.com/containous/traefik/blob/v1.7/templates/docker.tmpl.

Why this? Because you can totally define your own template with --docker. filename=xxx, so you could be able to achieve the case you describe here: passing only a few "custom labels" (port, frontend rule) that would rendered to the exact configuration file you want :slight_smile:

(reference. https://docs.traefik.io/v1.7/configuration/backends/docker/)

Woah. I haven't seen that before. That would actually be perfect for my usecase because I use pretty much the same labels every time, and using for this would be another plus! Thank you very much!

1 Like