Traefik detects container only if port is exposed in docker compose

I'm using a docker compose to start traefik and bunch of other containers. Home assistant container is the only one that is not detected if I disable exposing the ports. I can verify from traefik dashboard that home assistant rule only gets created if I leave the port exposed. Here is the docker-compose.yml:

version: "2.1"

services:
  # Traefik
  traefik:
    image: traefik:2.3.2
    container_name: traefik
    environment:
      - NAMECHEAP_API_USER=${NAMECHEAP_API_USER}
      - NAMECHEAP_API_KEY=${NAMECHEAP_API_KEY}
    command:
    #### CLI commands that will configure Traefik (static) ####
      ## API Settings ##
      - --api.insecure=true # <== Enables insecure api
      - --api.dashboard=true # <== Enables the dashboard to view services, middlewares, routers, etc...
      - --api.debug=true # <== Enables additional endpoints for debugging and profiling
      ## Log Settings ##
      - --log.level=DEBUG # <== Setting the level of the logs
      ## Provider Settings ##
      - --providers.docker=true # <== Enables docker as a provider
      - --providers.docker.exposedbydefault=false # <== Don't expose every container to traefik, only expose enabled ones
      - --providers.file.filename=/etc/traefik/dynamic.yml # <== Reference to the dynamic configuration file
      #- --providers.docker.defaultRule=Host(`{{ index .Labels "com.docker.compose.service" }}.${DOMAIN}`) # <== Enable this if you want to use container name as subdomain
      ## Entrypoints Settings  ##
      - --entrypoints.web.address=:80 # <== Defining an entrypoint for port :80 named web
      - --entrypoints.web.http.redirections.entryPoint.to=websecure # <== Redirect web to websecure (http > https)
      - --entrypoints.web.http.redirections.entryPoint.scheme=https # <== Set HTTPS as redirection scheme
      - --entrypoints.websecure.address=:443 # <== Defining an entrypoint for https on port :443 named websecure
      ## Certificate Settings (Let's Encrypt) ##
      - --certificatesresolvers.myresolver.acme.email=${EMAIL} # <== Setting email for certs
      - --certificatesresolvers.myresolver.acme.storage=/etc/traefik/acme/acme.json # <== Defining acme file to store cert information
      - --certificatesresolvers.myresolver.acme.dnschallenge=true # <== Enable DNS-01 ACME challenge  to generate and renew ACME certs
      - --certificatesresolvers.myresolver.acme.dnschallenge.provider=namecheap # <== Set DNS-01 challenge provider
      - --serversTransport.insecureSkipVerify=true # <== Disables SSL certificate verification between traefik and backend. Certificate does not need to be valid!
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ${DATADIR}/appdata/traefik/dynamic.yml:/etc/traefik/dynamic.yml
      - ${DATADIR}/appdata/traefik/acme.json:/etc/traefik/acme/acme.json
    labels:
      - "traefik.enable=true" # <== Enable traefik on itself to view dashboard and assign subdomain to view it
      - "traefik.http.routers.traefik.service=api@internal" # <== Enabling the api to be a service to access
      - "traefik.http.routers.traefik.tls=true"

    ports:
      - 80:80
      - 443:443
      - 8080:8080
    restart: always
  # WikiJs
  wikijs:
    image: linuxserver/wikijs
    container_name: wikijs
    environment:
      - TZ=${TZ}
      - PUID=${PUID}
      - PGID=${PGID}
    volumes:
      - ${DATADIR}/appdata/wikijs/config:/config
      - ${DATADIR}/appdata/wikijs/data:/data
    # ports:
    #   - 8300:3000
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.wikijs.entrypoints=websecure"
      - "traefik.http.routers.wikijs.rule=Host(`wiki.${DOMAIN}`)"
      - "traefik.http.routers.wikijs.tls=true"
    restart: always
  # Home Assistant
  homeassistant:
    image: homeassistant/home-assistant
    container_name: homeassistant
    environment:
      - TZ=${TZ}
      - PUID=${PUID}
      - PGID=${PGID}
    volumes:
      - ${DATADIR}/appdata/homeassistant/config:/config
    ports:
      - 8123:8123
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.homeassistant.entrypoints=websecure"
      - "traefik.http.routers.homeassistant.rule=Host(`homeassistant.${DOMAIN}`)"
      - "traefik.http.routers.homeassistant.tls=true"
    restart: always

# networking
networks:
  default:
    driver: bridge
    ipam:
      driver: default
      config:
      - subnet:  172.16.0.0/16
        gateway: 172.16.0.1

as you can see for other containers I have commented out the ports. There are also no errors in the traefik log. Traefik simply doesn't detect that single container unless port is exposed. Why is that?

Hi @shard

The homeassistant/home-assistant does not expose a port by default(the docs say this should be published in host mode, this is likely why). The docker provider will use the exposed port(or the first exposed port) as the service port for the load balancer.

You can use the label traefik.http.services.<service_name>.loadbalancer.server.port to specify it.

I can only guess at this point that the publishing of the port achieves the same thing.

Docs: Privder -> Docker -> Port Dectection

Sample docker inspect nginx, whoami vs homeassistant

for image in containous/whoami:latest nginx:latest homeassistant/home-assistant:latest; 
do 
  echo -n "${image}: "; docker image inspect ${image} | jq '.[].Config.ExposedPorts'; 
done

containous/whoami:latest: {
  "80/tcp": {}
}
nginx:latest: {
  "80/tcp": {}
}
homeassistant/home-assistant:latest: null

This seems to be the case. :+1: Thanks for pointing it out!

1 Like

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.