openanalytics / shinyproxy

ShinyProxy - Open Source Enterprise Deployment for Shiny and data science apps
https://www.shinyproxy.io
Apache License 2.0
524 stars 152 forks source link

Extend the functionality of additional-port-mappings #473

Open danielloader opened 10 months ago

danielloader commented 10 months ago

[!NOTE]
This is just an open feature request and musings about any theoretical implementation.

The additional port mappings are a welcome improvement for being able to access sidecar/additional containers/services in the kubernetes pods.

However I'd like to propose a more free form mapping capacity inside shinyproxy.

Lets take the documented example:

- id: myapp
  port: 8080
  additional-port-mappings:
    - name: mypath
      port: 8701
    - name: special_subpath
      port: 8888
      target-path: "#{proxy.getRuntimeValue('SHINYPROXY_PUBLIC_PATH')}special_subpath"

In the above example the following mappings are used:

/app/myapp/ maps to container:8080/
/app/myapp/mypath/ maps to container:8701/
/app/myapp/special_subpath/ maps to container:8888/app_proxy/<proxy_id>/special_subpath/

and extend it to:

- id: myapp
  port: 8080
  additional-port-mappings:
    - name: mypath
      port: 8701
    - name: special_subpath
      port: 8888
      target-path: "#{proxy.getRuntimeValue('SHINYPROXY_PUBLIC_PATH')}special_subpath"
    - name: backend_service
      port: 8080 
      hostname: backend-api.namespace

In the above example the following mappings are used:

/app/myapp/ maps to container:8080/
/app/myapp/mypath/ maps to container:8701/
/app/myapp/special_subpath/ maps to container:8888/app_proxy/<proxy_id>/special_subpath/
/app/myapp/backend_service/ maps to backend-api.namespace:8080/ (relative dns lookup)

The rationale here is I'm deploying a non shiny application (react) in addition to the other shiny applications in my shinyproxy application stack, and I'd like to be able to reach a backend REST API service that lives inside the cluster for auxiliary data shared between shinyproxy spawned applications.

Currently the solution is to host the react app as a static route on an express server and a simple API proxy on the same container as the shinyproxy spawned application.

The application works and the proxy functions as expected to be able to redirect traffic from the browser to hostname/app_proxy/{uuid} as documented.

However it mandates the use of a runtime server application to do this, and if possible I'd rather deploy the spec as an nginx container hosting static bundled web assets, and route to the hosted deployment/service backend via a port mapping (or similar) functionality.

I'm proposing shinyproxy can make this an authenticated route, on a subpath but instead of proxying the communications via the spawned application pod, instead directly to the hostname specified.

LEDfan commented 8 months ago

Hi @danielloader

Thank you for opening this issue. It's an interesting use-case, which we have considered implementing as well. We are currently collecting interest for making it easier to host API's in ShinyProxy, this could be part of this effort. I'll keep this open as a feature request.

danielloader commented 8 months ago

In the meantime, a question:

If I wanted to access a sidecar container in my shinyproxy spawned pod from the frontend, in a predictable url - what should I hit and how?

Currently I need to dynamically create my url hrefs to include the app_proxy/$UUID/proxy/$PATH

        additional-port-mappings:
          - name: proxy
            port: 8080

and the browser via XHR is calling /app_proxy/cc29ab3d-eb86-402e-a031-9058c6a7f09e/proxy/$PATH to hit that API/JSON.

Works fine if you can configure all your frontend links to include this extra stuff at pod spawn lunch time via the SHINYPROXY_PUBLIC_PATH environment variable, but shouldn't these additional port mappings allow me to get to the same outcome using a predictable path? if my app was called example, I'd expect to be able to get to this path via /app/example/proxy/$PATH.

Would like to know if I'm missing something here since bundling the vite react dev server in a pod to dynamically change these urls seems a bit extreme.