Home Assistant with Docker and Traefik

Im hoping someone here can help. I currently have Docker running on an Ubuntu Server 18.04. I have Traefik, Home Assistant and Portainer (all running the latest versions) running at the moment. I have Traefik setup with my DuckDNS account and its set up successfully with Lets Encrypt. The trouble Im having is that the HA page doesnt load fully when attempting to access it from the DuckDNS url. I am able to access Traefik’s front end just from from the url, but when I attempt to access HA the only thing that loads is the blue bar across the top. I checked the logs in HA but there wasnt anything that talked about blocked access. Im not sure what else to check. Ill post my configs below

docker-compose.yml

version: "3.6"
services:

  portainer:
    image: portainer/portainer
    container_name: portainer
    restart: always
    command: -H unix:///var/run/docker.sock
    ports:
      - "9000:9000"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ${USERDIR}/Docker/portainer/data:/data
      - ${USERDIR}/Docker/shared:/shared
    environment:
      - TZ=${TZ}

  homeassistant:
    container_name: homeassistant
    restart: always
    image: homeassistant/home-assistant
    volumes:
      - ${USERDIR}/Docker/homeassistant:/config
      - /etc/localtime:/etc/localtime:ro
      - ${USERDIR}/Docker/shared:/shared
    ports:
      - "8123:8123"
    privileged: true
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=${TZ}
    networks:
      - traefik_proxy
      - default
    labels:
      - "traefik.enable=true"
      - "traefik.backend=homeassistant"
      - "traefik.frontend.rule=Host:${DOMAINNAME}; PathPrefixStrip: /homeassistant"
      - "traefik.port=8123"
      - "traefik.docker.network=traefik_proxy"
      - "traefik.default.protocol=http"
      - "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=example.com"
      - "traefik.frontend.headers.STSIncludeSubdomains=true"
      - "traefik.frontend.headers.STSPreload=true"
      - "traefik.frontend.headers.frameDeny=true"

  traefik:
    hostname: traefik
    image: traefik:latest
    command: --api --docker
    container_name: traefik
    restart: always
    domainname: ${DOMAINNAME}
    networks:
#      - default
      - traefik_proxy
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    environment:
      - DUCKDNS_TOKEN=${DUCKDNS_TOKEN}
    labels:
      - "traefik.enable=true"
      - "traefik.backend=traefik"
      - "traefik.frontend.rule=Host:${DOMAINNAME}; PathPrefixStrip: /traefik"
      - "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=example.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:ro
      - ${USERDIR}/Docker/traefik:/etc/traefik
      - ${USERDIR}/Docker/shared:/shared

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

traefik.toml

    logLevel = "DEBUG" #DEBUG, INFO, WARN, ERROR, FATAL, PANIC
defaultEntryPoints = ["https", "http"]

[api]
  entryPoint = "traefik"
  dashboard = true
  address = ":8080"
  usersFile = "/shared/.htpasswd"

