Avoid network_mode: host for Docker

I finally got this working too @Lapatoc’s method; docker running with --host, the port mapped, and adding the traefik provider manually.
Make sure to also add [file] to traefik.toml, to enable the non-docker traefik provider.

The log doesn’t seem to load in developer tools -> info -> log. Does that work for anyone that is running with net=host and static backend configuration?

It works if I directly access it via IP

Could you please share your complete config? Do you have a docker-compose.yml and a traefik.toml right?

Thanks!

I use Ansible instead of docker-compose, which is fairly similar in terms of syntax (both YAML), but not the same.
You can probably figure out how your docker-compose.yml would look like, by looking at my Ansible config though:

- name: "Create Home Assistant container"
  docker_container:
    name: homeassistant
    image: homeassistant/home-assistant
    privileged: yes
    volumes:
      - /opt/homeassistant/config:/config
    ports:
      - "8123:8123"
    network_mode: host
    restart_policy: always
    restart: yes
    state: started
    labels:
      traefik.enable: "false"

My traefik.toml looks like this:

debug = false
logLevel = "INFO"

defaultEntryPoints = ["http", "https"]

[api]
# traefik dashboard
  entryPoint = "traefik"
  dashboard = true

[entryPoints]
  [entryPoints.traefik]
    address = ":8080"

  [entryPoints.http]
    address = ":80"
# forward all HTTP traffic to HTTPS
    [entryPoints.http.redirect]
      entryPoint = "https"

  [entryPoints.https]
  address = ":443"
    [entryPoints.https.tls]

# watch Docker, when new containers are created with label create mapping.
[docker]
  endpoint = "unix:///var/run/docker.sock"
  domain = "<your domain>"
  watch = true

[file]
[frontends]
  [frontends.frontend-home-assistant]
  backend = "backend-home-assistant"
    [frontends.frontend-home-assistant.routes.test_1]
    rule = "Host: home.<your-domain>"

[backends]
  [backends.backend-home-assistant]
    [backends.backend-home-assistant.servers.server1]
    url = "http://<your HA IP>:8123"

[acme]
email = "<your email>"
storage = "acme.json"
caServer = "https://acme-v02.api.letsencrypt.org/directory"
entryPoint = "https"
  [acme.dnsChallenge]
  provider = "transip"
  
[[acme.domains]]
# note: wild cards like the one below only work with DNS challenge
  main = "*.your-domain.com"

Note, I’m using a DNS challenge for LetsEncrypt, you should probably replace that for a HTTP challenge, unless there’s a reason for you to use a DNS challenge. See Traefik examples.

Thank you so much for the tidbit about the [file] parameter! I have been going mad over the past 2 days wondering why I could not get Traefik to read the config from my toml file! This was the ticket.

Has anyone managed to get this working with the iOS App? I get numerous authentication errors and cannot enable notifications. I did find some extra Traefik parameters on www.smarthomebeginner.com however not having much luck with these nor the default configurations above.

1 Like

Could it be possible to share you docker-compose file?

I’ll try and break it down:

version: "3.6"

services:

  hass:
    container_name: 'hass'
    image: 'homeassistant/home-assistant:latest'
    restart: 'unless-stopped'
    ports:
      - 8123:8123
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ./volumes/home-assistant:/config
      - /dev/ttyACM0:/dev/ttyACM0
    environment:
      - TZ=Europe/London
    privileged: true
    networks:
      macvlan:
          ipv4_address: 192.168.1.22
      traefik_proxy:
      default:
    labels:
      - "traefik.enable=true"
      - "traefik.frontend.rule=Host:hass.xxx.com"
      - "traefik.port=8123"
      - "traefik.docker.network=traefik_proxy"
      - "traefik.frontend.headers.SSLRedirect=true"
      - "traefik.frontend.headers.STSSeconds=315360000"
      - "traefik.frontend.headers.browserXSSFilter=true"
      - "traefik.frontend.headers.contentTypeNosniff=true"
      - "traefik.frontend.headers.forceSTSHeader=true"
      - "traefik.frontend.headers.SSLHost=xxx.com"
      - "traefik.frontend.headers.STSIncludeSubdomains=true"
      - "traefik.frontend.headers.STSPreload=true"
      - "traefik.frontend.headers.frameDeny=true"

here are the networks:

networks:
  traefik_proxy:
    external:
      name: traefik_proxy
  macvlan:
    external: true
  default:
    driver: bridge

here is one of the other containers:

  node-red:
    container_name: 'node-red'
    depends_on:
      - hass
    image: 'nodered/node-red-docker:v8'
    restart: 'unless-stopped'
    hostname: 'node-red.xxx.com'
    user: 'root'
    ports:
      - 1880:1880
    volumes:
      - ./volumes/node-red:/data
    networks:
      - traefik_proxy
      - default
    labels:
      - "traefik.enable=true"
      - "traefik.backend=node-red"
      - "traefik.frontend.rule=Host:node-red.xxx.com"
      - "traefik.port=1880"
      - "traefik.docker.network=traefik_proxy"
      - "traefik.frontend.headers.SSLRedirect=true"
      - "traefik.frontend.headers.STSSeconds=315360000"
      - "traefik.frontend.headers.browserXSSFilter=true"
      - "traefik.frontend.headers.contentTypeNosniff=true"
      - "traefik.frontend.headers.forceSTSHeader=true"
      - "traefik.frontend.headers.SSLHost=xxx.com"
      - "traefik.frontend.headers.STSIncludeSubdomains=true"
      - "traefik.frontend.headers.STSPreload=true"
      - "traefik.frontend.headers.frameDeny=true"

