Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reusable Traefik middleware and names config field #150

Closed
tommiv opened this issue Apr 10, 2023 · 2 comments
Closed

Reusable Traefik middleware and names config field #150

tommiv opened this issue Apr 10, 2023 · 2 comments
Labels
bug Something isn't working

Comments

@tommiv
Copy link

tommiv commented Apr 10, 2023

Intro
So first of all let me thank you for Sablier because this is the only working solution for my problem I found so far.

Describe the bug
It's not really a bug but more like a clarification or maybe a feature request. I want to use Sablier to on-demand start/stop "staging" instances of the same application stack (just a website, so api, frontend app, DB and some more containers, doesn't really matter). For this, I have multiple versions of the same application running each in its own container with a unique container name (prefixed with a git branch name). For brevity, let's say that I have these two:

  • git_branch_name1_front
  • git_branch_name2_front

So, what puzzles me – if I create just one instance of Sablier middleware, it only works if I enumerate all possible names in the names field of the middleware config, which is pretty hard to automate. A couple of examples to demostrate:

wrong approach

# dynamic/defaults.yaml
http:
  middlewares:
    sablier:
      plugin:
        sablier:
          sablierUrl: http://sablier:10000
          # <====== notice there's no `names` field here
          sessionDuration: 1m
          dynamic:
            showDetails: true
            theme: ghost
            refreshFrequency: 5s
# dynamic/git_branch_name1.yaml
http:
  services:
    git_branch_name1_front:
      loadBalancer:
        servers:
          - url: http://git_branch_name1_front:80

  routers:
    git_branch_name1_front:
      rule: Host(`git_branch_name1.mycompany.domain`)
      middlewares:
        - gzip@docker
        - sablier@file
      service: git_branch_name1_front

This approach doesn't work, Sablier tries to poll the container with an empty name, which is illegal.

working approach

# dynamic/defaults.yaml
# ... no reusable middleware declared here 
# dynamic/git_branch_name1.yaml
http:
  services:
    git_branch_name1_front:
      loadBalancer:
        servers:
          - url: http://git_branch_name1_front:80

  middlewares:
    git_branch_name1_sablier:
      plugin:
        sablier:
          dynamic:
            displayName: 'git_branch_name1'
          names: 'git_branch_name1_front'
          sablierUrl: 'http://sablier:10000'
          sessionDuration: '1m'

  routers:
    git_branch_name1_front:
      rule: Host(`git_branch_name1.mycompany.domain`)
      middlewares:
        - gzip@docker
        - git_branch_name1_sablier@file
      service: git_branch_name1_front

This approach does work but in this case I will create a new middleware instance per git branch, which can be kinda clumsy. I mean it's ok if there's no other choice, it will work, I'll just lose an ability to centralize Sablier config in one simple semi-static file easily deployable via Ansible. Not sure if it impacts performance of Traefik if I multiply the number of middlewares used. Logically it should not.

Context

  • Sablier version: 1.3.0
  • Provider: docker v23.0.1
  • Reverse proxy: traefik v2.10.0-rc2
  • Sablier running inside a container? – yes

Expected behavior
It would be great if Sablier could somehow calculate the names array automatically per-request level (getting it from router for example), but I'm not sure if Traefik allows this at all.
Another possible approach is to override one centralized middleware config with something on the dynamic configuration file level, but I can't find anything like this in Traefik docs.

@tommiv tommiv added the bug Something isn't working label Apr 10, 2023
@acouvreur
Copy link
Owner

Hey!

So currently, there is no solution that is reverse proxy agnostic.

And because of the nature of reverse proxies in general, a route is not necessarily tied to a specific container instance.

For this reason I'm not developping any integration for a specific reverse proxy.

On the other hand, you might be interested in the group feature. This is a new feature in beta that you can see here: #134

It will explain how to tag your container instead of knowing their names.


But in the end, a single middleware will always be tied to a specific group of containers by using names or group. Calling the same middleware cannot have a different behavior depending on the host path for the moment.

For feature like this, you should always think "provider agnostic".


However, one way to have a reusable middleware would be to be able to transmit specific data to the middleware on the runitme.

This can be achieved wiht: headers

So we could definitely create a combination of groups and header to have a reusable middleware.

Let say you add a middleware that adds the following header: X-Sablier-Group or X-Sablier-Names prior to the sablier middleware being called, the middleware could use these headers to override the ones that you have to configure today on your middleware.


To sum up:

  • You cannot have a reusable middleware as of today
  • You should look if the new feature group is more interesting for you
  • We could create a feature request to override the group or name value at runtime

@tommiv
Copy link
Author

tommiv commented Apr 11, 2023

@acouvreur thanks for a quick response.

You're making a great point regarding reverse proxy agnosticism so I assume this answers my question.

I've checked the group feature. It's nice to have but in my particular case it changes nothing because it's still one middleware instance per stack instance.

The idea with dynamic groups via headers is a smart one though, but I think that for now I'm happy with what I have already, I'm going to close the issue.

@tommiv tommiv closed this as completed Apr 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants