Host network container routes not working

I was under the impression that even if a container used host networking, although you have to define the services with the file provider, I could still define the router on the container via labels. It looks like this isn't working for me. Below is an example of one of the containers, but the dashboard does not show the router.

version: '3'
services:
  test:
    container_name: test
    environment:
      PGID: ${PGID}
      PUID: ${PUID}
    image: image: ghcr.io/linuxserver/nginx:1.26.2
    labels:
      traefik.enable: true
      traefik.http.routers.test.rule: Host(`test.myserver.com`)
      traefik.http.routers.test.service: test@file
      traefik.http.routers.test.tls: 'true'
    network_mode: host
    restart: unless-stopped

services.yaml

http:
  services:
    test:
      loadBalancer:
        servers:
        - url: http://host.docker.internal:80

Share you full Traefik static and dynamic config, and docker-compose.yml if used.

Note that host.docker.internal only works when using Docker Desktop.

compose file:

version: "3.3"
networks:
  dockerproxy:
    internal: true
    ipam:
      config:
      - subnet: 172.18.4.0/24
      driver: default
    name: dockerproxy
  web:
    internal: true
    ipam:
      config:
      - subnet: 172.18.2.0/24
      driver: default
    name: web
    
services:
  traefik:
    image: traefik:v3.1.4
    container_name: traefik
    networks:
      - web
      - dockerproxy
    depends_on:
      - dockerproxy
    env_file:
      - .env
    environment:
      - CF_API_EMAIL=${CLOUDFLARE_EMAIL}
      - CF_DNS_API_TOKEN=${CLOUDFLARE_API_KEY}
    restart: unless-stopped
    extra_hosts:
      - host.docker.internal:host-gateway
    ports:
      - 80:80
      - 443:443
    volumes:
      - ${APPDATA}/traefik:/etc/traefik
      - /var/log/traefik:/var/log/traefik
    labels:
      traefik.http.routers.traefik.tls.certresolver: letsencrypt
      traefik.http.routers.traefik.tls.domains[0].main: "${SERVER_DOMAIN}"
      traefik.http.routers.traefik.tls.domains[0].sans: "*.${SERVER_DOMAIN}"

  dockerproxy:
    container_name: dockerproxy
    image: ghcr.io/tecnativa/docker-socket-proxy
    privileged: true
    networks:
      - dockerproxy
    restart: unless-stopped
    environment:
      CONTAINERS: 1
      POST: 0
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro

  test:
    container_name: test
    environment:
      PGID: ${PGID}
      PUID: ${PUID}
    image: image: ghcr.io/linuxserver/nginx:1.26.2
    labels:
      traefik.enable: true
      traefik.http.routers.test.rule: Host(`test.myserver.com`)
      traefik.http.routers.test.service: test@file
      traefik.http.routers.test.tls: 'true'
    network_mode: host
    restart: unless-stopped

traefik config

entryPoints:
  web:
    address: :80
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  websecure:
    address: :443
    transport:
      respondingTimeouts:
        readTimeout: 0
    http:
      tls: {}
  traefik:
    address: ":8080"

ping: {}

providers:
  docker:
    endpoint: tcp://dockerproxy:2375
    watch: true
    exposedByDefault: false
  file:
    directory: /etc/traefik/file_rules

api:
  dashboard: true
  insecure: true

log:
  level: DEBUG
  filePath: /var/log/traefik/traefik.log

accessLog:
  filePath: /var/log/traefik/access.log

certificatesResolvers:
  letsencrypt:
    acme:
#      caServer: https://acme-staging-v02.api.letsencrypt.org/directory
      email: alexhphil@gmail.com
      storage: /etc/traefik/acme.json
      dnsChallenge:
        provider: cloudflare
        delayBeforeCheck: 0
        resolvers:
          - 1.1.1.1:53
          - 1.0.0.1:53

serversTransport:
  insecureSkipVerify: true
  forwardingTimeouts:
    idleConnTimeout: 0   # Time allowed to establish a connection to the backend
    dialTimeout: 0   # Time allowed to establish a connection to the backend
    responseHeaderTimeout: 0  # Time allowed to wait for the response header from the backend

dynamic config

http:
  services:
    test:
      loadBalancer:
        servers:
        - url: http://host.docker.internal:80

Just to note that everything works properly when this is added to the dynamic file. It's without this it doesn't work. I was hoping the container labels would replace the routers in the dynamic file:

  routers:
    test:
      entrypoints:
      - web
      - websecure
      rule: Host(`test.myserver.com`)
      service: test

Probably the providers.docker is overwriting the target service address with the internal Docker IP of the container. As that is what it is normally used for.


I always find the use of a docker-proxy interesting. You don’t trust Traefik and therefore don’t allow POST - that’s fine. But you trust another less known Docker image more, which now has full access to Docker socket instead?

As far as I remember the proxy image has a history of not being updated for years. If I remember a discussion correctly, because they didn’t know how to deal with the image build pipeline. How do you know a bad actor hasn’t smuggled in some code into that Docker image?

It’s fine for a small project to not being perfect, but the question is if you give such a project access to critical data and infrastructure.

The alternative is to roll your own Docker socket proxy, based on a well-known image, like in this example (link).

That's an interesting point about docker proxy. I'd rather trust traefik than add in another application / trust layer.

As far as your reasoning why this isn't working, I don't quite understand. When I use the router labels on these host networked containers, the routers aren't even showing up in the dashboard as existing. It's not that it's not routing properly.