Shiny enables you to build an interactive web application in R. Your app can access databases, run custom R code, and respond to users in real time. Shiny apps can be launched inside of Civis Platform, so your apps are secure and live alongside your other report deliverables in Platform.
Shiny apps are deployed using the Services tool in Platform. For more information on how to deploy your app, please visit the Civis Services page, or check out our quick start option below.
Quick Start
The fastest way to get started is to launch our Shiny Service Template. Navigate to the Publish menu and choose Shiny under the "Create from Template" header. On the service page, click "Start Deployment". This will start a preview of the demo application, with a link to clone the repository and start customizing your own.
Building your app from scratch
Alternatively, you can build your own app from scratch. To demonstrate the design, let’s create a simple R Shiny application. The first step is to click “Service Deployment” from the “Publish” menu.
Creating a New Service
After creating a new service, there are a number of parameters to configure, including “Git Connection”, “Docker”, and “Resources”.
Git Connection
The first configuration we need to set is our “Git Connection”. This is where we point our service to the code that it will be running. RStudio hosts a number of example Shiny applications at https://github.com/rstudio/shiny-examples, which we'll use to test Services.
To download the latest version of these examples, we’ll use the Git branch “main,” which is the conventional name in Git for the default branch. We could also use a commit hash or a Git tag here instead of a branch name.
To deploy an app within a folder of a repository, we need to set the “Path” parameter to the location of the app.R or server.R file. The app we’ll use is found in the folder 001-hello, so we’ll put this as the path of our Git Connection.
Docker
The next section is “Docker”, which configures the Docker image where we’ll be running our code. “Image Name” is the repository name on Docker Hub and “Tag” is the specific tag or version of the Docker image. Since civisanalytics/civis-services-shiny is the default Docker image for Services, we don’t need to change any Docker parameters to run an R Shiny Service.
Docker is an advanced tool for managing dependencies and environments, so it requires a bit of time to learn. There are many nice introductions on the web. If you’d like to dive in more we recommend this one.
Resources
Finally, we can configure the resources of our app in the Resources section. Here, we can set the amount of memory and compute our app requires and how many replicas to create (in order to serve many users simultaneously), and we can configure whether our app will remain available at all times or will sleep and conserve resources when it’s not being used.
If you are deploying multiple apps, it is a good idea to use as few resources as necessary to ensure that all the apps are speedy and not using up too many compute hours. For our preview, the defaults will work fine, so we don’t need to adjust them.
Now, after entering all of our configuration, we can start our app by clicking "Start Deployment". When you click this button, a preview of the app will load under the preview section of the configuration page.
Viewing a Preview of an App
Once we’re satisfied with how our app looks in Platform, we can edit parameters to optimize the viewing experience for other users. For example, I want to bump up the compute resources and turn on “Specific Times” so my app will be immediately available for users during the work week.
Scheduling an App
Once we’re finished configuring our app, we can click “Publish” to create a steamlined version of our app known as a “Service Report”. After initial publication, the “Publish” button will become a “View Report” button.
Viewing a Service as a Report
Instead of showing us the app on the same page, clicking on “publish” or "view report" redirects us to a new URL that looks like
https://platform.civisanalytics.com/#/reports/services/<some number>?fullscreen=true
This is the live URL for our app! We can share that link with our users and they will immediately be able to access the service. If your users aren’t in your default group, you may need to add them as viewers to the report. This can be done by clicking the share button in the upper right hand corner after minimizing the report.
Sharing a Report with New Users
The final task we need to do now is shut down this deployment so that we’re not using up resources with a service we don’t need. We can navigate back to the Services configuration screen from our report and then stop the deployment from there. We can always turn the service back on later, and all of our configurations will be saved.
Shutting Down a Deployment
Helpful Tips
Dependencies
Code put in `global.R` or at the top of `app.R` will be run once before the application starts up. Dependencies can be installed by adding a line such as:
- `install.packages(“my_package”) or `devtools::install_github(“my_repo/my_library”)` to one of these files.
- Note: civisanalytics/civis-services-shiny uses a checkpoint version of CRAN, so when using `install.packages` you may not install the latest version of your package from CRAN. Use `devtools::install_github` or specify “repos” in `install.packages` if a certain version is required.
Dependencies from private Github repositories can be installed using devtools if your Civis Platform profile includes Github Credentials.
- If your Service is using the civisanalytics/civis-services-shiny Docker image, your Github credentials are saved as the environment variable GITHUB_PAT instead of REPO_HTTP_TOKEN (the default). This is to comply with devtools.
Common Reasons for Shiny App Greying Out
1) If the Shiny app greys out, this means it has lost its connection to the Shiny server. To make sure your app connection does not time out and that the server reconnects when it does lose connection, you must add the following to your Shiny App:
If you don't have a www folder already, create a folder called "www" in your app directory and put this JavaScript file, named "keep-alive.js", inside
var socket_timeout_interval; var n = 0 ; $(document).on( 'shiny:connected' , function(event) { socket_timeout_interval = setInterval(function() { Shiny.onInputChange( 'alive_count' , n++) }, 30000 ); }); $(document).on( 'shiny:disconnected' , function(event) { clearInterval(socket_timeout_interval) }); |
In your ui.R, reference the keep-alive.js file somewhere in the fluidPage
fluidPage( tags$head(HTML(" <script type= 'text/javascript' src= 'keep-alive.js' ></script>")), ... ) |
Add these two lines to your server.R
shinyServer(function(input, output, session) { ... observe(input$alive_count) session$allowReconnect( "force" ) }) |
2) Another reason why the app might grey out is if the Shiny server is busy performing a computation. Shiny performs request handling and all computation in the same thread. This means apps which do a lot of computation block the process from handling additional web requests.
Consider doing these computations in a separate process by wrapping the computationally expensive parts of your app to run in parallel with mclapply or future and increase the CPU resources for your Service (1000 represents 1 core, 2000 represents 2 cores and so on).
3) If your Shiny app greys out immediately after loading, it is probably failing to start. If you have code in global.R
, it executes in between the time that the app "starts" and when the app is active and you see the UI. If the operations in your global.R take a long time, the app can appear to have failed to start, even though Platform says it is still running. There is a one-hour limit on the operations in global.R
, and if your app does not respond to web requests after that point it will be terminated by Platform to save resources.
Scaling & Performance Optimization
Shiny Apps are single-threaded. This means that they can only do one thing at a time, and has a few implications:
- A Shiny App cannot use more than 1000m of CPU by default. Unless you implement some sort of parallel processing, don’t request more than 1000 shares of CPU (which is equivalent to one CPU core).
- We’ve found that the typical, non-optimized Shiny App with 1000m CPU can handle about 7 concurrent users. If you anticipate more than 7 users needing to use your app simultaneously, you may want to increase the number of replicas for your service. Each replica will run independently and will not share state.
If you want to dive further into improving the performance of your Shiny App, RStudio has published helpful articles about caching, profiling, and asynchronous programming, among other topics.
Comments
0 comments
Please sign in to leave a comment.