Today we release version 3.0.0 of ShinyProxy, providing improvements on all aspects of using and deploying ShinyProxy. 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. For example, ShinyProxy is used more and more to host complete development environments. This blog post covers some major improvements of this release. All changes in this version can be found in the release notes.
High Availability and Scaling
Although a single ShinyProxy server is able to handle a large amount of users and apps, it does not provide high availability. All apps are inaccessible if that single server crashes or restarts. With ShinyProxy 3.0.0, it is now possible to run multiple replicas of ShinyProxy, providing both high availability and scaling. Therefore, one of the replicas may crash without the apps becoming inaccessible. Furthermore, by using a load balancer all requests are spread over the replicas, which reduces the load on a single server and increases the maximum throughput.
In order to fully benefit of this feature, it is advised to make use of Kubernetes and the ShinyProxy Operator. Together with this release we are releasing the ShinyProxy Operator 2.0.0, with full support for high availability and scaling. Nevertheless, the high availability mode is also supported when using Docker Swarm.
A completely new feature in this release is the support for app parameters. As part of an app configuration, you can now specify a set of parameters for the app. Whenever the user launches an application, ShinyProxy will show a form and ask the user to select a (pre-defined) value for each parameter. For example, the following app defines a parameter for the amount of CPU cores and memory:
This feature has lots of possibilities and applications. For example, in the case of a Shiny application it could be useful to allow the user to start older versions of the application (e.g. to compare different models). This can be achieved by adding a parameter with the version of the application and using the value of this parameter to launch a specific Docker image. In other circumstances, e.g. when deploying IDE’s, it is possible to add a parameter for the amount of CPU and memory which will be reserved for the app. Or you could add a parameter to let the user specify the max lifetime of an app.
This feature has been designed to be easy to use for both the administrator of ShinyProxy and the end-users. Because there is no built-in list of parameters, you can freely add parameters for (almost) all configuration properties of an application. Furthermore, you can use the parameters as environment variables in order to make them available to the app itself. Finally, it is possible to provide your own form for choosing the parameters.
In order to support all new features of this release, we have improved the (HTTP) API of ShinyProxy. In addition, the API is now documented using the OpenAPI specification which can be viewed using the Swagger UI. Together with the new API being more consistent, this makes the API much easier to use.
The API has also been improved in terms of security. In the first place, the API no longer returns any sensitive information to users. For example, the user can no longer retrieve the complete spec of an application or retrieve which docker image is used by a running application. Furthermore, it is now possible to configure CORS or add additional headers to API responses.
A key advantage of the improved API is that the request to start an app now takes at most ten seconds to complete, even if the app needs more time to startup. Therefore, there is no longer a need to configure load balancer or proxies in front of ShinyProxy to have (very) long request-timeouts.
Improved logging and hidden error messages
Handling error messages and logging is yet another area that has been improved a lot in this release. First of all, ShinyProxy does no longer return any internal errors or stack traces to the user. Instead, a nice looking page is shown to the user:
For many deployments this improves security, as end-users should not know any details on the reason the app failed to start. However, for the administrators of ShinyProxy it should be very easy to discover why applications are failing to start. For the Docker (Swarm) backend, ShinyProxy has always logged the exact error. However, for Kubernetes this is more difficult because of the distributed nature of Kubernetes. Fortunately, this has been fixed in this release: ShinyProxy is able to extract the error message from Kubernetes and log it in the ShinyProxy log. Along with other improvements with respect to logging this makes debugging ShinyProxy on Kubernetes a lot easier.
For example, using the ShinyProxy Monitoring stack, the complete logs of a single app can be easily viewed in Grafana:
A final major improvement is the support for Shiny bookmarking. ShinyProxy is now able to track the URL of the app and reproduce changes in the URL (of the app) into the browser of the URL. In fact, this does not only work well with Shiny bookmarking, but with any web app.
Don’t hesitate to send in questions or suggestions and have fun with ShinyProxy!