Shouldn’t it work with Configuration Discovery and a constraint for both services? (Doc)
Here is a simple example, that doesn't fully utilize TLS, you would need to setup a wildcard cert (with LetsEncrypt). And the rule in traefik-dynamic.yml
could be improved, using something like *.lab.example.com
.
traefik-ext
listens externally on 80 and 443, creates TLS certs. It recognizes services with traefik.ext=true
label. Every request not matching the discovered "ext" services will be forwarded to traefik-int
via the traefik-dynamic.yml
configuration file.
traefik-int
only listens in Docker network internally on port 80, no TLS, discovers services using traefik.int=true
label.
docker-compose.yml:
version: '3.9'
networks:
proxy-ext:
name: proxy-ext
driver: overlay
proxy-int:
name: proxy-int
driver: overlay
volumes:
traefik-certificates:
configs:
traefik-dynamic.yml:
file: traefik-dynamic.yml
services:
traefik-ext:
image: traefik:v2.10
hostname: '{{.Node.Hostname}}'
ports:
- target: 80
published: 80
protocol: tcp
mode: host
- target: 443
published: 443
protocol: tcp
mode: host
networks:
- proxy-ext
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- traefik-certificates:/certificates
configs:
- traefik-dynamic.yml
command:
- --providers.docker=true
- --providers.docker.swarmMode=true
- --providers.docker.exposedByDefault=false
- --providers.docker.network=proxy-ext
- --providers.docker.constraints=Label(`traefik.ext`,`true`)
- --providers.file.filename=/traefik-dynamic.yml
- --providers.file.watch=true
- --entryPoints.web.address=:80
- --entryPoints.web.http.redirections.entryPoint.to=websecure
- --entryPoints.web.http.redirections.entryPoint.scheme=https
- --entryPoints.websecure.address=:443
- --entryPoints.websecure.http.tls=true
- --entryPoints.websecure.http.tls.certResolver=myresolver
- --api.debug=true
- --api.dashboard=true
- --log.level=INFO
- --accesslog=true
- --certificatesResolvers.myresolver.acme.email=mail@example.com
- --certificatesResolvers.myresolver.acme.storage=/certificates/acme.json
- --certificatesresolvers.myresolver.acme.tlschallenge=true
deploy:
mode: global
placement:
constraints:
- node.role==manager
labels:
- traefik.ext=true
- traefik.enable=true
- traefik.http.routers.traefik-ext.entrypoints=websecure
- traefik.http.routers.traefik-ext.rule=Host(`traefik-ext.example.com`)
- traefik.http.routers.traefik-ext.service=api@internal
- traefik.http.routers.traefik-ext.middlewares=auth-ext
- 'traefik.http.middlewares.auth-ext.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/'
- traefik.http.services.dummy-svc.loadbalancer.server.port=9999
traefik-int:
image: traefik:v2.10
hostname: '{{.Node.Hostname}}'
networks:
- proxy-ext
- proxy-int
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
command:
- --providers.docker=true
- --providers.docker.swarmMode=true
- --providers.docker.exposedByDefault=false
- --providers.docker.network=proxy-int
- --providers.docker.constraints=Label(`traefik.int`,`true`)
- --entryPoints.web.address=:80
- --entryPoints.web.forwardedHeaders.insecure=true
- --api.debug=true
- --api.dashboard=true
- --log.level=INFO
- --accesslog=true
deploy:
mode: global
placement:
constraints:
- node.role==manager
labels:
- traefik.int=true
- traefik.enable=true
- traefik.http.routers.traefik-int.entrypoints=web
- traefik.http.routers.traefik-int.rule=Host(`traefik-int.example.com`)
- traefik.http.routers.traefik-int.service=api@internal
- traefik.http.routers.traefik-int.middlewares=auth-int
- 'traefik.http.middlewares.auth-int.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/'
- traefik.http.services.dummy-svc.loadbalancer.server.port=9999
whoami-ext:
hostname: '{{.Node.Hostname}}'
image: traefik/whoami:v1.10
networks:
- proxy-ext
deploy:
mode: global
labels:
- traefik.ext=true
- traefik.enable=true
- traefik.http.routers.whoami-ext.entrypoints=websecure
- traefik.http.routers.whoami-ext.rule=Host(`whoami-ext.example.com`)
- traefik.http.services.whoami-ext.loadbalancer.server.port=80
whoami-int:
hostname: '{{.Node.Hostname}}'
image: traefik/whoami:v1.10
networks:
- proxy-int
deploy:
mode: global
labels:
- traefik.int=true
- traefik.enable=true
- traefik.http.routers.whoami-int.entrypoints=web
- traefik.http.routers.whoami-int.rule=Host(`whoami-int.example.com`)
- traefik.http.services.whoami-int.loadbalancer.server.port=80
traefik-dynamic.yml:
http:
routers:
forward-all:
rule: PathPrefix(`/`)
service: forward-all
services:
forward-all:
loadbalancer:
servers:
- url: http://traefik-int/