Shiny Server Pro with Docker


You can put Shiny Server Pro in a Docker container, but licensing must be handled explicitly. For this configuration, we recommend using a floating license server on hardware or a static VM, on the same network as the Docker container so the Shiny Server Pro instance can communicate with it to obtain a license lease. 

Sample Dockerfile

Note the following:

  • CentOS 7 is in use; you will need to adapt this if your preferred OS is not CentOS 7.
  • FLOATING_LICENSE_SERVER argument is expected; this is the URL to the server you have already installed and configured.
  • The latest version of R is installed via EPEL. A specific version of R is not built from source, so each time it is run, the latest version will be installed. This may break older shiny apps that depend on an older version of R, so consider building a specific version or versions from source for your own needs.
  • Only the shiny and rmarkdown packages are installed; you can augment this list as appropriate.
  • In the step to install Shiny Server Pro, there is a placeholder for the RPM URL for the version to be installed. Update this with the URL from the download page; the version of Shiny Server Pro should be v1.5.10 or later to take advantage of Docker and the floating licenses.
  • The Shiny Server Pro configuration file is called floating.config here, and resides in the same directory as this Dockerfile so it can be copied to the server in the container. You can call this file whatever you like as long as the filename is correct in this Dockerfile.

These options should be updated to reflect your own environment and package needs.

FROM centos:7

# host:port of the floating license server at runtime


# Install EPEL

RUN yum -y install epel-release && yum -y update

# Install R

RUN yum -y install R

RUN echo $'options(\n\
  repos = c(CRAN = ""),\n\
  download.file.method = "libcurl",\n\
  Ncpus = parallel::detectCores(logical=FALSE)\n\
)' >> /usr/lib64/R/etc/

# Install shiny and rmarkdown

RUN R -e "install.packages(c('shiny', 'rmarkdown'))"

# Install version of Shiny Server Pro with floating license support

RUN yum install -y \
      --setopt=tsflags=nodocs \
      "<URL to the latest Shiny Server Pro rpm>" \
    && yum clean all \
    && rm -rf /var/cache/yum

# Install configuration that sets license_type

COPY floating.config /etc/shiny-server/floating.config

# Set License Server

RUN /opt/shiny-server/bin/license-manager license-server $FLOATING_LICENSE_SERVER

# Run server as shiny user

USER shiny
ENTRYPOINT ["opt/shiny-server/bin/shiny-server", "/etc/shiny-server/floating.config"]

Sample Shiny Server Pro configuration file

Note that the file includes a line for floating licensing, but is otherwise the default config. You will need to update this to suit your need. This is the floating.config file referred to in the Dockerfile above, but you can call it anything as long as the name matches what you have in the Dockerfile.

# Instruct Shiny Server to run applications as the user "shiny"
run_as shiny;

# Use floating licensing
license_type floating;

# Specify the authentication method to be used.
# Initially, a flat-file database stored at the path below.
auth_passwd_file /etc/shiny-server/passwd;

# Define a server that listens on port 3838
server {
  listen 3838;

  # Define a location at the base URL
  location / {

    # 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.
    utilization_scheduler 20 .9 3;

    # Host the directory of Shiny Apps stored in this directory
    site_dir /srv/shiny-server;

    # Log all Shiny output to files in this directory
    log_dir /var/log/shiny-server;

    # 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;

# Provide the admin interface on port 4151
admin 4151 {
  # Restrict the admin interface to the usernames listed here. Currently 
  # just one user named "admin"
  required_user admin;