Shiny Server Professional v1.0.0 Administrator's Guide

1 Getting Started

1.1 Introduction

Shiny Server enables users to host and manage Shiny applications on the Internet. Shiny is an R package which uses a reactive programming model to simplify the development of R-powered web applications. Shiny Server can manage R processes running various Shiny applications over different URLs and ports. Using Shiny Server offers a variety of benefits over simply running Shiny in R directly. These features allow the administrator to:

PRO

This manual describes Shiny Server Professional which offers, among other things, the following additional features:

1.2 System Requirements

Shiny Server is currently only supported on the Linux operating system. We officially support the following distributions:

We currently only support the x86-64 architecture. As described in the Installation section, you will install R and the Shiny package prior to installing Shiny Server. Root privileges will be required both in the installation process and also at runtime.

PRO

Shiny Server Professional allows you to host multiple R processes concurrently to balance the load of incoming requests across multiple Shiny instances. The Utilization Scheduler section explains how to configure this in more detail. We recommend carefully evaluating the computational properties and memory profile of a Shiny application using the tools discussed in the Admin section. This dashboard will provide much more insight into the profile of a Shiny application than was previously possible.

1.3 Installation

The Shiny Server installer does not come with R, nor does it provide the Shiny R package. Below are the steps for installing each of them separately.

If you had previously installed Shiny Server 0.3.x or 0.4.x, please see the relevant section before proceeding to ensure a seamless upgrade:

1.3.1 Ubuntu (12.04+)

Installing R

Shiny Server recommends an installation of R version 3.0 or higher. To install the latest version of R you should first add the CRAN repository to your system as described here:

You can then install R using the following command:

$ sudo apt-get install r-base

NOTE: if you do not add the CRAN Debian or Ubuntu repository as described above this command will install the version of R corresponding to your current system version. Since this version of R may be a year or two old it is strongly recommended that you add the CRAN repositories so you can run the most up to date version of R.

At this point, follow the instructions in Install Shiny to setup the necessary packages in R.

Once Shiny is installed, you can begin the installation of Shiny Server. You should have been provided with a .deb installer for Shiny Server. If you only have a link to this file, you can use wget to download the file to the current directory. You will need to first install the gdebi-core package to install Shiny Server and its dependencies. Once the .deb file is available locally, run the following commands to complete the installation of Shiny Server.

sudo apt-get install gdebi-core
sudo gdebi shiny-server-1.0.0.deb

This will install Shiny Server into /opt/shiny-server/, with the main executable in /opt/shiny-server/bin/shiny-server and also create a new shiny user. The rest of this guide will document the intricacies of how you can configure and manage Shiny Server. If you're just looking to get up and running quickly, we recommend you look at the Quick Start section in the appendix which will walk you through the process of installing and configuring a Shiny application.

1.3.2 RedHat/CentOS (5.4+)

Prerequisites

Shiny Server recommends an installation of R version 3.0 or higher. Shiny Server has several dependencies on packages (including R itself) found in the Extra Packages for Enterprise Linux (EPEL) repository. If you don't already have this repository available you should add it to your system using the instructions found here: https://fedoraproject.org/wiki/EPEL

After enabling EPEL you should then ensure that you have installed the version of R available from EPEL. You can do this using the following command:

$ sudo yum install R  

At this point, follow the instructions in Install Shiny to setup the necessary packages in R.

Once Shiny has been installed, you can begin the installation of Shiny Server. You should have been provided with an RPM file which contains Shiny Server and all of its dependencies (other than R and Shiny). You can install this rpm file using yum. If you have only a link to the RPM file, you can use wget to download the file to the current directory. You can install this RPM file using yum.

$ sudo yum install --nogpgcheck shiny-server-1.0.0.rpm

This will install Shiny Server into /opt/shiny-server/, with the main executable in /opt/shiny-server/bin/shiny-server and also create a new shiny user. The rest of this guide will document the intricacies of how you can configure and manage Shiny Server. If you're just looking to get up and running quickly, we recommend you look at the Quick Start section in the appendix which will walk you through the process of installing and configuring a Shiny application.

1.3.3 Install Shiny

Before Shiny Server can be installed, the Shiny package must be installed in the system library; you typically need sudo privileges to install to this library. Shiny Server currently requires Shiny version 0.7.0 or later. The following command will download and install the shiny package from CRAN in the system library.

$ sudo su - \
  -c "R -e \"install.packages('shiny', repos='http://cran.rstudio.com/')\""

Once this command completes, you can continue with the installation of Shiny Server.

1.3.4 R Installation Location

