简体   繁体   中英

traefik reverse-proxy with docker backend - configure frontend rules in traefik's config file and not via container label

For using traefik as a reverse-proxy in front of a Docker container whose dynamic IP address might change over time, traefik comes with a docker backend . All examples that I could find for setting this up follow the same pattern:

First, start traefik in docker mode without an extra configuration file, activate host network mode (optional, so that traefik can see all Docker networks on the host if required) and mount the Docker unix socket so that traefik can listen to container starts and stops.

docker run --rm -p 80:80 --net=host --name traefik-reverse-proxy -v /dev/null/traefik.toml:/etc/traefik/traefik.toml -v /var/run/docker.sock:/var/run/docker.sock traefik --docker --loglevel debug

Then, start another container and set at least the following labels :

  • traefik.backend: "some-backend-name"
  • traefik.frontend.rule: "Host: localhost; Method: GET" (or whatever your rules are)
  • traefik.port: 80 (or whatever port your container exposes internally)

Example:

docker run --rm --name nginx -l traefik.backend="some-backend-name" -l traefik.frontend.rule="Host: localhost; Method: GET" -l traefik.port="80 nginx

Then, doing a curl localhost , one can see in the logs of the traefik container that it took the request and routed it to the NGINX container.

So far, so good... however, I do not like the fact that I have to configure my reverse-proxy forwarding rules (eg forward Host: some.host.name to container xxx) within the application itself (where my docker-compose files setting up the containers, labels etc. are usually located). Rather, I would like to separate this from the application and configure it as part of traefik's configuration instead.

Is this possible somehow? What I tried is leaving out the traefik.frontend.rule label from the example nginx container and instead mount the following configuration file for traefik :

[frontends]
  [frontends.frontend1]
  backend = "some-backend-name"
    [frontends.frontend1.routes.test_1]
    rule = "Host: localhost; Method: GET"

The startup command for traefik thus becomes:

docker run --rm -p 80:80 --net=host --name traefik-reverse-proxy -v $PWD/traefik.toml:/etc/traefik/traefik.toml -v /var/run/docker.sock:/var/run/docker.sock traefik --docker --loglevel debug

However, this does not seem to attach the frontend rule from the config file with the backend label from the nginx container. curl localhost now returns a 404 / Not found error.

the watch flag seems only works under the condition of rule.toml changed first time.

In your case, i suggest you write a service to update your rule in etcd or zookeeper. the service read etcd changes and update traefik configure in etcd.

This is likely an order of operations issue. Enabling debug logging in config ( debug = true ) shows that traefik is parsing the config file frontend rules first, and only later generating frontends and backends based on what's running in docker.

This means that the docker backends don't exist when the frontends from config are created, and it throws and error.

One solution is to put your rules config in a seperate file (eg rules.toml as shown in the docs ) and add the watch = true directive to your config. This means that the frontend rules you define there will be updated after the backends from docker are generated.

We should probably submit a bug for this, because it's not exactly desirable functionality.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM