Firstly, thanks so much for the efforts and open sourcing Shinyproxy.
Background
I deployed a Flask ‘hello world’ container on Shinyproxy which worked fine once I changed the ports to 3838. However, I’m now moving into deploying more complex python apps on Shinyproxy, namely dash apps. Dash was released a few months ago by Plotly claiming to be the ‘shiny of python’. This is quite exciting particularly if both Shiny and Dash can be deployed on Shinyproxy. The issue is dash apps require additional static resources. (Disclaimer!) I haven’t programmed in Java or SpringBoot. However, as far as I can see from looking at Chrome developer tools there are two ways Shinyproxy delivers static files to the client.
Webjars - I can see that the main template of shinyproxy loads the bootstrap css which I think also gets utilised by each shiny app.
Possible Solution: Add all the static resources to the pom.xml and add them on the webjars.org site.
Load from the Container - Additional static content for shiny apps is requested by using the container name, in this case peaceful_jepsen e.g.:
That’s an interesting question. You already made the distinction between content served by the shinyproxy server and content served by the web server inside the docker container.
I think it’s important to maintain that distinction, and have any content for your custom app served by the server inside your container. The shinyproxy server should only serve content related to shinyproxy itself, e.g. the login page, the app overview page, etc.
These URLs get proxied to your container and will be served from there.
For shiny apps, this works because all content referenced from the shiny app’s page uses hrefs that are relative to the page, e.g.
Then that means the href being used was “/_dash-layout” and not “_dash-layout”.
Do you control the hrefs? If so, removing the slash may solve your issue. If not, it becomes trickier… you could use javascript and extract the correct URL from window.location.
Thanks for the quick response and insight provided. You’ve given me some ideas for things to try, particularly around how Flask.py (the Dash backend) is sending the requests. I’ll post back here with my updates
Another Option
If I’m able to set the container name and pass that name as a variable to the containterised application, then I can prefix the routes Dash takes.
On my local
docker run -p 4002:3838 --name=this_name -e CONTAINER_NAME=this_name dash-image
Now that I have set the container name and set that name as a environment variable. My Flask/Dash app can prepend the requests.
container_name = os.environ.get('CONTAINER_NAME')
app.config.update({
# as the proxy server will remove the prefix
'routes_pathname_prefix': container_name + '/',
# the front-end will prefix this string to the requests
# that are made to the proxy server
'requests_pathname_prefix': container_name + '/'
})
Result
This results in the GET requests looking like this:
Question
Assuming there is no glaringly obvious reason this wouldn’t work, how do I set the docker image name to be custom in shinyproxy? And how do I pass an env var to the container? Can this be done in the application.yml?
The solution was coded in the Dash code as follows:
# In order to work on shinyproxy
app.config.supress_callback_exceptions = True
app.config.update({
# as the proxy server will remove the prefix
'routes_pathname_prefix': ''
# the front-end will prefix this string to the requests
# that are made to the proxy server
, 'requests_pathname_prefix': ''
})