Allowing different libraries for different apps on Shiny Server, Shiny Server Pro, and Posit Connect
This article describes two ways to configure applications to use different sets of libraries in Shiny Server, Shiny Server Pro, and Posit Connect.
Different libraries for different apps on Posit Connect
Posit Connect installs the R package dependencies of Shiny applications using the rsconnect
and packrat
R packages to identify the target source code and enumerate its dependencies. That information is bundled into an archive (.tar.gz
) file and uploaded to Posit Connect. This is done on a per-app basis, therefore two apps on Posit Connect can use different packages or different versions of the same packages. The packrat
package attempts to re-use R packages whenever possible, so if two apps share the same version of a package as a dependency, they can take advantage of previously-installed packages, hence making deployment faster.
Different libraries for different apps on Shiny Server and Shiny Server Pro
Allowing for different libraries for different apps on Shiny Server and Shiny Server Pro requires a different approach. In the remainder of this article we describe two ways to configure applications to use different sets of libraries on Shiny Server and Shiny Server Pro.
- Method 1 relies on Shiny Server’s
exec_supervisor
feature. It will only work with Shiny Server Pro. - Method 2 relies on Shiny Server’s
run_as
feature. It will work with both Shiny Server and Shiny Server Pro.
Method 1 - exec_supervisor
With Shiny Server Pro, you can run R sessions under a program supervisor that modifies the environment of the sessions. You can use this supervisor to set the R_LIBS_USER
environmental variable, which controls which libraries a session may use.
Section 3.6 of the Shiny Server Administrator’s Guide explains how to add a program supervisor. You add an exec_supervisor
setting to your server config file to specify a supervisor (and the arguments which control its behavior).
The file below uses exec_supervior
to modify the default /etc/shiny-server/shiny-server.conf file that ships with Shiny Server. exec_supervisor
partitions the applications up by setting the R_LIBS_USER
environment variable.
Near the bottom of the file, a /finance
sub-location is defined for apps that use a specific set of libraries. Beneath that, a specific app is given its own set of libraries.
# Instruct Shiny Server to run applications as the user "shiny"
run_as shiny;
# Specify the authentication method to be used.
# Initially, a flat-file database stored at the path below.
/etc/shiny-server/passwd;
auth_passwd_file
# Define a server that listens on port 3838
server {3838;
listen
# Define a location at the base URL
/ {
location # Define a default library for applications
"R_LIBS_USER=/usr/lib/LibraryA";
exec_supervisor
# Only up tp 20 connections per Shiny process and
# at most 3 Shiny processes per application.
# Proactively spawn a new process when our processes
# reach 90% capacity.
20 .9 3;
utilization_scheduler
# Host the directory of Shiny apps stored in this directory
/srv/shiny-server;
site_dir
# Log all Shiny output to files in this directory
/var/log/shiny-server;
log_dir
# When a user visits the base URL rather than a particular application,
# an index of the applications available in this directory will be shown.
directory_index on;
# Now define a sub-location at /finance
/finance {
location # Define a library that should be used by the finance department
"R_LIBS_USER=/usr/lib/FinanceLibrary";
exec_supervisor
# Further, define another sub-location that happens to correspond to
# a particular app.
/app1 {
location #Define a specific library to be used by this application
"R_LIBS_USER=/usr/lib/LibraryC";
exec_supervisor
}
}
}
}
# Provide the admin interface on port 4151
4151 {
admin
# Restrict the admin interface to the usernames listed here. Currently
# just one user named "admin"
required_user admin; }
In this case, you could set up as many different libraries as you want and specify a different library for each location, or even each application that you want to deploy. This would give you fine-grained control over each of your applications.
Method 2 - run_as
Shiny Server (and Shiny Server Pro) use a run_as
setting to determine which user should spawn each R Shiny processes. The user setting determines which library R will look in for packages (as well as which directories the app will be able to read and write to).
The run_as
setting can be configured globally, or for a particular server or location. As a result, you can set up different locations for hosting apps that use different packages. Each location can be affiliated with its own user—each of which presumably has a different set of libraries specified with a ~/.Rprofile file.
With this approach, you would probably have only a handful of users that you create that each maintain their own separate libraries.
Section 2.3 of the Shiny Server Administrator’s Guide explains how to set a user with run_as
.
The file below uses run_as
to modify the default /etc/shiny-server/shiny-server.conf file that ships with Shiny Server. run_as
defines a global user, shiny
, for the server. It then defines a different user for the /finance
location, shinyFinance
. The finance department can deploy apps in this location. Those apps will be restricted to the packages in the library of shinyFinance
, which may be different than the packages in the library of the user namedshiny
.
# Specify the authentication method to be used.
# Initially, a flat-file database stored at the path below.
/etc/shiny-server/passwd;
auth_passwd_file
# Define a server that listens on port 3838
server {3838;
listen
# Define a location at the base URL
/ {
location # Instruct Shiny Server to run applications as
# the user "shiny" by default
run_as shiny;
# Only up tp 20 connections per Shiny process and
# at most 3 Shiny processes per application.
# Proactively spawn a new process when our processes
# reach 90% capacity.
20 .9 3;
utilization_scheduler
# Host the directory of Shiny apps stored in this directory
/srv/shiny-server;
site_dir
# Log all Shiny output to files in this directory
/var/log/shiny-server;
log_dir
# When a user visits the base URL rather than a particular application,
# an index of the applications available in this directory will be shown.
directory_index on;
/finance {
location # Run as a different user for this location
run_as shinyFinance;
}
}
}
# Provide the admin interface on port 4151
4151 {
admin
# Restrict the admin interface to the usernames listed here. Currently
# just one user named "admin"
required_user admin; }