Trying out flowable-ui behind reverse proxy, need help

I tried this https://hub.docker.com/r/flowable/flowable-ui and am using this docker-compose.yml file: https://github.com/flowable/flowable-engine/blob/main/docker/config/ui-postgres.yml

I got it to work by accessing the docker host it runs on via: http://10.10.10.10:8080/flowable-ui/

Now I am trying to put it behind traefik as reverse proxy. The result is that when accessing https://flowable.mydomain.tld I get a tomcat error 404 which was to be expected.

If I access https://flowable.mydomain.tl/flowable-ui I get to the login form and everything works except I need to manually add /flowable-ui which is very inconvenient.

So I tried this directive which makes the traefik reverse proxy add a prefix:

          - "traefik.http.routers.flowable.middlewares=secHeaders@file,localIPsOnly@file,flowable"                                                                                                                                                                                                                  
          - "traefik.http.middlewares.flowable.addprefix.prefix=/flowable-ui"

which results in visits to https://flowable.mydomain.tld being redirected to https://flowable.mydomain.tld/flowable-ui/idm/#/login which gives a page not found error.

If I manually remove “/flowable-ui” => https://flowable.mydomain.tld/idm/#/login I can log in and I can click and access “Task App”, “Modeler App”, “Admin App” and “IDM App” but when navigating further down these menus, the Flowable icon on the top left, does not redirect to https://flowable.mydomain.tld/flowable-ui/ but to the root of the respective APPs so to get back to https://flowable.mydomain.tld/flowable-ui/ I have to manually type it into the browser.

Sorry if this sounds really complicated, I’m sure there are a couple of environmental variables I need to set for all of this to just work, right?

Any pointers please?

Hi,

We have run Flowable UI behind different reverse proxies and load balancers.
Flowable UI does not require any specific configuration for that.
This seems very Traefik specific. I personally don’t that much experience with it this specific reverse proxy.
But this feels related to some rewrite rules that need to be in place in it to work correctly.
Perhaps some other forum members have experience with Traefik which they can share.

Regards,

Yvo

Thanks for the quick reply.

Let’s leave traefik aside, whatever reverse proxy you use, do you manually add “/flowable-ui” to your URL every time you visit?

If not, can someone share how they sorted it out with caddy or nginx or whatever reverse proxy they are using? I can then figure out what the corresponding traefik rule would be.

Can be both.
Currently the application in the container is configured by default to run with that servlet endpoint.
But you can configure that by override the default properties. That can also be done in several ways.
From the command line with for example;

docker run -p8080:8080 flowable/flowable-ui --server.servlet.context-path=/somethingelse

But with docker compose or some other orchestrator you perhaps want to override these properties with env variables.

But you can also use the rewrite functionality of your reverse proxy of choice to map a path (or root) it is exposing to a certain path (and or port) of its backend service.

But normally I start my containers without a servlet path. And let the reverse proxy route to that. But that all depends on the situation.
Because you can configure Flowable UI container easily with the flowable and spring properties. That’s all op to you and the configuration of your reverse proxy.

Regards,

Yvo

Thanks Yvo, I appreciate all the help I’ve gotten so far on this forum. Let me see if I can squeeze a few more answers out of you, or someoen else :slight_smile:

I’ve been searching up and down the internet to find documentation for available environmental variables, do you happen to have a pointer for me?
The most useful thing I could find is something somebody shared 5 years ago. Necessary environment variables for Flowable Applications · GitHub

Looking at that and what you shared, would the variable by any chance be:

FLOWABLE_ADMIN_APP_SERVER-CONFIG_PROCESS_CONTEXT-ROOT=/

That is what I tried but my understanding of flowable was flawed, so my reverse proxy applied the prefix to all URLs while it is apparently only needed for the main starting URl.

Hi.

The Flowable application properties can be found here;

And because it is a Spring boot application the default Spring Boot configuration properties are also available.

Then for setting them, and this is also plain Spring Boot, you can use various mechanismes.
For example with a .properties file. This wouldn’t be your first choice because you use a Docker image.

Or via application parameters. This needs to be supported by the image (because of the way the executable jar is executed). Luckely our image supports that. (see my previous remark with the --server.servlet.context-path runtime parameter).

Or via environment variables. In that case you need to use this naming convention; SPRING_CONFIG_NAME instead of spring.config.name.

