ShinyProxy 2.6.0

[This article was first published on Open Analytics, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

ShinyProxy 2.6.0

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 demonstrates the 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.

App Recovery

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 access-groups property 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 (running) apps.

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.

Additional metrics

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 time.

ShinyProxy Operator

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.

Full release notes can be found on the downloads page and updated documentation can be found on As always community support on this new release is available at

Don’t hesitate to send in questions or suggestions and have fun with ShinyProxy!

To leave a comment for the author, please follow the link and comment on their blog: Open Analytics. offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)