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.