Here is the mtacvlan setup from my ubuntu docker host. It creates me a /28 network range I can use for docker containers on my local network:

docker network create -d macvlan --subnet=192.168.1.0/24 --ip-range=192.168.1.16/28 --gateway=192.168.1.1 -o parent=ens33 macvlan

And here is the traefik:

version: '2'

services:
  traefik:
    image: traefik:latest
    restart: always
    domainname: xxx.com
    dns: 8.8.8.8
    ports:
      - 80:80
      - 443:443
#      - 7070:8080
    networks:
      - default
      - traefik_proxy
    environment:
      - [email protected]
      - CLOUDFLARE_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    labels:
      - "traefik.enable=true"
      - "traefik.backend=traefik"
      - "traefik.frontend.rule=Host:traefik.xxxx.com"
#      - "traefik.frontend.rule=Host:${DOMAINNAME}; PathPrefixStrip: /traefik"
      - "traefik.frontend.auth.basic.users=yyyyyy:$$xxxxxxxxxxxxxxxxxxxxx"
      - "traefik.port=8080"
      - "traefik.docker.network=traefik_proxy"
      - "traefik.frontend.headers.SSLRedirect=true"
      - "traefik.frontend.headers.STSSeconds=315360000"
      - "traefik.frontend.headers.browserXSSFilter=true"
      - "traefik.frontend.headers.contentTypeNosniff=true"
      - "traefik.frontend.headers.forceSTSHeader=true"
      - "traefik.frontend.headers.SSLHost=xxx,com"
      - "traefik.frontend.headers.STSIncludeSubdomains=true"
      - "traefik.frontend.headers.STSPreload=true"
      - "traefik.frontend.headers.frameDeny=true"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./volumes/traefik:/etc/traefik
      - ./volumes/shared:/shared
    container_name: traefik

networks:
  traefik_proxy:
    external:
      name: traefik_proxy
  default:
    driver: bridge

The big challenge with mtacvlan is that the container cannot talk to the host on the mtacvlan network. I have got around this by using the traffic_proxy network to hook the hass front end into traefik, using the default network to allow the hass containers including db (not shown), influxdb (not shown) etc… to talk to each other .

I might try and simplify this by running every container in the mtacvlan network. The /28 gives me 16 usable addresses on the LAN for containers, I could increase this with a /27 or event a /26.

Not sure I have explained this entirely well.

1 Like

Thanks for the fast reply

When I do the changes and validated the config with docker-compose config, I get the following error: services.homeassistant.networks contains {"macvlan": {"ipv4_address": "192.168.0.200"}}, which is an invalid type, it should be a string

Config: https://pastebin.com/CtZ0ieB3

I removed the ‘ipv4_address’ line and managed to get it started, though HA isn’t able to connect to any thing.

How did you define the mtacvlan network.

Adrian

I used the following command:

docker network create -d macvlan --subnet=192.168.0.0/24 --ip-range=192.168.0.200/29 --gateway=192.168.0.1 -o parent=eth0 macvlan

I’m unable to ping to the ip of the docker server. The rest same to work as intended.

In order to make the port available on the macvlan IP I followed this guide: https://docs.docker.com/v17.09/engine/userguide/networking/get-started-macvlan/#macvlan-bridge-mode-example-usage

There is a requirement for mtacvlan to have your adapter in promiscuous mode. How to do that will depend on your setup

Did you find a solution to this, particularly a way to use bluetooth inside a container without host networking? I run my containers with macvlan networking, so using host networking isn’t an option for me.

2 Likes

Thanks! Nice trick to get this to work.

Did you manage to get this working with the iOS app ? I’m getting a homeassistant | 2019-09-17 18:48:27 WARNING (MainThread) [homeassistant.components.http.ban] Login attempt or request with invalid authentication from 172.18.0.2

Even though Traefik (172.18.0.2) is in trusted proxies

Most of the replies in this thread are about traefik v1.x, here is my config for v2.1 in case anyone finds it useful.

Home assistant still uses network_mode: host and runs on port 8123 but traefik accesses it by its local IP address.

docker-compose.yml
version: "3"

# This network is not required for home-assistant but for other docker containers
networks:
  proxy:
    external: true

services:
  reverse-proxy:
    image: traefik:v2.1
    networks:
      - proxy
    ports:
      - "80:80"
    volumes:
      # So that Traefik can listen to the Docker events
      - /var/run/docker.sock:/var/run/docker.sock
      # Traefik config files
      - ./traefik.toml:/etc/traefik/traefik.toml
      - ./dynamic_conf.toml:/etc/traefik/dynamic_conf.toml
traefik.toml
[providers.file]
  filename = "/etc/traefik/dynamic_conf.toml"
dynamic_conf.toml
[http]
  [http.routers]
    [http.routers.home-assistant]
      service = "home-assistant"
      rule = "PrefixPath(`/`)"

[http.services]
  [http.services.home-assistant.loadBalancer]
    [[http.services.home-assistant.loadBalancer.servers]]
      url = "http://IP_ADDRESS:8123/"

If all went well you should be able to access home assistant at http://IP_ADDRESS:80. Tweak the rule in dynamic_conf.toml to your preferred forwarding setting. Refer to traefik’s docs for a list of available matchers.

1 Like

That can be solved with adding this to your traefik service in the compose file:

extra_hosts:
      - "host.docker.internal:host-gateway"

That way you can keep the HA in host mode because it enables you to communicate with the Docker Host. Then you can just create a network for your other containers (including traefik).

1 Like

Thanks for this. The extra_hosts addition works brilliantly. I was running into issues with integrations (konnected, ubiquiti etc) when attempting to run HA out of hosts mode yet wanted to use traefik to handle web facing access.