How to run R Shiny on Platform.sh

Goal

To run R Shiny on Platform.sh.

Assumptions

You will need:

Problems

Platform.sh offers many different language runtimes by default, but some applications require different environments, such as data science applications which use R Shiny. By installing the Miniconda Python package manager, it is possible to run R applications, such as R Shiny, on Platform.sh.

Steps

1. Set git remote to Platform.sh project

$ git init
$ platform project:set-remote <project id>

2. Create an installation script file

The Platform.sh build hook runs Dash, not Bash, so the installation script is executed separately in install_r.sh:

#!/bin/bash

# Download the latest Miniconda3 release and name the file `conda.sh`
curl https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -o conda.sh

# Run the downloaded `conda.sh` script using bash
# — Use the `-b` flag to run the installer in batch mode
# — Use the `-p` flag to specify where the package manager will actually be installed
bash conda.sh -b -p $PLATFORM_APP_DIR/conda

# Source the following `conda.sh` file to put the `conda` command in our path for the duration of this script
. /app/conda/etc/profile.d/conda.sh

# Add the above command to `.bash_profile` so that it is available during SSH sessions
echo ". /app/conda/etc/profile.d/conda.sh" >> ~/.bash_profile
echo "conda activate" >> ~/.bash_profile

# Enter the base conda environment and make sure it is up to date
conda activate base
conda update -n base -c defaults conda

# Install R
# `r-essentials` is a bundle of 80 common R packages, including `r-shiny`.
# Remove `r-essentials` from the line below to only have a barebones install.
# The `-n` flag gives the environment its name.
conda create -n r-env r-essentials r-base

# Activate the freshly created environment
conda activate r-env

# Install additional packages if desired
# conda install r-rbokeh

IMPORTANT: When using conda to install R packages, you will need to add r- before the regular CRAN or MRAN name. For instance, if you want to install rbokeh, you will need to use conda install r-rbokeh.

3. Add a start script for running scripts with R

start_command.sh:

#!/bin/bash

# Source the `conda.sh` file to make this particular shell session able to run the `conda` command
. /app/conda/etc/profile.d/conda.sh

# Activate the conda environment that was created in the build hook
conda activate r-env

# Run the Shiny web app
Rscript start_shinyapp.R

4. Add a Shiny app in the shinyapp directory

In the file shinyapp/app.R:

library(shiny)

# Define UI for application that draws a histogram
ui <- fluidPage(

   # Application title
   titlePanel("Old Faithful Geyser Data"),

   # Sidebar with a slider input for number of bins
   sidebarLayout(
      sidebarPanel(
         sliderInput("bins",
                     "Number of bins:",
                     min = 1,
                     max = 50,
                     value = 30)
      ),

      # Show a plot of the generated distribution
      mainPanel(
         plotOutput("distPlot")
      )
   )
)

# Define server logic required to draw a histogram
server <- function(input, output) {

   output$distPlot <- renderPlot({
      # generate bins based on input$bins from ui.R
      x    <- faithful[, 2]
      bins <- seq(min(x), max(x), length.out = input$bins + 1)

      # draw the histogram with the specified number of bins
      hist(x, breaks = bins, col = 'darkgray', border = 'white')
   })
}

# Run the application
shinyApp(ui = ui, server = server)

5. Add a script for running the R app

Create the R script start_shinyapp.R:

library(shiny)
options(shiny.host = "0.0.0.0")
options(shiny.port = 8888)
runApp('shinyapp')

6. Add .platform.app.yaml

Create the .platform.app.yaml configuration file:

# The name of this app. Must be unique within a project.
name: app

# The runtime the application uses.
type: "python:3.7"

# The hooks executed at various points in the lifecycle of the application.
hooks:
    build: |
      set -e

      # The build hook uses `dash` rather than `bash`.
      # Thus, the installation occurs in separate script that runs with `bash`.
      bash install_r.sh

    deploy: |
      set -e

      # Make the start script executable
      chmod +x start_command.sh

# The size of the persistent disk of the application (in MB).
disk: 1024

# The configuration of app when it is exposed to the web.
web:
    commands:
        start: bash ./start_command.sh
    upstream:
        socket_family: tcp
        protocol: http
    locations:
        "/":
            passthru: true
variables:
    env:
        PORT: 8888

7. Define routes

./.platform/routes.yaml

http://{default}/:
  type: redirect
  to: "https://{default}/"

https://{default}/:
  type: upstream
  upstream: "app:http"
  primary: true
  id: http
  cache:
      enabled: false

8. Add empty services

./.platform/services.yaml

# empty

9. Add, commit, and push these files to your Platform.sh project

git add .
git commit -m "Adding configuration to install R Shiny"
git push platform master

10. Visit the URL on the app that was just created

platform url

Conclusion

By executing the Anaconda or Miniconda installation Bash scripts in the build hook, a project is able to install an Conda-based execution environment on Platform.sh.