Feature Request: Reload application.yml Dynamically
Opened this issue · 6 comments
Feature Request
One of the features that we are considering for the future is the ability to reload the application.yml
file without restarting ShinyProxy. This would allow us to update the image version of sub Shiny apps or edit user permissions for individual apps dynamically. We are thinking of implementing this feature either through a web UI or an API trigger.
Expected Behavior
We would like the ability to make changes to the application.yml
configuration file, such as updating image versions or modifying user permissions, without the need to restart ShinyProxy. This would provide greater flexibility and reduce downtime when managing and updating Shiny apps.
Use Case
- Updating the image version of a Shiny app to deploy a new version.
- Modifying user permissions for individual Shiny apps.
- Making runtime changes to other configuration parameters in
application.yml
without requiring a full restart.
Implementation Options
We are considering implementing this feature through one of the following methods:
-
Web UI: Provide a user-friendly web interface within ShinyProxy where administrators can make configuration changes and trigger a reload of the
application.yml
file. -
API Trigger: Implement an API endpoint that allows administrators to send a request to reload the configuration dynamically.
This comes into its own when the application.yml is mounted into a pod on kubernetes as a secret or configmap, as changes to those mounted entities have an eventually consistent model of propagating those changes down.
NOTE: Though you'd need to make the path to the application config file configurable if it's not already, as you'd need to volume mount a directory path not a subPath to a single file for this propagation to happen.
Hi
In general we have taken the approach of only reading the configuration file at startup of ShinyProxy and not re-loading any of the configuration settings. The main reason is that certain aspects of the configuration are managed by Spring (Boot) which will cause certain services to be loaded and initialized while other parts of the code may not be started. Changing this at runtime, would be very complex. In addition, this allows caching certain values in memory, while not having complex logic to invalid these caches.
However, since ShinyProxy 3.0.0, the currently running proxies no longer need access to the proxyspec configuration. That means that the running proxies are completely independent of the ShinyProxy configuration. E.g. when using the ShinyProxy operator, it is possible to remove a spec while still keeping the proxies using this spec. With this change, it would be easier to only re-load the specs without restarting ShinyProxy. The difficulty here would be to check which caches inside ShinyProxy would need to be refreshed.
To conclude, I think this is technically possible, but currently we do not have plans to implement this. Therefore, I'll keep this issue open as a feature request.
I will add, using kubernetes, i create the application.yml file as a configmap and mount it into the deployment. To ensure shinyproxy restarts, I add an ENV variable with the git commit number. Therefore, every push with yaml changes ensures the deployment will restart because of the new commit sha. Helm, a template manager and ARGO a continuous deployment application make this really streamlined
Hi @corey-dawson on Kubernetes you can also use the shinyproxy operator: https://github.com/openanalytics/shinyproxy-operator . This works in a similar way as you described. However, it will keep the old ShinyProxy servers running, until they have no active websocket connections. This ensures that the websocket connection isn't terminated (and therefore state is lost) when using e.g. Shiny apps,
Hey @corey-dawson, could you share how you achieved to mount application.yml file as a configmap ? I am trying to do the same but I having a lot of troubles to make it work.
Hey @corey-dawson, could you share how you achieved to mount application.yml file as a configmap ? I am trying to do the same but I having a lot of troubles to make it work.
@ggarza31416 Sure. Achieve a config map mount without helm. Just the skeleton, but it is important to specify the volume/volumeMounts correctly. In addition, notice the key in the configmap is "application.yml" to prepare for this data to be saved as a file.
configmap.yaml
kind: ConfigMap
apiVersion: v1
metadata:
name: shinyproxy-setup
namespace: mynamespace
labels:
app: my-shinyproxy
data:
instance: dev
application.yml: |
proxy:
title: Open Analytics Shiny Proxy
logo-url: https://www.openanalytics.eu/shinyproxy/logo.png
landing-page: /
heartbeat-rate: 10000
heartbeat-timeout: 60000
port: 8080
authentication: simple
admin-groups: scientists
# Example: 'simple' authentication configuration
users:
- name: jack
password: password
groups: scientists
- name: jeff
password: password
groups: mathematicians
specs:
- id: 01_hello
display-name: Hello Application
description: Application which demonstrates the basics of a Shiny app
container-cmd: [ "R", "-e", "shinyproxy::run_01_hello()" ]
container-image: openanalytics/shinyproxy-demo
access-groups: [ scientists, mathematicians ]
- id: 06_tabsets
container-cmd: [ "R", "-e", "shinyproxy::run_06_tabsets()" ]
container-image: openanalytics/shinyproxy-demo
access-groups: scientists
logging:
file:
name: shinyproxy.log
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: shinyproxy
labels:
app: shinyproxy
spec:
replicas: 1
selector:
matchLabels:
app: shinyproxy
template:
metadata:
labels:
app: shinyproxy
spec:
containers:
- name: shinypropxy
image: shinyproxy_image
ports:
- containerPort: 8080
volumeMounts:
- name: configmap-volume
mountPath: /opt/shinyproxy/application.yml
subPath: application.yml
volumes:
- name: configmap-volume
configMap:
name: shinyproxy-setup
defaultMode: 420