I’ve been working though the forum + docs to set up Home Assistant in Docker and make it publicly available. My home lab currently uses tailscale + traefik to set up a FQDN and TLS for certs. This solution works fine for other services but for HA when I navigate to my domain root, e.g. machine.tailnet.net
it will load the auth page and after a successful auth will redirect to:
https://machine.tailnet.net/lovelace?auth_callback=1&code=XXXXXXXXXXX&storeToken=true
and show error:
Unable to connect to Home Assistant. Retrying in XX seconds…
Under the hood in dev tools I can see the hassTokens
write to session storage. And the network tab shows a 404 error under the websocket path wss://machine.tailnet.net/api/websocket
.
I created an additional issue since this differs slightly from Websockets Error 500 in traefik logs
Attached are my docker-compose files, 1x traefik + tailscale and 1x for home-assistant.
docker-compose-ts-traefik
networks:
sbridge:
name: sbridge
external: true
driver_opts:
com.docker.network.driver.mtu: 1280
attachable: true
services:
traefik:
#e.g., image: "traefik:v3.0", "traefik:3.0.0-beta1", "traefik:3.0.0-beta2", "traefik:3.0.0-beta3", "traefik:v3.0.3", "traefik:v3.1.4"
image: "traefik:3.2.3"
container_name: "traefik"
privileged: true
command:
- "--log.level=DEBUG"
- "--api.insecure=true"
- "--serversTransport.insecureSkipVerify=true"
- "--providers.docker=true"
- "--providers.docker.network=sbridge"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.watch=true"
- "--accesslog=true"
- "--accesslog.filepath=/var/log/traefik/access.log"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.has.address=:8123"
- "--entryPoints.has.http.tls=true"
- "--entrypoints.file.address=:888"
- "--entryPoints.file.http.tls=true"
- "--entryPoints.websecure.http.tls=true"
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
- "--entrypoints.web.http.redirections.entryPoint.scheme=https"
- "--entryPoints.websecure.forwardedHeaders.trustedIPs=127.0.0.1/32,10.0.10.0/24,172.0.0.0/16,172.18.0.0/24,192.168.65.1,172.18.0.9"
- "--entryPoints.web.forwardedHeaders.trustedIPs=127.0.0.1/32,10.0.10.0/24,172.0.0.0/16,172.18.0.0/24,192.168.65.1,172.18.0.9"
- "--providers.file.watch=true"
- "--providers.file.directory=/etc/traefik/dynamic"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- ${CONFIG}/traefik/config/config.yml:/config.yml
- ${CONFIG}/traefik/certs-traefik.yaml:/etc/traefik/dynamic/certs-traefik.yaml
- ${CONFIG}/tailscale/varlib/certs:/etc/certs
- /var/run/docker.sock:/var/run/docker.sock:ro
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.mydashboard.entrypoints=web,websecure'
- 'traefik.http.routers.mydashboard.rule=(Host(`${DOMAIN}`) && PathPrefix(`/proxy`) || PathPrefix(`/api`))'
- "traefik.http.routers.mydasboard.tls=true"
- 'traefik.http.routers.mydashboard.service=api@internal'
- 'traefik.http.middlewares.cors.headers.accesscontrolallowcredentials=true'
- "traefik.http.middlewares.cors.headers.accesscontrolallowmethods=GET,OPTIONS,PUT,POST,DELETE"
- 'traefik.http.middlewares.cors.headers.accesscontrolallowheaders=*'
- 'traefik.http.middlewares.cors.headers.customResponseHeaders.Access-Control-Allow-Origin=${DOMAIN}'
- "traefik.http.middlewares.cors.headers.addvaryheader=true"
- "traefik.http.middlewares.cors.headers.accesscontrolmaxage=100"
- "traefik.http.middlewares.dashboard-strip.stripprefix.prefixes=/proxy"
- "traefik.http.routers.mydashboard.middlewares=cors,dashboard-strip"
networks:
- sbridge
depends_on:
- tailscale
tailscale:
container_name: tailscale
image: tailscale/tailscale:latest
hostname: machine
privileged: true
network_mode: host
cap_add:
- NET_ADMIN
- NET_RAW
- SYS_MODULE
volumes:
- ${CONFIG}/tailscale/varlib:/var/lib
- /tmp/tailscale/tmp:/tmp
- /tmp/var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock
- /dev/net/tun:/dev/net/tun
environment:
- TS_STATE_DIR=/var/lib/tailscale
- TS_AUTH_KEY=${TS_AUTH}
- TS_SOCKET="tmp/var/run/tailscale/tailscaled.sock"
- TS_ROUTES=172.18.0.0/24,10.0.10.0/24
- TS_EXTRA_ARGS=--accept-routes
docker-compose-home-assistant
networks:
sbridge:
name: sbridge
external: true
services:
homeassistant:
image: homeassistant/home-assistant:stable
container_name: homeassistant
# network_mode: host
networks:
- sbridge
expose:
- 8123
ports:
- 8123:8123 #optional
environment:
- PGID
- PUID
- TZ
volumes:
- ${CONFIG}/homeassistant/data:/config
# devices:
# - /path/to/device:/path/to/device #optional
restart: unless-stopped
labels:
- 'traefik.enable=true'
- "traefik.docker.network=sbridge"
- 'traefik.http.routers.homeassistant.service=homeassistant'
- 'traefik.http.routers.homeassistant.rule=(Host(`${DOMAIN}`))'
- "traefik.http.services.homeassistant.loadbalancer.server.port=8123"
- 'traefik.http.routers.homeassistant.entrypoints=web,websecure'
- 'traefik.http.routers.homeassistant.tls=true'
- "traefik.http.routers.homeassistant.tls.domains[0].main=machine.tailnet.net"
- "traefik.http.services.homeassistant.loadbalancer.passhostheader=true"
- "traefik.http.middlewares.sslheader.headers.customrequestheaders.X-Forwarded-Proto=wss"
- "traefik.http.middlewares.sslheader.headers.customRequestHeaders.X-Forwarded-Host=172.18.0.19:8123"
- "traefik.http.routers.homeassistant.middlewares=sslheader"