Creating R Shiny apps has been useful in class demonstration, project assignments, and customized tests. However, to host and share these apps, a server is needed. I have tried three options so far: Shinyapps.io, Amazon Web Service (AWS), and Linode.
This is the easiest way. In RStudio IDE, the Publish button deploys the Shiny apps to RStudio’s web host for shiny apps: https://www.shinyapps.io/. Here is the full tutorial from RStudio.
A free plan on shinyapps.io has limits on run-time and number of deployed apps. Still, it is a good way for getting started with Shiny apps. Plans on shinyapps.io are pricy comparing with AWS and Linode.
We are on our own to set up a shiny server (and more) in the AWS Elastic Compute Cloud (EC2). Charles Bordet wrote a wonderful step-by-step installation guide, The Ultimate Guide to Deploying a Shiny App on AWS.
The general purpose (burstable) instance families include T2 (July 2014), T3 (August 2018) and T3a (April 2019), each comes with a variety of capacity (nano / micro / small / medium / large / xlarge) in memory sizes and vCPUs. A new generation is 10% cheaper than the previous generation.
Amazon generously offers a one-year Free Tier plan (t2.micro / 1GB Memory / 1 vCPU / 8 GB Storage) Afterwards, users can choose from a handful of pricing plans, such as On-Demand and 1-year or 3-year Saving Plans. Users can estimate the cost. Below is a comparison of t3a.micro 3-year Saving Plan with Linode’s entry-level plan.
Plan | Memory | vCPUs | Storage | Monthly Price |
---|---|---|---|---|
t3a.micro | 1 GB | 2 | 20 GB | $4.99 |
Linode | 1 GB | 1 | 25 GB | $5.00 |
I started with 8 GB elastic block storage (EBS) and went up to 20 GB. Resizing requires two steps:
1. Modifying an EBS volume using Elastic Volumes. This can be done in the AWS console.
2. Extending a Linux file system after resizing a volume. This needs to be done in a terminal.
ssh -i key_name.pem ubuntu@ec2-xxx-xxx-xxx-xxx.us-east-2.compute.amazonaws.com
df -h
lsblk
sudo growpart /dev/xvda 1
sudo resize2fs /dev/xvda1
Since I have learned how to set up a Shiny server on AWS, getting started in Linodes seems easier and faster. Here is Linode’s guide: Getting Started with Linode. By the way, besides using the terminal to type commands, Linode provides a web-based shell, the Linode Shell (Lish) in the account interface.
Below are my notes for quick future reference.
Secure Your Server. Login as root on Linode to add a limited user account.
ssh root@xxx.xxx.xxx.xxx
adduser example_user
adduser example_user sudo
mkdir -p ~/.ssh && sudo chmod -R 700 ~/.ssh/
ls ~/.ssh/id_rsa*
ssh-keygen -b 4096
scp ~/.ssh/id_rsa.pub example_user@xxx.xxx.xxx.xxx:~/.ssh/authorized_keys
sudo apt-key adv –keyserver keyserver.ubuntu.com –recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9
sudo add-apt-repository ‘deb https://cloud.r-project.org/bin/linux/ubuntu bionic-cran35/’
sudo apt update
sudo apt install r-base
sudo su - \
-c “R -e \”install.packages(‘shiny’, repos=‘https://cran.rstudio.com/’)\""
sudo apt-get install gdebi-core
wget https://download3.rstudio.org/ubuntu-14.04/x86_64/shiny-server-1.5.14.948-amd64.deb
sudo gdebi shiny-server-1.5.14.948-amd64.deb
sudo systemctl status shiny-server.service
directory_index off;
in shiny-server.conf.
sudo nano /etc/shiny-server/shiny-server.conf
# Instruct Shiny Server to run applications as the user "shiny"
run_as shiny;
# Define a server that listens on port 3838
server {
listen 3838;
# Define a location at the base URL
location / {
# 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 off;
}
}
Reload Shiny server after making changes in shiny-server.conf.
sudo systemctl reload shiny-server
sudo su - \
-c “R -e \”install.packages(‘package_name’, repos=‘https://cran.rstudio.com/’)\""
git clone https://github.com/github_user_name/app_name.git
cd /srv/shiny-server
sudo ln -s ~/app_name
scp local_path_to_file example_user@xxx.xxx.xxx.xxx:/home/example_user
scp example_user@xxx.xxx.xxx.xxx:/home/example_user local_path_to_file
sudo apt install nginx
sudo nano /etc/nginx/nginx.conf
http { # Basic Settings # Hide version number server_tokens off; map $http_upgrade $connection_upgrade { default upgrade; '' close; } }
sudo nano /etc/nginx/sites-available/shiny.conf
server {
listen 80;
listen [::]:80;
server_name example.com;
location / {
proxy_pass http://localhost:3838;
proxy_redirect http://localhost:3838/ $scheme://$host/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 20d;
proxy_buffering off;
}
}
cd ../sites-enabled
sudo ln -s ../sites-available/shiny.conf .
sudo nginx -t
sudo systemctl restart nginx
sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-nginx
sudo certbot --nginx
sudo nano /etc/nginx/sites-available/shiny.conf
server { listen 443 ssl http2 ipv6only=on; # managed by Certbot listen [::]:443 ssl http2; # managed by Certbot # HSTS max-age=31536000 seconds means one year add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; server_name example.com; location / { proxy_pass http://localhost:3838; proxy_redirect http://localhost:3838/ $scheme://$host/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_read_timeout 20d; proxy_buffering off; } } server { if ($host = example.com) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; listen [::]:80; server_name example.com; return 404; # managed by Certbot }Again, check NGINX configuration and reload it.
sudo nginx -t
nginx -s reload
sudo apt install ufw
sudo systemctl start ufw && sudo systemctl enable ufw
sudo ufw allow http
sudo ufw allow https
sudo ufw allow 22/tcp
sudo ufw enable
Optional RStudio server installation. NGINX reverse proxy is needed as well.