Deploy RShiny on AWS EC2
Mar 22, 2020If you're deploying applications on AWS one of the easier ways to get started is to simply deploy everything on EC2. If you're not familiar with AWS EC2, EC2 instances are compute instances. They are like your (linux) desktop, except that yous spin them up and kill them on demand with AWS console (or CLI or some other infrastructure automation tool).
Should I use EC2 to Deploy my RShiny App?
If you're looking for a solution that has some built in scale and ability to throw a Load Balancer at it EC2 is fine. It's also nice because it's just a computer. You don't have to find a work around to get you a computer the way you do with Docker (docker run) or Kubernetes (kube exec). You deal with an EC2 instance the way you would any remote server, but its on AWS so you get some additional niceness such as the backups, Elastic IPs, and Load Balancers.
This is slightly more difficult than using LightSail. If you are completely new to AWS and on a tight deadline you may want to start there. If you need more flexibility, you may need to scale in the future, already know how to deal with EC2, or are just looking to learn a new skill read on!
If you'd like to learn more about deploying RShiny please consider checking out my FREE Deploy RShiny on AWS Guide!
Let's get started!
Deploy your EC2
The rest of this tutorial is going to assume that you know how to spin up an EC2 instance. If you don't the short answer is to go to the AWS console -> Services -> EC2 -> Launch Instance. Select your favorite OS (go with Bitnami NGINX, Ubuntu, or ALinux2) and take note of the EC2 ID, name of the security group and SSH key. When you get to the final page with the tags add in a tag 'Name' and give it a value of some name that will be descriptive to you (Rshiny EC2 Tutorial). This will make it easier for you to find when you're going through the AWS console.
Here are some screenshots to help you along.
I like the NGINX image from Bitnami because it's all future proof with NGINX, preconfigured security groups, and SSL certificates. What more could you really ask for?
Once you've hit 'Launch' you will see a clickable link to i-abcdefgfhij
. Click on that link and leave it open as you are going through the rest of this post.
The long answer well how do I deploy an EC2 instance is to go and take my FREE Getting Started with AWS course that will teach you all you need to know to launch an EC2 instance and where to look for things like opening ports and finding IP addresses. I say course, but it's really about an hour of taking you through the console to show you how to find IP addresses and open ports.
SSH on over to your EC2 Instance
Remember how I told you to keep open that browser tab with your EC2 instance? Go back there. You may have to wait a few minutes for it to be 'running' depending on your instance type and availability, but once it's running you will see a Public DNS address.
Additionally, if you had to download your SSH key download it, put it in your ~/.ssh
folder, and run chmod 400 ~/.ssh/my-ssh-key.pem
with my-key.pem being your actual SSH key.
# Bitnami
ssh -i ~/.ssh/my-ssh-key.pem ubuntu@my-ip
# Ubuntu
ssh -i ~/.ssh/my-ssh-key.pem ubuntu@my-ip
# ALinux2
ssh -i ~/.ssh/my-ssh-key.pem ec2-user@my-ip
Install RShiny on your EC2
Now, because an EC2 instance is just a computer you have 2 options. You can install your RShiny application directly to the EC2 instance or run with docker.
I'm going to assume here that if you're deploying on an EC2 instance instead of using a straight docker solution like ECS, Swarm or Kubernetes that what you want is to just install RShiny onto your instance with minimal fuss. ;-)
My favorite strategy to use conda to install R and Python packages. You could also install them using your system package manager, but I really, really, really do not recommend that route and I'm not talking about it anymore.
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
chmod 777 *sh
./Miniconda3-latest-Linux-x86_64.sh -b
export PATH=$HOME/miniconda3/bin:$PATH
# Conda forge has sooooo many packages
conda config --add channels conda-forge
# Create a conda environment called r-shiny and install the package r-shiny (add whatever packages you want here too)
conda create -y -n r-shiny r-shiny
If you don't have an RShiny app available check out this app.R
I modified from the RShiny Examples github repo .
#!/usr/bin/env Rscript
# This file is from the Rshiny examples github repo
# https://github.com/rstudio/shiny-examples/blob/master/001-hello/app.R
# I just made a few changes for the host and the port
library(shiny)
# Define UI for app that draws a histogram ----
ui <- fluidPage(
# App title ----
titlePanel("Hello Shiny!"),
# Sidebar layout with input and output definitions ----
sidebarLayout(
# Sidebar panel for inputs ----
sidebarPanel(
# Input: Slider for the number of bins ----
sliderInput(inputId = "bins",
label = "Number of bins:",
min = 1,
max = 50,
value = 30)
),
# Main panel for displaying outputs ----
mainPanel(
# Output: Histogram ----
plotOutput(outputId = "distPlot")
)
)
)
# Define server logic required to draw a histogram ----
server <- function(input, output) {
# Histogram of the Old Faithful Geyser Data ----
# with requested number of bins
# This expression that generates a histogram is wrapped in a call
# to renderPlot to indicate that:
#
# 1. It is "reactive" and therefore should be automatically
# re-executed when inputs (input$bins) change
# 2. Its output type is a plot
output$distPlot <- renderPlot({
x <- faithful$waiting
bins <- seq(min(x), max(x), length.out = input$bins + 1)
hist(x, breaks = bins, col = "#75AADB", border = "white",
xlab = "Waiting time to next eruption (in mins)",
main = "Histogram of waiting times")
})
}
# If you want to automatically reload the app when your codebase changes - should be turned off in production
options(shiny.autoreload = TRUE)
options(shiny.host = '0.0.0.0')
options(shiny.port = 8080)
# Create Shiny app ----
shinyApp(ui = ui, server = server)
Now that we have a hello world example let's run it!
./app.R
You will see that this comes up under port 8080. If your application is running and you can't view it in a browser it probably means that the port isn't accessible from your security group. Head on over to the AWS console -> Services -> EC2 -> Running EC2 -> and Find your Instance. In the bottom panel there will be some information, including your IP address and Security group. The security group should be clickable. Click on it and add an inbound rule for port 8080.
Wrap Up
That's it! You now have a working RShiny example running on EC2. Now that you have the skeleton install your needed packages and get started with your own RShiny app!