tiangolo
tiangolo

Reputation: 1606

Is it possible to limit Traefik to the current (docker-compose) Stack?

Objective

I have a server running Rancher (Docker). In that server, I have several un-related stacks.

I want to make Traefik the main interaction point of that stack. And make it load balance / proxy the requests to different containers based on the path.

I want to make it send the traffic for /api to the backend server service. And send the traffic for / to the frontendservice.

Current state

Here's a slimmed down version of my docker-compose.yml showing only the relevant services:

version: '2'
services:
  server:
    image: server
    labels:
      - "traefik.frontend.rule=PathPrefix:/api"
      - "traefik.enable=true"
      - "traefik.port=80"
  frontend:
    image: frontend
    labels:
      - "traefik.frontend.rule=PathPrefix:/"
      - "traefik.enable=true"
      - "traefik.port=80"
  proxy:
    image: traefik:v1.4
    command: --web --accessLog --rancher --rancher.exposedbydefault=false --rancher.metadata=true
    volumes:
      - /dev/null:/traefik.toml

Then using a Rancher load balancer that listens to the public ports, I redirect requests to app1.example.com to my proxy service. Then it takes the requests and re-directs traffic to each of the two containers based on the path.

I also redirect traffic to traefik.app1.example.com to the same proxy service, to the port 8080 to access the web UI.

If I have only one stack, it works.

The problem

If I add another stack (or if I duplicate that stack) and have more services with Traefik labels, the proxy from app1 will read the labels from the services in app2 and any other stack that declares Traefik labels.

Then, in the web UI for the proxy in app1, I can see all the backends from all the different stacks. But the frontend rules get overwritten.

Question

Up to now, I've seen examples mostly of how to use Traefik as a unique global load balancer / proxy. I just realized that I assumed that I could also create isolated Traefik instances per stack, or a hierarchy of Traefik load balancers.

It seems to me like I'm missing some configuration or misunderstanding something.

But still, I have to ask, is it possible to have different isolated Traefik instances per stack and make them only listen and use the services in their own stack?

Is it possible with Rancher? Is it possible with any other Docker stack orchestrator (e.g. Swarm)?

If that's possible, what am I missing?

Upvotes: 2

Views: 1946

Answers (2)

Yurii Melnychuk
Yurii Melnychuk

Reputation: 898

If you are interested in Traefik v2 solution for this, you can use --providers.docker.constraints option to achieve the same result. So, the basic example could be:

services:
  traefik:
    image: traefik:v2.3
    command:
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--providers.docker.constraints=Label(`custom.label`,`custom-value`)"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

  custom_service:
    image: ...
    labels:
      - "traefik.enable=true"
      - "custom.label=custom-value"

Docs

Upvotes: 1

tiangolo
tiangolo

Reputation: 1606

I think I found how to solve it.

It seems I can't make Traefik only use services in his own stack directly. But it seems I can use Traefik constraints and tags to achieve almost the same.

Here's my updated docker-compose.yml using constraints and tags:

version: '2'
services:
  server:
    image: server
    labels:
      - "traefik.frontend.rule=PathPrefix:/api"
      - "traefik.enable=true"
      - "traefik.port=80"
      - "traefik.tags=app1.example.com"
  frontend:
    image: frontend
    labels:
      - "traefik.frontend.rule=PathPrefix:/"
      - "traefik.enable=true"
      - "traefik.port=80"
      - "traefik.tags=app1.example.com"
  proxy:
    image: traefik:v1.4
    command: --web --accessLog --constraints=tag==app1.example.com --rancher --rancher.exposedbydefault=false --rancher.metadata=true
    volumes:
      - /dev/null:/traefik.toml

It will only match services that have the Traefik tag app1.example.com. Those tags can be any string, but as I'm wanting to filter by a specific domain, I just used the domain I wanted to filter as the tag to use.

Also, notice that the tag is set in the services with a label traefik.tag.

Upvotes: 4

Related Questions