# Force HTTPS
[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
    entryPoint = "https"
  [entryPoints.https]
  address = ":443"
    [entryPoints.https.tls]

[retry]

[file]
  watch = true
  filename = "/etc/traefik/rules.toml"

# Let's encrypt configuration
[acme]
email = "EMAIL"
storage = "/etc/traefik/acme/acme.json"
entryPoint = "https"
acmeLogging = true
# onDemand = false #create certificate when container is created
onHostRule = true
# Use a HTTP-01 acme challenge rather than TLS-SNI-01 challenge
[acme.httpChallenge]
entryPoint = "http"

[[acme.domains]]
  main = "MY_DOMAIN.duckdns.org"

# Connection to docker host system (docker.sock)
[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "MY_DOMAIN.duckdns.org"
watch = true
# This will hide all docker containers that don't have explicitly
# set label to "enable"
exposedbydefault = false

EDIT: I also tried re-creating the containers with all the - "traefik.frontend.headers. commented out but that didnt change anything.

I’m in the middle of setting this up right now to get rid of another box so I’m not at the HASS portion yet. But… you should switch your [acme] section around so you pull a wildcard cert for your duckdns domain.

# Let's encrypt configuration
[acme]
email = "[email protected]"
storage="/etc/traefik/acme/acme.json"
entryPoint = "https"
acmeLogging=true
[acme.dnsChallenge]
  provider = "duckdns"
  delayBeforeCheck = 0
[[acme.domains]]
  main = "*.yourdomain.duckdns.org"
  sans = ["yourdomain.duckdns.org"]

For others searching for “Traefik”: execellent tutorial at: https://www.smarthomebeginner.com/traefik-reverse-proxy-tutorial-for-docker/

1 Like

Hello, @fletch8527 did you find a solution? I am in the same situation as you :confused:

Yea, I solved me issue by getting a SmartThings hub instead lol. I was using HA so that I could get Google Assistant integration. I later found that I would need to restart the Google App monthly to keep the integration (I didnt pay the subscription for HA) and that was enough to push me to get something that supported the integration without a monthly fee.

Sorry I couldnt be any more help

Anyway you have take time to answer me :+1:t3: I’ll share my result of I succeed

I tested a traefik / homeassistant / portainer setup with the following setting:

traefik.toml:

debug = false

logLevel = "INFO"
defaultEntryPoints = ["https","http"]

[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
    entryPoint = "https"
  [entryPoints.https]
  address = ":443"
  [entryPoints.https.tls]
  [entryPoints.traefik]
  address = ":8080"

[retry]

[api]
debug = true

[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "yourdomain.de"
watch = true
exposedByDefault = false

[acme]
email = "[email protected]"
storage = "acme.json"
entryPoint = "https"
onHostRule = true
[acme.httpChallenge]
entryPoint = "http"

docker-compose.yml for traefik:

version: '2'

services:
  traefik:
    image: traefik:latest
    command: --api --docker
    restart: always
    ports:
      - 80:80
      - 443:443
      - 8080:8080
    networks:
      - web
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /var/opt/traefik/traefik.toml:/traefik.toml
      - /var/opt/traefik/acme.json:/acme.json
    container_name: traefik

  portainer:
    image: portainer/portainer:latest
    command: -H unix:///var/run/docker.sock
    container_name: portainer
    restart: always
    ports:
      - 9000:9000
    networks:
      - web
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /var/opt/portainer:/data
    labels:
      - "traefik.backend=portainer"
      - "traefik.enable=true"
      - "traefik.frontend.rule=Host:yourdomain.de" # URL entsprechend anpassen!
      - "traefik.port=9000"
      - "traefik.docker.network=web"


networks:
  web:
    external: true

and last but not least the docker-compose.yml for homeassistant:

version: '2'
services:
  homeassistant:
    container_name: home-assistant
    image: homeassistant/home-assistant:stable
    volumes:
      - /var/opt/homeassistant/config:/config
    environment:
      - TZ=Europe/Berlin
    restart: always
    ports:
      - 8123:8123
    networks:
      - web
    labels:
      - "traefik.backend=homeassistant"
      - "traefik.enable=true"
      - "traefik.frontend.rule=Host:subdomain.yourdomain.de" # URL entsprechend anpassen!
      - "traefik.port=8123"
      - "traefik.docker.network=web"

networks:
  web:
    external: true

This worked fine for me and will go live soon (right now I am still on NGINX, but I find traefik way more easy). I don’t use duckdns, I have my own domain (from Strato).

Here is my config - based on Traefik 2.x with DuckDNS and LetsEncrypt.

  reverse-proxy:
    # The official v2.0 Traefik docker image
    container_name: reverse_proxy
    image: traefik:latest
    # Enables the web UI and tells Traefik to listen to docker
    command: --api.insecure=true --providers.docker --entrypoints.web.address=:80 --entrypoints.websecure.address=:443 [email protected] --certificatesresolvers.le.acme.storage=/acme.json --certificatesresolvers.le.acme.dnschallenge=true --certificatesresolvers.le.acme.dnschallenge.provider=duckdns  --metrics.prometheus=true --metrics.prometheus.buckets="0.100000, 0.300000, 1.200000, 5.000000" --metrics.prometheus.entrypoint='metrics' --metrics.prometheus.addEntryPointsLabels=true --metrics.prometheus.addServicesLabels=true --entryPoints.metrics.address=:8282



  homeassistant:
    image: homeassistant/home-assistant:latest

    restart: always

    ports:
      - 8123:8123
    volumes:
      - /opt/docker/home-assistant:/config
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock
    links:
      - mysql
      - ha_dockermon
    labels:
      - traefik.http.routers.homeassistant.entrypoints=websecure
      - traefik.http.routers.homeassistant.rule=Host(`ha.xxxxx.duckdns.org`)
      - traefik.http.services.homeassistant.loadbalancer.server.port=8123
      - traefik.http.routers.homeassistant.tls.certresolver=le

Just curious… Why are you giving hass access to your docker socket?

[quote=" [sj3fk3], post:9, topic:85738"]
Just curious… Why are you giving hass access to your docker socket?
[/quote]

Because I’m sleeping :slightly_smiling_face:… Copy/paste error :slight_smile: thanks!

1 Like

This works also for me, but I have added a fixed IP address to both containers in order to use the ip-ban-list from HA. Here is my code:

version: '3.3'

services:
  traefik:
    image: traefik:latest
    command: 
      #- "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.myhttpchallenge.acme.httpchallenge=true"
      - "--certificatesresolvers.myhttpchallenge.acme.httpchallenge.entrypoint=web"
      #- "--certificatesresolvers.myhttpchallenge.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
      - "[email protected]rdomain.de"
      - "--certificatesresolvers.myhttpchallenge.acme.storage=/acme.json"
    ports:
      - 80:80
      - 443:443
      - 8080:8080
    networks:
      web:
        ipv4_address: 172.30.0.2
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    container_name: traefik

  homeassistant:
    container_name: homeassistant
    image: homeassistant/home-assistant:0.104.3
    volumes:
      - /home/daniel/docker/homeassistant/config:/config
    environment:
      - TZ=Europe/Berlin
    restart: unless-stopped
    ports:
      - 8123:8123
    networks:
      web:
        ipv4_address: 172.30.0.3
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.homeassistant.rule=Host(`yourdomain.homeassistant.de`)"
      - "traefik.http.routers.homeassistant.entrypoints=websecure"
      - "traefik.http.routers.homeassistant.tls.certresolver=myhttpchallenge"
      - "traefik.http.services.homeassistant.loadbalancer.server.port=8123"

networks:
  web:
    driver: bridge
    ipam: 
      driver: default
      config: 
        - subnet: 172.30.0.0/24

And in configuration.yaml:

http:
  base_url: http://yourdomain.homeassistant.de
  use_x_forwarded_for: true
  trusted_proxies: 172.30.0.2
  ip_ban_enabled: true
  login_attempts_threshold: 3