You can read about the Spring stuff here.

In regards to your question about the context path. Did my suggestion not work? Using the server.servlet.context-path property?

Yvo

Thanks for the pointers. It was hard work but I figured out part of the solution.

Inside docker-compose.yml I edited the entrypoint to set the server.servlet.context-path to the root “/”

entrypoint: ["./wait-for-something.sh", "flowable-ui-postgres", "5432", "PostgreSQL", "/flowable-entrypoint.sh", "--server.servlet.context-path=/"]

with the result that when I visit flowable.mydomain.tld I get redirected to flowable.mydomain.tld/idm/#/login and after a successful login I see the flowable-ui at flowable.mydomain.tld/#/

The remaining problem is that when I enter one of these 4 modules:

i.e.

when clicking the flowable logo, top-left I don’t end up back in the overview but stay in the same module.

Sorry, difficult to explain but the only way to get from “Task App”, “Modeler App” “Admin App” or “IDM App” back to the main screen where I can see all 4 is to manually enter the URL in the browser.

The code behind the flowable logo looks like:

and this “backToLanding” seems to not lead to “/” but to “/workflow/#/tasks”, "/modeler/#/processes, “/admin/#/engine” or respectively “/idm/#/user-mgmt” depending on the current module but never back to the main screen.

Anyway, at this point I am giving up except if anyone is willing to share their docker compose end .env files.
I am sure the problem is no longer related to traefik as reverse proxy as I have trimmed it down to only forward this domain to the flowable container, and not touch anything else.

Hi,

Could you share your complete Traefik config so that others can reproduce and potentially help?

Thanks.

Yvo

Sure, thanks for replying. I don’t think we need the complete traefik compose file as I have been running it for many years. The traefik compose file only has settings for it to listen on port 80 and 443, redirect 80 to 443 and sort out the letsencrypt certificates.

Every time I test a new app and want to see how it works behind a reverse proxy I only add a few lines to the apps “label” section inside the docker-.compose.yml file. This worked for all apps so far.

Its all about the few lines of traefik labels:
enabling traefik, telling traefik which is its network, enable the router for this container, define the entrypoint and apply the rule which lets traefik filter all incoming traefik to flowable.mydomain.tld and redirect it to port 8080 of this container.

This usually works for all apps, except here, flowable expects to be called on flowable.mydomain.tld/flwoable-ui and not just flowable.mydomain.tld so I thought simply adding this --server.servlet.context-path=/ to the entrypoint should suffice.

This compose file references a middleware secHeaders@file this si its content:

    secHeaders:                                                                                                                                                                                                                                                                                                      
      headers:                                                                                                                                                                                                                                                                                                       
        browserXssFilter: true                                                                                                                                                                                                                                                                                       
        contentTypeNosniff: true                                                                                                                                                                                                                                                                                     
        frameDeny: true                                                                                                                                                                                                                           
        sslRedirect: true                                                                                                                                                                                                                                                                                            
        #HSTS Configuration                                                                                                                                                                                                                                                                                          
        stsIncludeSubdomains: true                                                                                                                                                                                                                                                                                   
        stsPreload: true                                                                                                                                                                                                                                                                                             
        stsSeconds: 31536000                                                                                                                                                                                                                                                                                         
        customFrameOptionsValue: "SAMEORIGIN"                                                                                                                                                                                                                                                                        
        customRequestHeaders:                                                                                                                                                                                                                                                                                        
          Cache-Control: "no-cache, no-store, must-revalidate"                                                                                                                                                                                                                                                       
        customResponseHeaders:                                                                                                                                                                                                                                                                                       
          Cache-Control: "no-cache, no-store, must-revalidate"                                                                                                                                                                                                                                                       
        referrerPolicy: "same-origin"

To ensure seamless navigation within Flowable UI, make sure that you have properly configured the base URL or context path for Flowable UI in its configuration. It should align with the prefix you’re adding through Traefik.
Additionally, check if there are any other environment variables or settings within Flowable UI that need adjustment to work correctly behind a proxy.
And if you’re ever looking for a reliable proxy service, you can explore this proxy website. They offer secure proxy services that might complement your setup.
Keep up the good work, and you’ll have Flowable UI running seamlessly behind your proxy in no time!