Today we release version 2.6.0 of ShinyProxy which includes over forty improvements. ShinyProxy is a novel, open source platform to deploy Shiny apps for the enterprise or larger organizations. Nevertheless, ShinyProxy is also an excellent choice for deploying a handful of apps in smaller organizations. While ShinyProxy is generally used to host Shiny applications, it has always been designed with the idea to host any application that can be packaged into a Docker container. It is therefore no surprise that our customers show interest in deploying complete development environments using ShinyProxy. ShinyProxy has supported deploying RStudio, Visual Studio Code and Eclipse Theia for a long time. With the release of ShinyProxy 2.6.0, it is now possible to also host Jupyter notebooks. A major priority throughout this release was increasing the user-experience of both the end-user and administrator when hosting development environments with ShinyProxy. This blog post covers some of the improvements around this use-case. All changes in this version can be found in the changelog.
Multiple instances of an app
Traditionally, a user could only launch one instance of a specific app in ShinyProxy at the same time. For hosting Shiny apps, this was often sufficient. However, once users start using IDEs in ShinyProxy, a need for launching multiple instances of an app arises. When using RStudio, users often start a heavy and lengthy computation. By launching a new instance of RStudio, they can very easily continue their work while this computation is running.
The administrator of ShinyProxy can specify (for each app) the maximum number of
instances a user can launch. This is by default set to one instance, in order to
maintain the current behavior of ShinyProxy. The screenshot above also
Stop app and
Restart app buttons which where introduced in
this release, giving more control to the end-users.
Fine control on app termination
ShinyProxy can be an ideal solution for providing dynamic environments to
perform calculations and simulations, especially because of its flexibility and
easiness to deploy. In combination with Kubernetes, a very scalable solution can
be implemented, where no (expensive) resources are wasted. However, in a
standard deployment ShinyProxy terminates apps when they are no longer used by a
user. Of course, when performing long-term calculations the user is not using
the app during this calculation. Therefore, in ShinyProxy 2.6.0 it is possible
to control this behavior of ShinyProxy on a per-app level. For example, the
stop-on-logout property configures whether an app should be stopped when the
user logs out. Disabling this option is often combined with setting the
heartbeat-timeout property to
-1, which ensures ShinyProxy no longer
terminates an app when the user closes the browser tab of this app. This makes
it possible to have long-running apps of which the user can control the
lifecycle (by clicking the
Stop app or
Restart app buttons).
Maximum lifetime for an app
By providing users more control to the lifecycle of apps, there is also the risk that users forget about some apps they have running. Therefore, it is now possible to specify a maximum lifetime for an app. This lifetime can be configured both globally (for all apps in ShinyProxy) and per individual app. An administrator can set this value to, for example, 24 hours. ShinyProxy then ensures that apps are terminated when they have been running for 24 hours, ensuring no computation resources are wasted.
With apps running for multiple hours or even days, it is undesirable that these
apps are terminated when ShinyProxy is restarted. Therefore, this release
introduces the “App Recovery” feature. When enabled, ShinyProxy does not
terminate apps when it shuts down. In addition, when ShinyProxy starts up, it
looks for existing, running apps that it can “recover”. This means that those
apps are again connected to the respective user and that users can continue to
use them. This feature is most prominently designed to support situations where
ShinyProxy is restarted when the configuration of ShinyProxy is not modified.
However, it is possible to tell ShinyProxy to recover running apps even when the
configuration is modified. While this works fine in most situations, some
unexpected behavior could be experienced when one modifies or removes the
configuration of an existing app. For example, when the
of an app is changed, it could be the case that existing users no longer have
access to their (already running) apps. On the other hand, adding additional
apps to the configuration of ShinyProxy does not pose any risk to existing
When restarting ShinyProxy using the App Recovery feature, users will experience some temporary downtime. In order to limit the inconveniences caused by this restart, ShinyProxy can now automatically reconnect any WebSocket connection used by apps.
In our experience this feature works well with a broad set of Shiny apps. However, for complex apps the developer of the Shiny app has to ensure that the reconnecting mechanism is supported. In addition the feature integrates perfectly with apps using NodeJS, Python etc. As usual, this feature is disabled by default and can be enabled globally or per app. In addition it is possible to configure the option so that the user is asked for confirmation before restoring the connecting.
Dynamic app specifications
Besides the focus on making the hosting of development environments more useful, this release also improves some existing features. The context in which the Spring Expression Language is evaluated has been extended to include objects related to the authenticated user and additional runtime values. This makes it possible to have even more dynamic app specifications, e.g. by using attributes from the OpenID token. Furthermore, with this release, the configuration of ShinyProxy allows grouping apps and allows adding additional properties to both apps and groups that can be used in templates.
The previous release (ShinyProxy 2.5.0) added support for exposing Prometheus metrics. This release adds some additional metrics that provide more precise and consistent results for the various metrics. For example, a metric representing the absolute number of apps currently running is now exposed.
Fine-grained Access Control
This release introduces additional options for configuring the access control of
applications. In addition to specifying a list of groups that have access to
an app, it is now possible to specify a list of users. Furthermore, using the
access-expression property, it is possible to use Spring Expression for
determining whether a user has access to an app. This can be used, for example,
to only allow access to an app if a user is a member of two groups at the same
Together with the release of ShinyProxy 2.6.0, we also release ShinyProxy Operator 1.0.0. The Operator is the ideal way to run and manage ShinyProxy on Kubernetes, allowing seamless updates of the configuration of ShinyProxy and running multi-tenant deployments.
Don’t hesitate to send in questions or suggestions and have fun with ShinyProxy!