Shiny Server expects that R is available as an executable named R and is in the PATH of the user which you run shiny-server as. Note that on some CentOS systems, the PATH will be overridden by the startup script to /sbin:/usr/sbin:/bin:/usr/bin. On such systems, if R is not available in one of these locations (regardless of the user's PATH), you'll need to adjust the startup script.

To allow Shiny Server to search for R in additional locations, you'll alter the file in /etc/init.d/shiny-server or /etc/init/shiny-server.conf depending on which startup system you're using (as discussed in Stopping and Starting. You can either adjust the PATH variable to include the directory where R will be found, or you can set an environment variable named R to tell Shiny Server exactly where it should look for the executable.

If you choose to adjust the PATH, you can add the directory in which the executable named R is found to the line that defines the PATH environment variable (PATH=/sbin:/usr/sbin:/bin:/usr/bin).

If instead you choose to tell Shiny Server the exact executable to run (which is necessary if the executable is not named R on your system), you'll need to define a new environment variable named R. You can do this by adding a line that looks something like env R=/usr/local/bin/R-3-0-1 for Upstart, or export R=/usr/local/bin/R-3-0-1 for init.d.

1.4 Stopping and Starting

The installer will automatically deploy the necessary scripts to ensure that Shiny Server is started automatically on boot. When possible, we use the Upstart system to manage the shiny-server service. If Upstart is not available, we will deploy an init.d script to automatically start and stop the service.

1.4.1 Upstart

Upstart is a system used to automatically start, stop and manage services. The installer will automatically deploy an Upstart script to /etc/init/shiny-server.conf. This script will initialize shiny-server as soon as the network is activated on the machine and stop when the machine is being shut down.

The Upstart script will also ensure that shiny-server is respawned if the process is terminated unexpectedly. However, in the event that there is an issue which will consistently prevent Shiny Server from being able to start (such as a bad configuration file), Upstart will give up on restarting the service after approximately 5 failed attempts within a few seconds. For this reason, you may see multiple repetitions of a bad Shiny Server startup attempt before it transitions to the stopped state.

To start or stop the server, run the following commands, respectively.

$ sudo start shiny-server
$ sudo stop shiny-server

To restart the server you can run:

$ sudo restart shiny-server

This command will shutdown all running Shiny processes, disconnecting all open connections and will re-initialize the server. Note that restart will not reread the Upstart definition at /etc/init/shiny-server.conf. So if you have changed, for instance, some environment variables in that file. You will need to stop and start to have those changes take effect.

If you wish to keep the server and all Shiny processes running without interruption, but reload the configuration, you can use the reload command as in:

$ sudo reload shiny-server

This will cause the server to re-initialize but will not interrupt the current processes or any of the open connections to the server.

Known Bug: Due to a bug in the version of Upstart which comes with Ubuntu 13.04, reload will not behave as expected on that platform and should not be used.

To check the status or retrieve the Process ID associated with shiny-server, run the following:

$ status shiny-server

1.4.2 init.d

On some older Operating Systems (such as RedHat 5) the Upstart system may not be available. These systems will require the use of a script in /etc/init.d/ to start and manage the shiny-server daemon. This script does not have the capability to automatically restart the shiny-server daemon if it terminates unexpectedly. The installer uses chkconfig to ensure that shiny-server will start automatically on boot.

To start or stop the server, use the following commands, respectively:

$ sudo /sbin/service shiny-server start
$ sudo /sbin/service shiny-server stop

To restart the server, you can run:

$ sudo /sbin/service shiny-server restart

If you wish to keep the server and all Shiny processes running without interruption, but reload the configuration, you can use reload:

$ sudo /sbin/service shiny-server reload

This will cause the server to re-read the configuration file but will not interrupt the current processes and outstanding connections to the server.

To check the status or retrieve the Process ID associated with shiny-server, run the following:

$ /sbin/service shiny-server status

2 Server Management

2.1 Default Configuration

Initially, Shiny Server uses the following configuration file. Some users will find that this configuration meets their needs; others may find it useful to create a custom configuration. Details about each available setting and parameter are available in the Appendix. As a brief introduction, however, the following configuration file (available at /opt/shiny-server/config/default.config) is the default used if no other configuration file is provided:

# Define the user we should use when spawning R Shiny processes
run_as shiny;

# Define a top-level server which will listen on a port
server {
  # Instruct this server to listen on port 3838
  listen 3838;

  # Define the location available at the base URL
  location / {
    # Run this location in 'site_dir' mode, which hosts the entire directory
    # tree at '/srv/shiny-server'
    site_dir /srv/shiny-server;
    
    # Define where we should put the log files for this location
    log_dir /var/log/shiny-server;
    
    # Should we list the contents of a (non-Shiny-App) directory when the user 
    # visits the corresponding URL?
    directory_index on;
  }
}


# Setup a flat-file authentication system. {.pro}
auth_passwd_file /etc/shiny-server/passwd;

# Define a default admin interface to be run on port 4151. {.pro}
admin 4151 {
  # Only permit the user named `admin` to access the admin interface.
  required_user admin;
}

Lines beginning with a # are treated as comments and not parsed when configuring the server. Shiny Server can be configured to host multiple servers on different ports or hostnames. Each server can have locations which are capable of serving Shiny Applications and potentially static assets, as well. Individual applications can also override the settings applied to their parent location. These concepts are explained in further detail in the Server Hierarchy section. The default configuration above will create a single server listening on port 3838, serving any application contained within /srv/shiny-server/ at the root URL (/). Each possible setting in the configuration file is explained in the Appendix.

Most users will want to customize the configuration to meet their needs. The server will attempt to load its configuration from a file stored at /etc/shiny-server/shiny-server.conf; it is in this location that you should place your custom Shiny Server configuration. If this file is not found, the default will be used.

PRO

This configuration will also create an administrative dashboard running on port 4151. The admin interface requires that a user authenticate themselves, as discussed further in the chapter on Authentication & Security. The configuration will attempt to use a flat-file authentication system stored at /etc/shiny-server/passwd; an empty database is created for you here during installation. To create a new user named admin in this file to allow you to login to the dashboard, execute the following command

$ sudo /opt/shiny-server/bin/sspasswd /etc/shiny-server/passwd admin
and then enter and verify the password you wish to use for this user.

2.2 Server Hierarchy

Detailed descriptions of all available parameters are available in the appendix, but it is important to understand the overall hierarchy of the Shiny Server configuration file when editing the file.

2.2.1 Server

The server setting defines an HTTP server which will listen on a port/IP address combination. For example, the following lines:

server {
  listen 80;
}

define a server that would listen on port 80. A server can also define a server_name to limit the virtual hostnames on which it listens, as described in the Virtual Hosts section.

2.2.2 Location

The location setting is defined within a server and defines how a particular URL path should be served. For instance, the following settings:

server {
  ...
  # Define the location '/specialApp'
  location /specialApp {
    # Run this location in 'app_dir' mode, which will host a single Shiny
    # Application available at '/srv/shiny-server/myApp'
    app_dir /srv/shiny-server/myApp
  }
  
  # Define the location '/otherApps'
  location /otherApps {
    # Run this location in 'site_dir' mode, which hosts the entire directory
    # tree at '/srv/shiny-server/apps'
    site_dir /srv/shiny-server/apps;
  }
...
}

would define two locations, one which serves (potentially) a multitude of applications at the URL /otherApps/, and another which serves a single application at the URL /specialApp/. The various hosting models which can be applied to a location are described in the section on Hosting Models.

location directives can also be nested to provide more granular settings for a particular sub-location. For instance, if you used Google Analytics but the Finance department wanted to use its own Google Analytics ID for their finance directory, you could accomplish that with a configuration like:

server {
  ...
  # Define the '/depts' location
  location /depts {
    # Host a directory of applications
    site_dir /srv/departmentApps;
    
    # Provide a default/global GAID
    google_analytics_id "UA-12345-1";

    # Define the '/finance' location.
    # Corresponds to the URL '/depts/finance', and the filesystem path 
    # '/srv/departmentApps/finance' as defined by the parent location.
    location /finance {
      # Provide a custom GAID for only this sub-location
      google_analytics_id "UA-54321-9";
    }
  }
...

Note that the nested location's path is relative to the parent location's. Any directive that can be used for a location can be used in a nested location and will override the value specified in the parent, if any. If not overridden, the settings will be inherited by sub-locations from their parent locations.

2.2.3 Application

The application setting has been deprecated and removed from Shiny Server as of version 0.4.2.

See How Do I Translate My 'application' Settings to Nested 'location's? for help migrating.

2.3 run_as

Understanding which user will execute the R Shiny processes is important for a variety of reasons. For one, the paths in which R will look for packages (.libPaths()) are often user-dependent. In order to ensure that the libraries required to run a Shiny application are installed, you must first understand which user will be running the application. Additionally, directories will likely have restrictions regarding which users are able to read or write in them. The server should be configured in such a way that the user running the Shiny applications has the minimal privileges to do the work required by those applications.

locations configured with user_apps will be executed as the user in whose home directory the application was found. For locations configured with site_dir and app_dir, the run_as setting will be used to determine which user should spawn the R Shiny processes. This setting can be configured globally, or for a particular server or location. For example, the following configuration:

location / {
  run_as tim;
}

would execute all applications contained within this scope as the user tim with all of tim's relevant .libPaths.

2.3.1 Running Shiny Server with Root Privileges

Aside from spawning R Shiny processes as particular users, the shiny-server process itself can be configured to run as different users to control its privileges. There are three scenarios in which Shiny Server would need to be run as root:

  1. If user_apps is enabled for any location. In order to host applications as various users, Shiny Server must have root privileges.
  2. If your configuration uses run_as to spawn applications as multiple different users.
  3. If you're running any server on a privileged port (a port in the range of 1-1024).
By default, the shiny-server process will be started as the root user, then will spawn R processes according to the corresponding run_as setting. You can, however, run the shiny-server process as a non-privileged user such as the shiny user if none of the three limitations above are violated. PRO

For Shiny Server Pro, if it detects that it is running as root but has no need to (i.e. none of the three criteria above were met), then it will drop its privileges and run as an unprivileged user; note that, for security reasons, that change is irreversible. This means that once Shiny Server drops its privileges, it wouldn't be able to regain them should a new configuration be loaded that requires such privileges.

By default, if shiny-server detects that it doesn't need to run with root privileges, it will attempt to run as an unprivileged user to be more secure. It will determine which user to run as by inspecting the run_as directives in your configuration file -- if there is only one user which we will be running Shiny as (and the aforementioned constraints are satisfied), the entire Shiny Server process will just run as that user. The default configuration sets run_as to shiny, so the process will run as the shiny user. While the process will run as the shiny user (or whatever other user you're running as), it may not behave in exactly the same way as interactively logging in as that user. In particular, no startup scripts (such as .bashrc files) will be executed, and supplemental groups in which the user is a member will not be set.

Be aware that upon installing Shiny Server, permissions on the file system are set to enable the shiny user to read and write from various directories as is necessary to allow Shiny Server to run as the shiny user. Running Shiny Server as another user will require that you adjust the permissions to grant this other user the necessary privileges to run Shiny Server. In particular, ensure the user has write privileges on these paths (recursively):

and read privileges on these paths (recursively):

Finally, if the directory /tmp/shiny-server/ exists, it (and all files within it) should be owned by the user you specify.

2.4 Local App Configurations

In the global configuration file, the allow_app_override setting can be specified to enable local app configurations. If present, this setting enables owners of Shiny applications to customize the properties of their own applications using a file named .shiny_app.conf. This file can be placed within an application directory (alongside the server.R and ui.R files) and can contain settings which configure how Shiny Server should manage the application.

This behavior is controlled by the allow_app_override setting which is disabled by default. In order to enable local application configurations, you can add to your configuration file allow_app_override true; (or just allow_app_override; for short).

Server administrators should be mindful of the fact that allowing application owners to specify their own scheduler parmeters has potential performance implications, as an application owner could enable his or her application to consume more resources than is desired. It is thus recommended that write privileges on the .shiny_app.conf files be granted judiciously in the underlying filesystem.

2.5 Hosting Model

There are currently four different methods of configuring a location, three of which serve Shiny applications. These three are described below; see the following section on Redirecting to learn about a fourth mode.

2.5.1 Host a Directory of Applications

A location which uses site_dir will host an entire directory tree -- both Shiny Apps and static assets. This is the location used to serve an asset or application in /srv/shiny-server/ in the default configuration that ships with Shiny Server.

# Define the location '/'
location / {
  site_dir /srv/shiny-server/
}

The above configuration would instruct Shiny Server to make the /srv/shiny-server/ directory available at the base URL. Any Shiny applications stored in this directory (or any subdirectory), along with any static assets (including images, data, JavaScript/CSS files, etc.) will be made available at the corresponding URL. For example, see the following directory tree:

+---/srv/shiny-server
|   +---shinyApp1
|       +---server.R
|       +---ui.R
|   +---shinyApp2
|       +---server.R
|       +---ui.R
|   +---assets
|       +---style.css
|       +---script.js

If this server were available at http://server.com, the location settings above would make the following (along with any other file in the tree) publicly available to the user.

URL Definition
http://server.com/shinyApp1 Serve the Shiny App defined in 'shinyApp1'
http://server.com/shinyApp2 Serve the Shiny App defined in 'shinyApp2'
http://server.com/assets/style.css Serve this static CSS file
http://server.com/assets/script.js Serve this static JS file

2.5.2 Host a Single Application

A location configured to use app_dir will attempt to serve a single application hosted at the given directory. For instance,

# Define the location '/specialApp'
location /specialApp {
  app_dir /srv/shiny-server/myApp;
}

will configure the location responsible for the path /specialApp to use this app_dir router which serves a single application stored in the directory /srv/shiny-server/myApp. This configuration would presume a server.R file (and corresponding ui.R file) would be available at /srv/shiny-server/myApp/server.R. If so, the application saved there would be available at a URL like http://server.com/specialApp.

2.5.3 Host Per-User Application Directories

A location configured to use user_apps will allow users on the system to create and manage their own Shiny applications available in their home directories. This directive will host any application stored in an eligible user's ~/ShinyApps directory publicly at a URL prefaced by their username.

This privilege can be restricted only to users of particular groups using the members_of restriction. For instance, the following configuration:

# Define the root location
location / {
  user_apps;
  
  # Only allow members of the 'shinyUsers' group to host personal applications.
  members_of shinyUsers;
}

will -- for any user who is a member of the shinyUsers group -- publicly host any Shiny application available in the user's ~/ShinyApps directory. For instance, if tina is a user on this system and is also a member of the shinyUsers group, any application stored in /home/tina/ShinyApps/, such as the shinyApp1 application, would be available on this server at a URL like http://server.com/tina/shinyApp1, assuming /home/tina was tina's home directory.

2.6 Redirecting

The final mode in which a location can operate is to redirect to another URL. Such locations will immediately send a response to the client informing them of the URL to which they should redirect and the status code that should be used when informing the client of the redirection. Typically, a redirect will use the 301 status code for a permanent redirect, or a 302 status code for a temporary redirect. The final option when configuring a location for redirection is whether or not it should use exact matching. If a redirecting location is configured to use exact matching, only requests for that exact URL will be redirected. If not, any requests for that URL path or any subpath of that URL will be redirected. For example,

# Define a location at the base URL of this 'server'
location / {
  # Redirect traffic from '/shinyApp1/' to 'http://server.com' temporarily.
  location /shinyApp1 {
    redirect "http://server.com" 302 true;
  }
}

will redirect any requests for the exact path /shinyApp1 to http://server.com temporarily.

2.7 Virtual Hosts

The server_name setting allows Shiny Server to route incoming requests to a particular server element based on the hostname of the request. This will serve as an additional level of filtering on incoming traffic. Bear in mind that traffic must be destined for this server (i.e. traffic which was bound for the IP address and port on which this server was listening) in order to even be evaluated for a matching hostname.

The example below may clarify the configuration

server {
  # Instruct this server to listen to port 80
  listen 80;
  
  # Only accept requests for the hostname 'server1.com'
  server_name server1.com;
  
  # Define the location for this server.
  location / {
    site_dir /srv/shiny-server1;
    log_dir /var/log/shiny-server1;
  }
}

server {
  # Instruct this server to listen to port 80
  listen 80;
  
  # Only accept requests for the hostname 'server2.com'
  server_name server2.com;
  
  # Define the location for this server.
  location / {
    site_dir /srv/shiny-server2;
    log_dir /var/log/shiny-server2;
  }
}

This example presupposes that, on this network, the domains server1.com and server2.com both resolve to the same IP address. In the configuration above, we first create a server that listens on port 80 and will only accept traffic whose hostname matches server1.com. We then configure a server which will also listen on port 80 and require that it only accept traffic whose hostname equals server2.com.

This configuration would allow an application stored in /srv/shiny-server1/shinyApp to be accessible at http://server1.com/shinyApp and an application stored in /srv/shiny-server2/shinyApp to be accessible at http://server2.com/shinyApp.

2.8 Server Log

All information related to Shiny Server, rather than a particular Shiny application, is logged in the global system log stored in /var/log/shiny-server.log. This log should be checked often to ensure Shiny Server is performing as expected. Any errors and warnings which Shiny Server needs to communicate will be written here.

If logrotate is available when Shiny Server is installed, a logrotate configuration will be installed. The default configuration is to rotate the logfile when it exceeds 1MB. The old log file will be compressed and stored alongside the original log file with a .1.gz extension (then .2.gz, etc.). Up to twelve archived log files will be maintained; upon the 13th log rotation the oldest log file will be deleted.

For logs related to individual Shiny Applications, see the section on Logging and Analytics.

2.8.1 Access Logs

An access log can be configured globally using the acces_log parameter. This log is not enabled by default. This setting controls the location of the access log as well as the format used. The access log can be useful to audit the security and activity taking place on your Shiny Server installation. These logs can be audited manually or automatically to inspect how often various resources are being accessed, or by whom they are being accessed (using the originating IP address). Currently, one access log is created for the entire Shiny Server process; all Shiny applications share this access log.

The access logs will be written using the Connect logging libraries, so additional details can be found in their documentation in the "Formats" section. In brief, there are four pre-defined logging formats for access logs specified in the documentation referenced above:

For example, the following would configure an access log that uses the tiny format:

access_log /var/log/shiny-server/access.log tiny;

server {
  ...

2.9 Health Check Endpoint

Some advanced deployment scenarios are able to leverage a "health check endpoint" which provides an automated way to ensure that Shiny Server is online and responsive. The URL /ping can be used on any port Shiny Server is instructed to listen on in order to test the health of Shiny Server. If the server is online and responsive, it will respond with the text OK and an HTTP 200 code.

2.10 Environment Variable Settings

We strive to expose most settings through the configuration file described previously. However, there are some settings that we don't include in the configuration file which some users may still wish to change. Where possible, we'll allow users to configure these settings using environment variables. Some of these environment variables will later be promoted to configuration directives, but will be documented here until that time.

Typically, it is best to define these environment variables in the startup script used to run Shiny Server (often either /etc/init.d/shiny-server or /etc/init/shiny-server.conf, depending on whether or not you're using Upstart).

2.10.1 SHINY_LOG_LEVEL

Defines the verbosity of logging which will be used by Shiny Server. Valid options -- in level of increasing verbosity -- are TRACE, DEBUG, INFO, WARN, and ERROR. More verbose levels of logging (such as TRACE) may be helpful when debugging an issue or trying to understand exactly what Shiny Server is doing, but will likely be far too much information for a system with even moderate load.

The default if this environment variable is not found is to use INFO.

2.10.2 R

Defines the path to the R executable which should be used when running Shiny. Systems which have multiple versions of R installed, or don't wish to place R on the path before starting Shiny Server can override this setting to point to a particular version of R.

If no environment variable is found, Shiny Server will expect an executable named R to be on the path.

2.10.3 SHINY_DATA_DIR

The historical databases of Shiny applications used in the Admin dashboard can consume multiple Gigabytes of disk space on a system hosting many applications. This environment variable allows you to define the directory in which Shiny Server should persist data to disk. To estimate the amount of disk space required, we recommend reserving 10MB in this directory for every Shiny application you plan to host on a server. Additionally, ensure that this directory is writable by the shiny user, or whichever user you're running Shiny Server as (as is discussed in detail in the run_as section).

Note that Shiny Server expects a directory named monitor/rrd/ to already exist inside SHINY_DATA_DIR when it starts.

By default, Shiny Server will create and store data in /var/lib/shiny-server/.

3 Deploying Applications

3.1 Schedulers & Application Restarts

A scheduler is responsible for fulfilling incoming requests to a particular application. Each version of an application (see below) will have its own associated scheduler. Each scheduler can have different properties to control things like how many concurrent connections it should accept.

A scheduler can be specified at many locations in the configuration file and will be inherited to inner blocks. For instance, a scheduler definition found in a server block will be applied to every location in that server, unless overridden.

3.1.1 Restarting an Application

Some changes you make to the code, assets, or environment of an application will require the application's R processes to be restarted for the changes to take effect. These include upgrades to packages that are used by the application, changes to .Renviron/.Rprofile or other R source files, or modifications to data files that are read only at startup time.

(Fortunately, Shiny applications generally do not need to be restarted when changes to ui.R or server.R are made, as Shiny will check for changes to these files on page load.)

An application can be restarted by altering the "modified time" on a file named restart.txt in the application's directory. This can most easily be done using the touch utility as in touch restart.txt which will update the modified timestamp on this file to the current time. Upon the next new connection to the application, Shiny Server will spawn a new R process to run the "new" (restarted) Shiny Application for this and future users. When this occurs, the old processes will remain unaltered, and open connections will remain active and valid until the last connection closes itself.

This can cause unintuitive consequences regarding the number of processes that may be running for a given application. Even if using a single-process Simple Scheduler for an application, it is possible that there would be multiple R processes associated with this application, each corresponding to a separate restart timestamp. This behavior is likely to change in future versions of Shiny Server.

3.1.2 Simple Scheduler

The Simple Scheduler is the only scheduler available in the Open Source edition of Shiny Server. It associates a single R process with a single Shiny application. This scheduler accepts a single parameter which specifies the maximum number of concurrent sessions. Once this number is reached, users attempting to create a new session on this application will receive a 503 error page.

# Define a new location at the base URL
location / {
  # Define the scheduler to use for this location
  simple_scheduler 15;
  
  ...
}

In this example, the location defined at the base URL in this server will be configured to use the Simple Scheduler and to limit each application to a maximum of 15 simultaneous connections -- meaning that if there are 15 active connections on the application when a user attempts to visit this application, that user will receive a 503 error page. When one of the 15 active connections is disconnected, one new "seat" will be available for another user to connect to the application.

3.1.3 Utilization Scheduler

The Utilization Scheduler is a more sophisticated scheduler only available in Shiny Server Professional that allows a single Shiny application to be powered by multiple R Shiny processes. Incoming traffic will be routed to the R process associated with this Shiny application which has the fewest current connections.

The Utilization Scheduler is configured by three parameters.

As an example:

location /shinyApp1 {
  # Define the scheduler to use for this application
  utilization_scheduler 5 0.5 3;
  
  ...
}

The above configuration would create a Utilization Scheduler for this application which would support a maximum of 3 processes, a maximum of 5 connections per process, and a load factor of 0.5. Initially, only one process would be created to facilitate the first and second concurrent connection to this application. The third connection, however, would surpass the load factor (3/5 > 0.5) which would spawn a new R process. The next request would then be routed to this new process. This would continue until the load factor was again surpassed, at which point the third process would be spawned. With a maximum of 3 processes, no more would be created after the third. So the 16th concurrent connection would be turned away with a 503 error.

Be aware that, upon the restart of an application using a Utilization Scheduler, the resources allotted to this application will effectively double for a time. For instance, if an application is configured to use 4 maxProc and has sufficient load to create and maintain that many R processes, a restart of the application will motivate Shiny Server to create an R process for a "new" Shiny application which also is eligible to run up to 4 Shiny processes in parallel. Thus, with one restart and sufficient traffic to this application, it is possible that it could be running 8 Shiny processes. This behavior is likely to change in future versions of Shiny Server.

3.2 Application Timeouts

Each Shiny Application has two timeouts associated with it:

  1. app_init_timeout -- Describes the amount of time (in seconds) to wait for an application to start. After this many seconds if the R process still has not become responsive, it will be deemed an unsuccessful startup and the connection will be closed.
  2. app_idle_timeout -- Defines the amount of time (in seconds) an R process with no active connections should remain open. After the last connection disconnects from an R process, this timer will start and, after the specified number of seconds, if no new connections have been created, the R process will be killed.

Typically, these two parameters will be correlated. Shiny Applications which involve little processing to start (therefore have a small app_init_timeout) can often be closed with minimal concern (thus would have a small app_idle_timeout). Conversely, applications which require a substantial amount of data to be loaded on startup may merit a longer app_init_timeout to give the data time to load, and a longer app_idle_timeout as the task of spawning a new process is more expensive and should be minimized.

3.3 Session Timeouts

The app_session_timeout setting can be used to automatically disconnect idle Shiny connections. The setting accepts a single parameter which dictates the number of seconds after which an idle session will be disconnected. Here "idleness" is measured by a connection's interaction with the server. Incoming or outgoing data will reset the countdown time for this user's session. If the number of seconds specified elapses without any data being sent to or from this client, the user's session will be disconnected.

This parameter can be configured as a setting globally, or of a particular serveror location. It can be used to ensure that stale R processes are eventually closed by terminating sessions after they become idle for some period of time.

Session timeouts are configurable on a per-server or per-application basis. Controlling the session timeout can be important in helping the administrator manage the resource allocation for a given application and in freeing up resources from idle connections which will then be available to newly created sessions.

3.4 Logging and Analytics

3.4.1 Application Error Logs

Error logs are created for each R Shiny process separately. For locations configured to use user_apps, these logs are created in each user's ~/ShinyApps/log/ directory. For locations configured with app_dir or site_dir, the directory in which these logs are created is managed by the log_dir setting, which can be specified globally, for a particular server, or for a particular location. By default, these logs will be located at /var/log/shiny-server/. To change these locations, the log_dir can be specified in the following way:

location / {
  log_dir /var/log/shiny-server/;
}

The log files will be created in the following format:

<application directory name>-YYYMMDD-HHmmss-<port number or socket ID>.log

Log files will be created for each R process when it is started. However, if a process closes successfully, the error log associated with that process will be automatically deleted. The only error log files that will remain on disk are those associated with R processes that did not exit as expected.

If you're looking for log messages related to Shiny Server itself -- rather than individual Shiny applications -- see the section on the Server Log.

3.4.2 Google Analytics

Shiny Server is capable of automatically inserting the necessary JavaScript code to enable Google Analytics tracking globally or for a particular server or location. This is managed by the google_analytics_id setting which can be used as follows:

location / {
  google_analytics_id UA-12345-1;
}

3.5 Memory Limits

Memory limits will be added in a coming version of Shiny Server Professional.

3.6 Reactivity Log

The reactivity log is a great browser-based tool for analyzing and debugging reactive dependencies in a Shiny Application. We strongly recommend that you read the Overview of Reactivity in the Shiny tutorial to get the most out of the reactivity log. The symbols and representations introduced in that article are reused in the log. This tool should not be used in a production environment, as it exposes details that should not be publicly available. Many application authors find it to be a useful tool to use locally, however.

Currently, reactivity logs are maintained for an entire R process. Therefore, it should be used in a fresh R session in which only one Shiny application is active. To enable the reactivity log, run the command options(shiny.reactlog=TRUE) before running your application. Once you've started your application and are viewing it in a browser, you can use Ctrl+F3 (or Command+F3 for Mac users) to view the reactivity log. This visualization creates a snapshot of all reactive activity that had occurred up to the moment it was created. If you want to view the reactive activity that has occurred since opening the reactivity log, you'll need to refresh the browser.

The showReactLog() function exposes this functionality from within R and can be used outside of strictly Shiny contexts to generate a static HTML file visualizing reactivity. You can see the full documentation using ?showReactLog in R.

As the reactivity log exposes the architecture and some of the code behind your application, it would likely be unwise to enable this feature in a production environment. Unless explicitly enabled by the user, Shiny Server will not enable this functionality. We recomend using the reactivity log in a local R process not managed by Shiny Server.

3.7 Specifying Protocols

Shiny Server can use a wide variety of techniques to keep the data in the web browser synchronized. The preferred technique, and the one most widely used, is the use of WebSockets. However, if WebSockets are not supported -- either by some intermediate network between Shiny Server and your client or by your client's web browser -- then a fallback protocol will be used. In total, Shiny Server provides nine different methods of connecting to the server in real-time. In order of preference, they are:

  1. WebSocket
  2. XDR Streaming
  3. XHR Streaming
  4. iframe Eventsource
  5. iframe HTML File
  6. XDR Pollilng
  7. XHR Polling
  8. iframe XHR Polling
  9. JSONP Polling

Each of these will be tried by the client in order until a successful connection to Shiny Server. If you would like to omit one or more of these protocols from the list for whatever reason, you can currently do so only from the client (we hope to make a server-side configuration available in a future release of Shiny Server).

To change the available protocols, you can open any Shiny Application and press the keyboard shortcut: Ctrl+Alt+Shift+A (or, from a Mac: control+option+shift+A). This will bring up a window that will allow you to select or deselect any of the above protocols. After confirming your changes these settings will be saved in your browser for future visits to this server. These settings will take effect upon loading any Shiny application hosted on this domain and will last until you explicitly change them again.

4 Authentication & Security

4.1 Authentication Overview

Shiny Server Professional offers the ability to authenticate individual users. By specifying authentication requirements on particular servers or locations, the administrator can control the set of applications particular users are allowed to access.

Authentication can be implemented by integrating into an existing LDAP or Active Directory database, or by using a "flat-file" authentication system which is simply contained in a local file. To ensure that your users' passwords are being protected, it is strongly encouraged that any Shiny application requiring authentication use SSL to encrypt the usernames and passwords being transmitted.

The current user's username and groups (where applicable) will be available in Shiny (version 0.8 and later) in the session parameter of the shinyServer function. For instance:

shinyServer(function(input, output, session) {
  output$username <- reactive({
    session$user
  })
  
  output$groups <- reactive({
    session$groups
  })
})

4.2 Auth Duration

Regardless of which authentication mechanism is used, the duration of authentication can be configured using the auth_duration setting. This setting controls the amount of time (in minutes) for which a user should remain logged in after the finish using their last application. This setting should be set to 10 minutes or greater.

4.3 Flat-File Authentication

Shiny Server offers flat-file authentication as a simple and easy-to-configure authentication mechanism. This method is self-contained and not integrated into either the system's user/password database, nor any Enterprise authentication mechanism. Thus, usernames and passwords must be created explicitly for each user that should exist in Shiny Server.

The storage of usernames and passwords is handled by a single file which can be specified using the auth_passwd_file setting as follows:

run_as shiny;

auth_passwd_file /etc/shiny-server/passwd;

server {
  location / {
    ...

This will instruct Shiny Server to lookup all usernames and passwords in the file stored at /etc/shiny-server/passwd. This file should have zero or more lines in the format username:{scrypt-hashed-password}. The scrypt encryption algorithm is used to protect users' passwords from theft; the hashed passwords are expected in this file in base64 format. We provide the sspasswd utility with Shiny Server Professional that vastly simplifies the process of managing these "sspasswd" files.

You'll want to think carefully before adjusting the permissions on this file. For instance, if you were to enable the shiny user to write to your password database, any Shiny application running as shiny (the default) would now be able to modify your password database. Because the passwords are securely hashed, granting shiny read access to this file is not problematic and, in fact, is enabled by default.

4.3.1 sspasswd

The sspasswd utility comes with Shiny Server Professional and can be used to manage the username/password file. By default, it is not made available on the PATH but you can find it in opt/shiny-server/bin/. The general pattern for the utility is to provide the file to use for storage followed by a username, as in:

$ sudo /opt/shiny-server/bin/sspasswd /etc/shiny-server/passwd tina

To create a (or overwrite an existing) password file, use the -c switch. The default behavior will be to add the username specified (tina, in the example above) to the file after prompting the user for a password (or reading it from stdin). To instead delete a user from the file, use the -D switch. User/password combinations can be verified using the -v switch. Finally, the -C switch will set the maximum amount of time (in seconds) for encryption. The larger this value is, the more secure the password hash will be.

Currently, the ':', '$' and newline ('\r' or '\n') characters are prohibited in usernames.

4.4 LDAP and Active Directory

Lightweight Directory Access Protocol (LDAP) is a popular protocol for storing and validating user information in an enterprise. LDAP can store information about users and their group memberships which Shiny Server Pro is able to query using user's username and password. Fundamentally, the LDAP protocol simply describes a framework for storing hierarchical data and can be configured in a multitude of ways. Active Directory is one popular directory service which implements LDAP and encourages a certain model for storing data, while other vendors of LDAP systems often have their own distinct default configurations. A holistic overview of LDAP is outside of the scope of this document, so if you lack a solid background in LDAP you might benefit from consulting with an LDAP administrator in your organization to configure these settings.

An LDAP configuration in Shiny Server Pro might look like this:

auth_ldap ldap://ldap.example.org/dc=example,dc=org {
  group_filter "memberUid={username}";
  group_search_base ou=Groups;
}

It is fully possible to use the auth_ldap configuration to integrate with an Active Directory system. However, Active Directory encourages a certain pattern which we capture in the auth_active_dir directive which extends auth_ldap. The hope is that this configuration can be used to make setup simpler for groups using Active Directory. If you're using an Active Directory server, you may just be able to specify the auth_active_dir setting and not worry about providing any of the others.

An Active Directory configuration setting may look something like the following:

auth_active_dir ldaps://dc01.example.org/dc=example,dc=org example.org{
  trusted_ca /etc/ssl/certs/example-org.cert;
}

We currently support only a limited subset of Unicode characters as usernames for LDAP and Active Directory. Usernames must include only:

We do not permit empty usernames or passwords.

The parent directive for all LDAP-related settings is auth_ldap or auth_active_dir. Both accept an LDAP URL as their first argument. auth_active_dir accepts a second argument which is the suffix (typically a domain name) to be added to all usernames when attempting to bind. All other children settings within this directive are not required, but may be needed depending on your LDAP configuration.

The LDAP URL should look like the following:

ldaps://ldap.example.org:1234/dc=example,dc=org

It begins with the protocol to be used when contacting the LDAP server -- either ldap:// (for unencrypted LDAP) or ldaps:// (LDAP over an encrypted SSL tunnel). We do not currently support StartTLS. If your LDAP server supports ldaps://, this option is more secure and ensures the username and passwords aren't being transmitted between Shiny Server and your LDAP server in plain text. Next, the hostname or IP of the LDAP server should follow the protocol. Bear in mind that the given hostname or IP must match the hostname associated with the SSL certificate if using ldaps://. If using a non-standard port (anything other than 389 for ldap:// or 636 for ldaps://), you can follow the hostname with a colon and the port number which should be used. Following the hostname/port should be a forward slash then the root DIT of the directory to use.

There are a variety of settings which will be used to guide Shiny Server Pro's interaction with your LDAP server. These will all be defined inside of an auth_ldap or auth_active_dir setting and are described below. Be aware that the primary difference between auth_ldap and auth_active_dir is the default values assigned to these settings. If any of these settings are not specified, the default values will be used.

Some of the settings may include dynamic values which will be listed under the "Variables Available" section in each. These variables are enclosed in curly braces ("{" and "}") and will be replaced with their value before being used.

4.4.1 user_bind_template

Shiny Server Pro will transform the username entered at the login screen before attempting to "bind" (authenticate) to the LDAP server using this template. In general (notable exception being Active Directory), this pattern should map the given username to the user's DN in the LDAP database. In systems where that may not be possible (such as Active Directory), you can use the [user_filter] setting to lookup the user's DN given their username. In either case, this setting should manipulate the given username into the username used to perform the LDAP bind operation.

Variables Available

Default Value

4.4.2 group_search_base

Defines the subtree in which groups are stored. This will be used as the root of all LDAP queries which attempt to find the groups of which a user is a member. The given value will be followed by a comma and the root DIT given in the auth_ldap or auth_active_dir parent setting. If configured to use an empty string as the base, then the unmodified root DIT will be used as the group search base.

Default Value

4.4.3 group_filter

The LDAP query to use in determining a user's group membership. The query should return all groups of which the given user is a member

The default for auth_ldap checks the uniqueMember field -- a setting from the groupOfUniqueMembers LDAP class. If you're using the posixGroup LDAP class to store your group memberships, you should likely set this value to memberUid={username}.

Variables Available

Default Value

4.4.4 group_name_attribute

The attribute of the LDAP group object in which the group name is stored. This field will be compared to the entries in the required_group setting to determine whether or not a user should be granted access to a Shiny application.

Default Value

cn

4.4.5 trusted_ca

By default, Shiny Server Pro trusts many standard SSL Certificate Authorities (CAs) (such as Verisign). If your organization uses a non-trusted Certificate Authority to sign its SSL certificates, you will need to explicitly tell Shiny Server Pro to trust this CA's certificate. You can do this by placing the CA's certificate (in PEM format) in a file on your machine and pointing this setting to that file.

If this value is provided, the standard list of trusted CAs will be overridden with the provided certificate.

Default Value

None.

4.4.6 check_ssl_ca

When using LDAP over SSL (ldaps://), Shiny Server Pro will check that the SSL certificate was signed by a recognized Certificate Authority (CA) (though this can be modified using the trusted_ca setting). check_ssl_ca can be used to disable the checking of CAs entirely. By default, this option will be 'true' to enable SSL CA validation.

Disabling these checks is necessary if your LDAP server uses a self-signed certificate, for instance. Otherwise, this setting should typically be left enabled as disabling it will largely defeat the security gained by using SSL.

Default Value

true

4.4.7 user_filter

Some systems (notably many Active Directory implementations) do not use the username as a part of the user's DN. In such systems, It may be necessary to perform an extra LDAP query after binding to determine the user's DN based on their username before group membership can be determined. This setting stores the LDAP filter used to find the user object which matches the entered username.

Using the default provided for auth_active_dir (userPrincipalName={userBind}), as an example. Shiny Server Pro will attempt to bind to the LDAP server using the given username (after being manipulated as defined in user_bind_template) and password. If successful, it will then search for an object whose attribute userPrincipalName matches the username manipulated by user_bind_template. If found, the returned object's DN will be made available to the group_filter as the {userDN} variable.

Default Value

4.4.8 user_search_base

Defines the subtree in which users are stored. This will only be used if user_filter is not empty, as that is the only time that Shiny Server Pro would need to search for a user. If provided, this will be used as the root of the LDAP queries used to lookup a user by his or her username. The given value will be followed by a comma and the root DIT given in the auth_ldap or auth_active_dir parent setting. If configured to use an empty string as the base, then the unmodified root DIT will be used as the user search base.

Default Value

4.5 Required Users & Groups

4.5.1 User Authentication

The required_user setting controls which users should be able to access a particular server, location, or admin, as in:

location /app1 {
  required_user kim tom;
}

This directive would enable authentication on the specified location, which would present any new, un-authenticated visitor to the application with a login page. If the visitor entered valid credentials against your configured authentication mechanism, then he or she would be checked against the list of allowed users for this application. If found (i.e. if the user name was either kim or tom), the visitor would be granted access to the application. Otherwise, he or she would be unable to access the application.

It is encouraged that any server accepting user credentials be secured via SSL.

4.5.2 Group Authentication

The required_group setting allows the administrator to control access based on the groups of which users are a member. In this way, entire sets of users can be granted access to a particular location in one line in the configuration file.

Flat-file authentication does not support the notion of user groups, but this feature can be used with LDAP or Active Directory.

4.6 Proxied Headers

Typically, HTTP headers sent to Shiny Server will not be forwarded to the underlying Shiny application. However, Shiny Server Professional is able to forward specified headers into the Shiny application using the whitelist_headers configuration directive, which can be set globally or for a particular server or location.

server {
  listen 3838;
  whitelist_headers myorg_username myorg_groupnames myorg_privileges;
  
  ...

}

The above configuration would allow the three listed myorg_ headers (case-insensitive) to be forwarded from the originating HTTP traffic into the Shiny session. In Shiny, these headers would be converted to capital letters and prefaced with HTTP_ to designate that the headers originated in an HTTP request. They would then be available as objects in the session$request environment inside an application's server.R file. For example, the myorg_username object could be accessed via the following server.R file.

library(shiny)
shinyServer(function(input, output, session){
  output$username <- renderText({
    session$request$HTTP_MYORG_USERNAME
  })
})

Organizations which employ a centralized authentication system not supported by Shiny Server may use this feature to leverage a proxied authentication system. In such a model, traffic destined for Shiny Server Professional would first be sent through an authenticating proxy which would take care of ensuring that the user is authenticated and the appropriate headers are set indicating the user, groups, or permissions. The application deployed on Shiny Server Professional would then use these headers to determine whether the user should be allowed access to the application, or a subset of the features of the application.

Be aware that, in such a model, the entirity of the ui.R file will be run and passed to the client before the server-side has a chance to make any decision about what privileges the current user should have given their HTTP headers (if any). So the proxy must be responsible for authenticating or rejecting visitors prior to forwarding any traffic to Shiny Server Professional if any sensitive information would be disclosed by a user merely opening the UI. Additionally, precautions should be taken to ensure that the Shiny Server machine is not accessible directly by users, but is instead only accessible through the authenticating proxy. Otherwise, an attacker would merely need to provide fraudulent HTTP headers when accessing Shiny Server in order to imitate another user or claim particular privileges.

4.7 SSL

In Shiny Server Professional, SSL encryption is available for any configured server and in the admin interface. SSL is a means of encrypting traffic between web clients and servers and should be used for any application that will accept or transmit sensitive information such as passwords. Untrusted SSL certificates can be generated locally by anyone for free; signed SSL certificates can be obtained from authorized certificate authorities fairly inexpensively. Untrusted SSL certificates will still encrypt the traffic between a client and server, but (in most browsers), the client will need to proceed through a warning about the untrusted nature of the SSL certificate in use. SSL can be enabled on a server by configuring the two required parameters: the path to the SSL key, and the path to the SSL certificate.

server {
  # Instruct this server to listen on port 443, the default port for HTTPS 
  # traffic
  listen 443;
  ssl /etc/shiny-server/ssl-key.pem /etc/shiny-server/ssl.cert;
  
  ...
}

If a valid SSL key and certificate were provided, a user would now need to preface their request with "https://" to be able to visit any application hosted within this server or on the admin. It is highly recommended that any Shiny Server Pro configuration which expects to accept its users' LDAP or Active Directory credentials use SSL to secure the usernames and passwords on their applications and admin interface.

5 Admin

5.1 Configuration

The Admin interface provided as a part of Shiny Server Professional is disabled by default. To enable it, use the admin setting and specify the port number on which the admin interface should run.

admin 3957 {
  required_user tom sarah;
}

The above would enable the admin interface on port 3957. This interface would then be available from any modern web browser on that port. First-time visitors would be presented with a login page. If the visitor were able to authenticate themselves to the Shiny Server application as either tom or sarah, they would be granted access to the admin dashboard.

The required user must be one connected to Shiny Server as described in Authentication & Security.

You can also leverage SSL to secure the usernames and passwords accepted on the admin login screen.

5.2 Organization

The admin interface offers a real-time view into the current state of your Shiny Server. There is no need to refresh the page periodically, as the information is updated as it happens. The interface is divided into four main sections.

Dashboard

Initially when logging in, the user will be presented with the Dashboard view. This view shows a basic overview of the state of Shiny Server, including the current RAM and CPU utilization, the number of connections, and historical RAM and CPU saturation.

Applications

The highest-level grouping in the admin interface is the notion of an "Application." An application represents a Shiny App stored in a particular directory on your server. There may be multiple R processes behind one application due to application restarts, but all of these R processes are considered part of the same application. Initially, you will be presented with a table depicting an overview of the various directories on your server in which applications are stored, the current number of processes associated with that application, and the number of open connections to that application.

Shiny Server does not crawl the disk to discover all the potential Shiny applications which could be spawned. Instead, it only becomes aware of the existence of a Shiny application once its visited.

Clicking on any "App Directory" in the table will take you to the detailed view for that application. On this page, you'll be able to track current and historical RAM usage, along with CPU utilization, active processes, and open connections.

You'll also see the current and historical "latency" for this application. Keep in mind that, because R is single-threaded, it is only able to compute one request at at time. Thus, while one user's request is being computed, any other requests that are assigned to this R process will be inserted into a queue until the R process becomes free. Only at that point, will computation begin on the second request. The latency of an application represents the delay between when a request initially arrived at Shiny Server and the moment the assigned R process began computation to fulfill that request. A Shiny application that is not computationally intensive and doesn't have many active users may see a latency of just a few milliseconds. Conversely, an application which is computationally intensive and/or overwhelmed with more users than the associated process(es) can handle will see a much higher latency.

Processes

The "Processes" tab provides access to information about the underlying R Shiny processes which support the various applications being hosted on this server. The overview table reveals with which application each process is associated, the latency of this application, and its current memory consumption. Clicking on the ID of the process will take you to the detailed view for this process. Here you can see the current CPU utilization, open connections, and various other information used to help understand this process.

Connections

This tab displays all of the connections currently open between Shiny Server and its visitors. You can see which application the connection is accessing, when it was opened, its current status (whether it is idle or awaiting the results of some analysis), the protocol being used, whether or not the connection is encrypted, the IP address associated with the connection, and -- if relevant -- the username to whom the connection belongs. You can also filter to only those connections associated with a particular app directory or status.

The protocol each connection is using will be displayed in a blue oval at the far left edge of the table using some abbreviation. If you hover the cursor over the oval, you'll see the full protocol name. You can find more details on the various protocols supported by Shiny Server in the section on Specifying Protocols.

5.3 Killing Processes and Connections

The Admin interface also provides the opportunity to kill individual processes or connections. Alongside any table in which a process is listed, if you point your mouse at an application or connection, you will see a button appear on the right side which allows you to kill that app/connection. Clicking this button will present you with a confirmation dialogue box which asks you to confirm that you do desire to disconnect this connection or kill this process. If you confirm, that process or connection will be terminated.

If disconnecting a connection, the user will suddenly be disconnected from the server and the application will appear "greyed out." Keep in mind that, in some Shiny applications, this could forfeit some of the work being done by this user on that application. If disconnecting a process, any users with connections open to that process will be suddenly disconnected. Again, this potentially could cause the user to lose some data or work if they were using a complex Shiny application.

6 Licensing & Activation

6.1 Product Activation

6.1.1 Activation Basics

When Shiny Server Professional is first installed on a system it operates in evaluation mode for a period of time and then subsequently requires activation for continued use. To determine the current license status of your system you can use the following command:

$ sudo /opt/shiny-server/bin/license-manager status

After purchasing a license to Shiny Server Professional you'll receive a product key that can be used to activate the license on a given system. You can perform the activation as follows:

$ sudo /opt/shiny-server/bin/license-manager activate <product-key>
$ sudo reload shiny-server  # or "sudo /sbin/service shiny-server reload"

Note that you need to reload or restart the server for licensing changes to take effect.

If you want to move your license of Shiny Server Professional to another system you should first deactivate it on the system you are moving from. For example:

$ sudo /opt/shiny-server/bin/license-manager deactivate

6.1.2 Virtual Machines

By default Shiny Server Professional cannot be activated on virtual machines (this is because virtual machines confound the hardware signature used by the underlying activation mechanism). However, it is possible to activate on a virtual machine by contacting RStudio customer support and requesting that your product key allow VM activations.

6.2 Connectivity Requirements

In order to activate or deactivate Shiny Server Professional internet connectivity is required for communication with the licensing server. If your server is behind an internet proxy or not connected to the internet at all this section describes what's required to successfully activate.

6.2.1 Proxy Servers

If your server is behind an internet proxy you may need to add an additional command line flag indicating the address and credentials required to communicate through the proxy. Note however that this may not be necessary if either the http_proxy or all_proxy environment variable is defined (these are read and used by Shiny Server Professional when available).

If you do need to specify a proxy server explicitly you can do so using the --proxy command line parameter. For example:

$ sudo /opt/shiny-server/bin/license-manager --proxy=http://127.0.0.1/ activate <product-key>

Proxy settings can include a host-name, port, and username/password if necessary. The following are all valid proxy configurations:

http://127.0.0.1/
http://127.0.0.1:8080/
http://user:pass@127.0.0.1:8080/

If the port is not specified, the license manager will default to using port 1080.

6.2.2 Offline Activation

If your system has no connection to the internet it's also possible to perform an offline activation. To do this, you first generate an offline activation request as follows:

$ sudo /opt/shiny-server/bin/license-manager activate-offline-request <product-key>

Executing this command will print an offline activation request to the terminal which you should copy and paste and then send to RStudio customer support (support@rstudio.com). You will receive a reply with a file attachment that can be used to activate offline as follows:

$ sudo /opt/shiny-server/bin/license-manager activate-offline <activation-file>
$ sudo reload shiny-server  # or "sudo /sbin/service shiny-server reload"

Note that you need to reload or restart the server in order for licensing changes to take effect.

If you want to move your license of Shiny Server Professional to another system you can also perform license deactivation offline. You can do this as follows:

$ sudo /opt/shiny-server/bin/license-manager deactivate-offline

Executing this command will print an offline deactivation request to the terminal which you should copy and paste and then send to RStudio customer support (support@rstudio.com).

You can also perform an offline check of your current license status using the following command:

$ sudo /opt/shiny-server/bin/license-manager status-offline

7 Appendix

7.1 Quick Start

We recommend reading through the relevant sections of this guide to gain a complete understanding of how to operate Shiny Server. If you're just looking to get running quickly, you can follow one of the guides below.

All of the guides will help you customize your Shiny Server configuration file which will be stored at /etc/shiny-server/shiny-server.conf. By altering this file, you can control exactly how Shiny Server runs.

The following guides are available:

PRO

And for Pro features:

7.1.1 Host a directory of applications

Until a custom configuration is specified, Shiny Server will use the configuration stored at /opt/shiny-server/config/default.config. This configuration expects your Shiny applications to be hosted in /srv/shiny-server/. Let's start by copying one of the example applications from the Shiny package to this directory.

We'll need to know where the Shiny package was installed -- this can vary from distribution to distribution. You can locate Shiny's first example by entering the following command at a terminal:

R -e "system.file('examples/01_hello', package='shiny')"

which will return something like:

[1] "/usr/local/lib/R/site-library/shiny/examples/01_hello"

You can copy that entire directory into /srv/shiny-server using the following command (using the directory that was returned in the previous command, if it's different):

sudo cp -R /usr/local/lib/R/site-library/shiny/examples/01_hello /srv/shiny-server/

If that command succeeds, you've installed your first Shiny application into Shiny Server!

By default, Shiny Server listens on port 3838, so your new application will be available at http://myserver.com:3838/01_hello where myserver is the hostname or IP address of the Shiny Server.

If you wanted to change the port or the directory Shiny Server uses, you would adjust the configuration file. Shiny Server will look for a custom configuration file in /etc/shiny-server/shiny-server.conf. If none is found, it will use its default configuration. To begin customizing your server, copy the default configuration there then begin modifying. To copy the file, run the following command:

sudo cp /opt/shiny-server/config/default.config /etc/shiny-server/shiny-server.conf

Then open /etc/shiny-server/shiny-server.conf in your preferred text editor and modify the line which says listen 3838. This is the line that instructs your server to listen to port 3838 -- change it to another port such as 12345 and save the file. You'll need to restart Shiny Server to make it aware of the new configuration file. The Stopping and Starting section explains this in more detail. For now, you'll run this command if you're on a distribution which supports Upstart (most recent distributions, including Ubuntu 12 and later and CentOS 6):

sudo restart shiny-server

If you're on an older system that relies on init.d (such as CentOS 5), you'll use the following command instead:

sudo /sbin/service shiny-server restart

You should now find that Shiny Server is no longer running on port 3838, but is on whichever new port you selected.

7.1.2 Let users manage their own applications

Some administrators of Shiny Server would prefer to give users -- or some trusted subgroup of users -- the ability to manage and host their own Shiny applications. This allows users to work directly with their applications rather than requiring an administrator to deploy and update applications on their behalf. This guide will document how to create such an environment using the user_apps directive documented in the section named Host Per-User Application Directories.

We provide a configuration file in /opt/shiny-server/config/user-apps.config that enables this functionality. To use this file as your active configuration, you'll need to copy it to /etc/shiny-server/shiny-server.conf using the following command:

sudo cp /opt/shiny-server/config/user-apps.config /etc/shiny-server/shiny-server.conf

This configuration enables all users on the system to host their own apps by creating a ShinyApps directory in their home directory; you can always alter this file later to tailor it to meet your needs. You can deploy an application under your username by copying one of the examples that comes with Shiny into your own ShinyApps directory. To do this, we'll need to know where the Shiny package was installed -- this can vary from distribution to distribution. You can locate Shiny's first example by entering the following command at a terminal:

R -e "system.file('examples/01_hello', package='shiny')"

which will return something like:

[1] "/usr/local/lib/R/site-library/shiny/examples/01_hello"

You can copy that entire directory into ~/ShinyApps using the following command (using the directory that was returned in the previous command, if it's different):

mkdir ~/ShinyApps
sudo cp -R /usr/local/lib/R/site-library/shiny/examples/01_hello ~/ShinyApps/

If that command succeeds, you've successfully installed a user_apps Shiny application! However, you'll need to restart Shiny Server to make it aware of the changes you made to the configuration file. The Stopping and Starting section explains this in more detail. For now, you'll run this command if you're on a distribution which supports Upstart (most recent distributions, including Ubuntu 12 and later and CentOS 6):

sudo restart shiny-server

If you're on an older system that relies on init.d (such as CentOS 5), you'll use the following command instead:

sudo /sbin/service shiny-server restart

By default, Shiny Server listens on port 3838, so your new application will be available at http://myserver.com:3838/<your_username>/01_hello where myserver is the hostname or IP address of the Shiny Server and <your_username> is your Linux username.

If you wanted to restrict the privilege of running Shiny applications to a particular set of users on your system, you can uncomment the members_of line in the configuration file. You can then specify the Linux group name of which a user must be a member before he or she would be allowed to host Shiny applications.

7.1.3 Run Shiny Server on multiple ports

This guide will show how to run Shiny Server on multiple ports simultaneously and will also show how to run a single server with multiple locations.

We provide a configuration file in /opt/shiny-server/config/multi-server.config that enables this functionality. To use this file as your active configuration, you'll need to copy it to /etc/shiny-server/shiny-server.conf using the following command:

sudo cp /opt/shiny-server/config/multi-server.config /etc/shiny-server/shiny-server.conf

This configuration will run two servers: one on port 3838, and one on port 4949. As you can see in the configuration file, a variety of different locations are defined with different hosting models.

The server running on port 3838 defines two locations. The first for the URL /users which makes user applications available as documented in the section entitled Host Per-User Application Directories. The second location is at the URL /example1 and hosts a single application which should be stored in /srv/shiny-server/01_hello/.

You can copy this example application from the Shiny package to the relevant directories. To do this, we'll need to know where the Shiny package was installed -- this can vary from distribution to distribution. You can locate Shiny's first example by entering the following command at a terminal:

R -e "system.file('examples/01_hello', package='shiny')"

which will return something like:

[1] "/usr/local/lib/R/site-library/shiny/examples/01_hello"

You can copy that entire directory into the necessary locations using the following commands (using the directory that was returned in the previous command in both cp commands, if it's different):

# Copy to your home directory's 'ShinyApps' folder
mkdir ~/ShinyApps
sudo cp -R /usr/local/lib/R/site-library/shiny/examples/01_hello ~/ShinyApps/

# Copy to /srv/shiny-server
sudo cp -R /usr/local/lib/R/site-library/shiny/examples/01_hello /srv/shiny-server/

You'll need to restart Shiny Server to make it aware of the changes you made to the configuration file. The Stopping and Starting section explains this in more detail. For now, you'll run this command if you're on a distribution which supports Upstart (most recent distributions, including Ubuntu 12 and later and CentOS 6):

sudo restart shiny-server

If you're on an older system that relies on init.d (such as CentOS 5), you'll use the following command instead:

sudo /sbin/service shiny-server restart

You should now be able to access applications in a variety of ways:

7.1.4 Require user authentication on an application

Shiny Server Pro comes with multiple different methods of authenticating users (as described in the chapter on Authentication & Security). Out of the box, it's configured to use a Flat-File Authentication database stored in /etc/shiny-server/passwd. This database is initially empty; to create a user named admin, execute the following command:

$ sudo /opt/shiny-server/bin/sspasswd /etc/shiny-server/passwd admin

then enter the new password for the admin user when prompted. Once completed, you'll have a single user defined in your database named admin.

You should now be able to login to your administrative dashboard at a URL like http://myserver.com:4151/ (after replacing myserver.com with your server's IP or hostname) using the username admin with the password you just created. See the chapter entitled Admin for more details on how to take advantage of this interface.

After defining usernames and passwords in this password database, you can also restrict access to servers and locations using the required_user directive. We provide an example of such a configuration at /opt/shiny-server/auth.config. To use this file as your active configuration, you'll need to copy it to /etc/shiny-server/shiny-server.conf using the following command:

sudo cp /opt/shiny-server/config/auth.config /etc/shiny-server/shiny-server.conf

You'll need to restart Shiny Server to make it aware of the changes you made to the configuration file. The Stopping and Starting section explains this in more detail. For now, you'll run this command if you're on a distribution which supports Upstart (most recent distributions, including Ubuntu 12 and later and CentOS 6):

sudo restart shiny-server

If you're on an older system that relies on init.d (such as CentOS 5), you'll use the following command instead:

sudo /sbin/service shiny-server restart

If you haven't already, let's start by copying one of the example applications from the Shiny package to /srv/shiny-server/, which is the directory in which this configuration expects applications to be stored.

We'll need to know where the Shiny package was installed -- this can vary from distribution to distribution. You can locate Shiny's first example by entering the following command at a terminal:

R -e "system.file('examples/01_hello', package='shiny')"

which will return something like:

[1] "/usr/local/lib/R/site-library/shiny/examples/01_hello"

You can copy that entire directory into /srv/shiny-server using the following command (using the directory that was returned in the previous command, if it's different):

sudo cp -R /usr/local/lib/R/site-library/shiny/examples/01_hello /srv/shiny-server/

Because of the specifications provided in our current configuration file (in /etc/shiny-server/shiny-server.conf), the application we just copied requires authentication -- you must be logged in as the user named "admin" to access it. If you already visited the Administrative Dashboard on port 4151 mentioned earlier, then you may already be logged in. But you can test your configuration by either logging out or using another browser/computer to confirm that you're unable to access the application you just copied hosted at a URL like http://myserver.com:3838/01_hello without logging in, where myserver is the hostname or IP address of the Shiny Server. However, once you login as the user named "admin" using the password you defined above, you will be granted access to this application.

Note that, because the configuration in use is structured like so:

server {
  listen 3838;
  
  location / {

    ...

    location /01_hello {
      required_user admin;
    }
  }
}

only the 01_hello location requires authentication; all other applications are freely available. If you were to move the required_user directive to the parent location, however, all applications defined in that location would require being authenticated as the user named "admin".

7.1.5 Host a secure Shiny Server

Shiny Server is able to serve Shiny applications using SSL/TLS -- an encrypted channel between your server and your clients. A configuration exemplifying this setup is available in /opt/shiny-server/ssl.config. To use this file as your active configuration, you'll need to copy it to /etc/shiny-server/shiny-server.conf using the following command:

sudo cp /opt/shiny-server/config/ssl.config /etc/shiny-server/shiny-server.conf

This configuration expects your SSL key and certificate to be available in /etc/shiny-server/server.key and /etc/shiny-server/server.cert, respectively. If you have an existing SSL certificate stored elsewhere, you can update the configuration file at /etc/shiny-server/shiny-server.conf to point to the appropriate files. If you don't have an SSL certificate available, you can setup a "self-signed" certificate. This certificate will allow you to encrypt traffic between your clients and server but will not be "trusted" by most browsers. Thus, when a user visits a page secured via a self-signed certificate, the user will get a warning advising them not to proceed. Nonetheless, we can demonstrate how to create a self-signed certificate and integrate it into Shiny Server. The details of creating and signing SSL certificates is outside the scope of this guide, but the commands are given below for your convenience.

In order to create a certificate, you'll need to have the openssl library installed on your server. You can then create an SSL key using the following command.

sudo openssl genrsa -out /etc/shiny-server/server.key 1024

You'll then generate a certificate signing request (CSR) using the following command:

sudo openssl req -new -key /etc/shiny-server/server.key \
  -out /etc/shiny-server/server.csr

(Where a command includes a \ you can either enter that literally as it appears in this document or you can omit it and enter the whole command on a single line.) This command will ask you a variety of information about your organization which you can provide or omit, if you just plan to sign this certificate yourself.

You can then sign that request yourself using this command:

sudo openssl x509 -req -days 3650 \
  -in /etc/shiny-server/server.csr \
  -signkey /etc/shiny-server/server.key \
  -out /etc/shiny-server/server.cert

At this point, you can restart the server to make it recognize its new configuration. The Stopping and Starting section explains this in more detail. For now, you'll run this command if you're on a distribution which supports Upstart (most recent distributions, including Ubuntu 12 and later and CentOS 6):

sudo restart shiny-server

If you're on an older system that relies on init.d (such as CentOS 5), you'll use the following command instead:

sudo /sbin/service shiny-server restart

It is a good idea to inspect the log file at this point to ensure that there were no problems using your SSL key and certificate. The server log file is stored in /var/log/shiny-server.log. You can preview the last 20 lines of this file using the following command.

sudo tail -n 20 /var/log/shiny-server.log

You can ensure here that there were no errors in using your SSL configuration.

Finally, if you haven't already, you'll need to copy an example application into /srv/shiny-server/ which is the directory this configuration expects your applications to be hosted in. Let's start by copying one of the example applications from the Shiny package to this directory.

We'll need to know where the Shiny package was installed -- this can vary from distribution to distribution. You can locate Shiny's first example by entering the following command at a terminal:

R -e "system.file('examples/01_hello', package='shiny')"

which will return something like:

[1] "/usr/local/lib/R/site-library/shiny/examples/01_hello"

You can copy that entire directory into /srv/shiny-server using the following command (using the directory that was returned in the previous command, if it's different):

sudo cp -R /usr/local/lib/R/site-library/shiny/examples/01_hello /srv/shiny-server/

Once you've copied this application in, you should be able to connect to your server from a browser by visiting a URL like https://myserver.com:3939/01_hello (after replacing myserver.com with your server's IP or hostname). Note that this guide uses the port 3939, unlike the other guides and that you must specify the https:// protocol when visiting the page. If you signed the certificate yourself, your browser will likely prompt you about the untrusted certificate. If you instruct your browser to accept the certificate regardless, you'll be taken to your application which now is secured via SSL/TLS encryption.

7.2 Configuration Settings

Listed below are all the directives that are supported in Shiny Server config files.

Applies to indicates the kind of parent scope that this directive normally appears inside.

Inheritable means that you can put this directive at a higher level in the hierarchy and it will be inherited by any children to which it might apply. Inherited directives can be overridden by using the directive again in a child scope.

7.3 Migrating & Updating

7.3.1 Upgrading from Shiny Server 0.3.x

Shiny Server 0.4 and later include many major changes to the architecture of Shiny Server. There are a few things to be aware of when upgrading from Shiny Server 0.3.x.

First, Shiny Server is now distributed via deb and rpm installers, rather than using npm. Thus, you'll first want to uninstall the old version of Shiny Server which was installed from npm.

$ sudo npm uninstall -g shiny-server

Shiny Server no longer requires node.js to be installed on the system either. If you have no other need for node.js, you can uninstall it at this time, as well.

Running the latest Shiny Server installer will replace the scripts at /etc/init/shiny-server.conf or /etc/init.d/shiny-server. If you have made any modifications to these startup scripts that you wish to keep, please save a copy of these files before running the installer.

The default directories for logging and Shiny application hosting have also moved in this release. The default logging directory used to be /var/shiny-server/log, it is now /var/log/shiny-server. The default hosting directory was previously /var/shiny-server/www and is now /srv/shiny-server/. If you have not explicitly overridden these directories in the /etc/shiny-server/shiny-server.conf file, the new location will be created and used in the latest Shiny Server.

Finally, Shiny Server 0.4 and later require the Shiny package to be at least version 0.7.0. You can check the system-wide version of Shiny you have installed using the following command on the command line.

$ sudo su - -c "R -e \"packageVersion('shiny')\""

(Running this command using the sudo su - -c preface will allow you to see the system-wide version of Shiny. Individual users could have installed more recent versions of Shiny in their own R libraries.) If the installed version of Shiny predates 0.7.0, you should follow the instructions in Install Shiny to update to the most recent version.

At this point, you can proceed with the Installation instructions associated with your Operating System.

7.3.2 Upgrading from Shiny Server 0.4.x

There are problems on some systems with updating from 0.4.x versions to a more recent version. Thus, any user updating from the 0.4.x line should uninstall the package before installing the new one. In all versions 0.5.x and later, updating can simply be done by installing the newer version over the old one without explicitly removing the old package.

7.4 Frequently Asked Questions

7.4.1 What are the hardware requirements for running Shiny Server?

The performance footprint of a Shiny application is almost entirely dependent upon the Shiny application code. There are two factors to consider when selecting the hardware platform for Shiny Server.

RAM

The memory requirements of a Shiny application depend heavily on the data loaded when running the application. Often users find that a Shiny R process requires a minimum of 50MB of RAM -- beyond this, the amount of memory consumed by an application is determined by the data loaded or generated by that application. The Scoping Section of the Shiny Tutorial describes in detail how to take advantage of Shiny's scoping rules to share data across multiple Shiny sessions. This enables application developers to load only one copy of data into memory but still share this data with multiple shiny sessions.

CPU

R is fundamentally a single-threaded application. Unless parallel packages and tools are specifically selected when designing a Shiny application, the average R process (and the associated Shiny application) will be run serially on a single processing core. Thus, the typical Shiny application may saturate the processing core to which it's assigned, but will be unable to leverage other cores on the server which may be idle at that time.

7.4.2 Does Shiny Server work on Amazon Elastic Compute Cloud (EC2)?

Absolutely. Many customers deploy Shiny Server and Shiny Server Professional on the Amazon Web Services (AWS) framework.

7.4.3 Can I Deploy Shiny Server on an Isolated Network?

Of course. Shiny Server does not require a connection to the Internet in order to work properly, so you are free to deploy it in whatever sort of network configuration you would like. Offline activation is also available for Shiny Server Professional customers.

7.4.4 How Do I Translate My 'application' Settings to Nested 'location's?

Shiny Server 0.4.2 introduced a new model for managing applications at a more granular level by supporting nested location directives. Any existing application directives in your configuration file will need to be migrated to this nested location format in order to be supported by any version of Shiny Server after 0.4.2.

application directives were addressed by their full path on disk. Nested locations, on the other hand, are indexed by their relative path within their parent location. For instance, the following exemplifies how you could redirect a particular application in the old model:

location / {
  site_dir /srv/shiny-server;
  
  # Define rules to apply to one application, stored at '/srv/shiny-server/app1'
  application /srv/shiny-server/app1 {
    redirect "http://rstudio.com" 302 true;
  }
}

In the new "nested locations" model, the equivalent would be:

location / {
  site_dir /srv/shiny-server;

  # Define rules to apply to one application, stored at '/srv/shiny-server/app1'
  location /app1 {
    redirect "http://rstudio.com" 302 true;
  }
}

This structure is much more powerful than simple application settings. The following configuration defines a parent location (depts) with some settings, then overrides those settings for a particular directory (finance) within that location.

server {
  ...
  # Define the '/depts' location
  location /depts {
    # Host a directory of applications
    site_dir /srv/departmentApps;
    
    # Provide a default/global GAID
    google_analytics_id "UA-12345-1";

    # Define the '/finance' location.
    # Corresponds to the URL '/depts/finance', and the filesystem path 
    # '/srv/departmentApps/finance' as defined by the parent location.
    location /finance {
      # Provide a custom GAID for only this sub-location
      google_analytics_id "UA-54321-9";

      location /fall2014/app1 {
        redirect "http://rstudio.com" 302 true;
      }
    }
  }
...

In this case, all applications stored in the depts/finance/ directory would have a different Google Analytics ID than the rest of the applications on this server. Additionally, the application at depts/finance/fall2014/app1 would be redirected to http://rstudio.com.

7.4.5 Can I Bulk-Import in Flat-File Authentication?

Some users may have an existing table of usernames and passwords they wish to import into a flat-file authentication system using the sspasswd tool. The shell script below can be used as a model for scripting such a solution, but be aware of the security concern mentioned below.

#!/bin/bash
 
PWFILE="passwdfile"
USERFILE="users.txt"
 
if [ ! -f "$PWFILE" ]; then
  touch $PWFILE
fi

while read p; do
  parts=( $p )
  echo "Adding ${parts[0]}..."
  echo "${parts[1]}" | /opt/shiny-server/bin/sspasswd \
    $PWFILE "${parts[0]}"
done < $USERFILE
echo "Done."

The script above will extract the usernames and passwords from the file specified in the USERFILE variable, and will use the file name provided in the PWFILE variable as the file in which the usernames and passwords should be stored. This script expects a user file which is stored in a tab-delimited format in which the username is in the first column, and the password is in the second.

Most secure password-generating tools recommend that the password be typed in an interactive console in which the text can be hidden, rather than passing it in via a command-line argument. There are (at least) two reasons for this:

  1. Such commands (including the password, if it were provided as an argument to the command) are stored in the history file for your shell. Thus, a user with access to your shell history may be able to retrieve the password.
  2. In a model like the one used above, the passwords won't be stored in your shell's history, but they will be available in the system's process table. The echo command above (and the password associated with it) will likely be accessible by any other user on the system while that command is executing.

Be sure to fully understand the security implications of the above script before using it, especially if using it on an unsecured or multi-user server.