Nicole has been having a lot of fun the last few days creating her own Shiny apps. We work in the same space, and let’s just say her enthusiasm is very contagious. While she focused on deploying R-based web apps on ShinyApps.io, I’m more of a web development geek, so I put my energy towards setting up a server where she could host her apps. This should come in handy, since she blew through all of her free server time on ShinyApps after just a couple of days!

Before you begin, you can see a working example of this at https://shinyisat.net/sample-apps/sampdistclt/.

In this tutorial, I’m going to walk you through the process of:

  1. Setting up an Ubuntu 14.04 + NGINX server at DigitalOcean
  2. Installing and configuring R
  3. Installing and configuring Shiny and the open-source edition of Shiny Server
  4. Installing a free SSL certificate from Let’s Encrypt
  5. Securing the Shiny Server using the SSL cert and reverse proxy through NGINX
  6. Setting appropriate permissions on the files to be served
  7. Creating and launching the app Nicole created in her recent post

Setting Up an Ubuntu 14.04 Server at DigitalOcean

DigitalOcean is my new favorite web host. (Click this link to get a $10 credit when you sign up!) They specialize in high-performance, low-cost, VPS (virtual private servers) targeted at developers. If you want full control over your server, you can’t beat their $5/month offering. They also provide excellent documentation. In order to set up your server, you should start by following these tutorials:

  1. How to Create Your First DigitalOcean Droplet Virtual Server
  2. How to Connect to Your Droplet with SSH
  3. Initial Server Setup with Ubuntu 14.04
  4. Additional Recommended Steps for New Ubuntu 14.04 Servers
  5. How To Protect SSH with Fail2Ban on Ubuntu 14.04

I followed these pretty much exactly without any difficulties. I did make a few changes to their procedure, which I’ll describe next.

Allowing HTTPS with UFW

I found that the instructions for setting up ufw needed a tweak. Since HTTPS traffic uses port 443 on the server, I thought that sudo ufw allow 443/tcp should take care of letting HTTPS traffic through the firewall. Unfortunately, it doesn’t. In addition you should run the following:


$ sudo ufw allow https

$ sudo ufw enable

Your web server may not accept incoming HTTPS traffic if you do not do this. Note: you may not have noticed, but you also installed NGINX as part of the UFW tutorial.

Setting up Automatic Updates on Your Server

The default install of Ubuntu at DigitalOcean comes with the automatic updates package already installed. This means your server will get security packages and upgrades without you having to do it manually. However, this package needs to be configured. First, edit /etc/apt/apt.conf.d/50unattended-upgrades to look like this:

Unattended-Upgrade::Allowed-Origins {
   "${distro_id}:${distro_codename}-security";
   "${distro_id}:${distro_codename}-updates";
};
Unattended-Upgrade::Mail "admin@mydomain.com";
Unattended-Upgrade::Remove-Unused-Dependencies "true";
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "02:00";

Note, that this configuration will install upgrades and security updates, and will automatically reboot your server, if necessary, at 2:00AM, and it will purge unused packages from your system completely. Some people don’t like to have that much stuff happen automatically without supervision. Also, my /etc/apt/apt.conf.d/10periodic file looks like:

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
APT::Periodic::Unattended-Upgrade "1";

Which sets upgrades to happen daily, and purges to happen once a week.

Installing and Configuring R

Okay, now that your server is set up (you should be able to view the default NGINX page at http://your-domain-name.com), it’s time to install R.

Set the CRAN Repository in Ubuntu’s sources.list

The first step is to add your favorite CRAN repository to Ubuntu’s sources list. This will ensure that you get the latest version of R when you install it. To open and edit the sources list, type the following:


$ sudo nano /etc/apt/sources.list

Move the cursor down to the bottom of this file using the arrow keys, and add the following line at the bottom:


deb https://cran.cnr.berkeley.edu/bin/linux/ubuntu trusty/

Of course, you can substitute your favorite CRAN repo here. I like Berkeley. Don’t miss that there is a space between “ubuntu” and “trusty”. Hit CTRL+x to exit from this file. Say “yes” when they ask if you want to save your changes. The official docs on installing R packages on Ubuntu also recommend that you activate the backports repositories as well, but I found that this was already done on my DigitalOcean install.

Add the Public Key for the Ubuntu R Package

In order for Ubuntu to be able to recognize, and therefore trust, download, and install the R packages from the CRAN repo, we need to install the public key. This can be done with the following command:


$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 51716619E084DAB9

Install R

Run the following:


$ sudo apt-get update

$ sudo apt-get install r-base

When this is finished, you should be able to type R –version and get back the following message:


$ R --version

R version 3.2.2 (2015-08-14) -- "Fire Safety"
Copyright (C) 2015 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu (64-bit)

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under the terms of the
GNU General Public License versions 2 or 3.
For more information about these matters see
http://www.gnu.org/licenses/.

If you get this, you’ll know that R was successfully installed on your server. If not, you’ll need to do some troubleshooting.

Configure R to Use curl and Your CRAN Repository of Choice

Type the following to open up the Rprofile.site file:


$ sudo pico /etc/R/Rprofile.site

You may delete all of the content and add the following:


options(download.file.method="libcurl")

local({
    r <- getOption("repos")
    r["CRAN"] <- "https://cran.rstudio.com/"
    options(repos=r)
})

This will allow us to run install.packages('packagename') without specifying the repository later.

Install Dependencies and Packages Needed by Shiny Server

We’re going to need the devtools package, which means we need to install the libraries upon which it depends first (libcurl and libxml2):


$ sudo apt-get -y build-dep libcurl4-gnutls-dev

$ sudo apt-get -y install libcurl4-gnutls-dev

$ sudo apt-get -y build-dep libxml2-dev

$ sudo apt-get -y install libxml2-dev

Now we can install devtools, rsconnect, and rmarkdown:


$ sudo su - -c "R -e \"install.packages('devtools')\""

$ sudo su - -c "R -e \"devtools::install_github('rstudio/rsconnect')\""

$ sudo su - -c "R -e \"install.packages('rmarkdown')\""

$ sudo su - -c "R -e \"install.packages('shiny')\""

Install Shiny Server

Okay! Now we’re finally ready to install Shiny Server. Run the following:


$ cd ~ 
$ sudo apt-get install gdebi-core
$ wget https://download3.rstudio.org/ubuntu-12.04/x86_64/shiny-server-1.4.1.759-amd64.deb
$ sudo gdebi shiny-server-1.4.1.759-amd64.deb

At this point, your Shiny Server should be up and running, but we can’t visit it on the web yet because by default, it runs on port 3838, which is blocked by the firewall we set up earlier. We’re now going to secure it, and use a reverse proxy to run it through NGINX.

Install an SSL Certificate with Let’s Encrypt

Let’s Encrypt is a new, free service that will allow you to install a trusted SSL certificate on your server. Since Google and Mozilla are working hard to phase out all non-HTTPS traffic on the web, it’s a good idea to get into the habit of installing SSL certs whenever you set up a new website. First install git, then use it to download letsencrypt:


$ sudo apt-get install git
$ git clone https://github.com/letsencrypt/letsencrypt
$ cd letsencrypt

Now before we install the certificate, we have to stop our web server (NGINX). In the code below, replace yourdomain.com with your actual domain name that you registered for this site.


$ sudo service nginx stop
$ sudo ./letsencrypt-auto certonly --standalone -d yourdomain.com -d www.yourdomain.com

If all goes well, it should have installed your new certificates in the /etc/letsencrypt/live/yourdomain.com folder.

Configure the Reverse Proxy on NGINX

Open up the following file for editing:


$ sudo nano /etc/nginx/nginx.conf

And add the following lines near the bottom of the main http block, just before the section labeled “Virtual Host Configs”. In my file, this started around line 62:


...

##
# Map proxy settings for RStudio
##
map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

##
# Virtual Host Configs
##
...

And then open up the default site config file:


$ sudo nano /etc/nginx/sites-available/default

And replace its contents with the following. Note you should replace yourdomain.com with your actual domain name, and 123.123.123.123 with the actual IP address of your server.


server {
   listen 80 default_server;
   listen [::]:80 default_server ipv6only=on;
   server_name yourdomain.com www.yourdomain.com;
   return 301 https://$server_name$request_uri;
}
server {
   listen 443 ssl;
   server_name yourdomain.com www.yourdomain.com;
   ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
   ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
   ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
   ssl_prefer_server_ciphers on;
   ssl_ciphers AES256+EECDH:AES256+EDH:!aNULL;

   location / {
       proxy_pass http://123.123.123.123:3838;
       proxy_redirect http://123.123.123.123:3838/ https://$host/;
       proxy_http_version 1.1;
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection $connection_upgrade;
       proxy_read_timeout 20d;
   }
}

Now start NGINX up again:


$ sudo service nginx start

And if all went well, your new Shiny Server should be up and running at https://yourdomain.com!

Note that even if you try to go to the insecure URL, traffic will be automatically redirected through HTTPS.

Setting Appropriate Permissions

Sometimes, your Shiny apps will need access to the filesystem to read or write files. Since the Shiny server runs as the user shiny, and since all the files that are being served are owned by root, then your apps will crash when they try to access files. I like Dean Attali’s solution. Run the following commands, substituting yourusername with the username you are using to access the server:


$ sudo groupadd shiny-apps
$ sudo usermod -aG shiny-apps yourusername
$ sudo usermod -aG shiny-apps shiny
$ cd /srv/shiny-server
$ sudo chown -R yourusername:shiny-apps .
$ sudo chmod g+w .
$ sudo chmod g+s .

In the future, any time you add files under /srv/shiny-server, you may need to change the permissions so the Shiny server can read them. We’ll do that in a moment.

Installing a New App

Finally, I’m going to show you how to put a new app on the server. We’re going to use the app that Nicole created and add it into the “sample apps” folder. Run the following:


$ cd /srv/shiny-server/sample-apps
$ mkdir sampdistclt
$ cd sampdistclt
$ nano server.R

This will create a new file called server.R and open it for editing. Copy and paste the second half of the code from Nicole’s post (the part that starts with ## server) into this file. Save and exit. Now create a second file in this directory called ui.R and paste the code from the first half of Nicole’s post (the part that starts with ## ui up to but not including the part that starts ## server). Save and exit.

Now you need to make sure that the permissions are set correctly:


$ chown -R :shiny-apps .

You may also need to restart the Shiny and/or NGINX servers. The commands to do that are:


$ sudo service nginx restart
$ sudo service shiny-server restart

If all has gone well, you can now view the app up and running at https://yourdomain.com/sample-apps/sampdistclt!

Conclusion

I haven’t had a lot of time to use this configuration, so please let me know if you find any bugs, or things that need to be tweaked. On the plus side, this configuration may be cheaper than using ShinyApps.io, but it also doesn’t have all the cool bells and whistles that you get there, either, like their user interface and monitoring traffic. At the very least, it should be a way to experiment, and put things out in the public for others to play with. Enjoy!

23 responses to “Deploying Your Very Own Shiny Server”

  1. […] based on statistical analysis with the R programming language to the web. I just wrote a guest post on Quality and Innovation (Nicole’s blog) on how to install your very own Shiny Server. Check it […]

  2. […] article was first published on Quality and Innovation » R, and kindly contributed to […]

  3. […] Deploying Your Very Own Shiny Server In this tutorial, I’m going to walk you through the process of: 1. Setting up an Ubuntu 14.04 + NGINX server at DigitalOcean 2. Installing and configuring R 3. Installing and configuring Shiny and the open-source edition of Shiny Server 4. Installing a free SSL certificate from Let’s Encrypt 5. Securing the Shiny Server using the SSL cert and reverse proxy through NGINX 6. Setting appropriate permissions on the files to be served 7. Creating and launching the app Nicole created in her recent post […]

  4. flaviomargarito Avatar
    flaviomargarito

    Hello, take a look at this: http://www.rmining.net/2015/05/11/git-pushing-shiny-apps-with-docker-dokku/

    I think might be a more economical and easy approach.

    1. Morgan Benton Avatar
      Morgan Benton

      That’s super cool! I don’t know if it is more economical (it costs the same $5/month), but I do like the push-to-deploy capability. I’ve been curious about Docker for some time now. Your post is making me think it’s time to finally figure out what all the hubbub is about. Thanks!

      1. Morgan Benton Avatar
        Morgan Benton

        @tony Thanks! I was excited to see your post, and look forward to digging into Docker a bit more. BTW, I’ve been a follower of @psychemedia for years (seriously, like maybe 10 years!). I don’t even remember what prompted me to follow you at the beginning but I really enjoy your insights on where technology meets society meets policy.

      2. Tony Hirst Avatar

        @morgan Glad to be of service! 😉

        As a technology optimist, I guess I generally accept claims folk make for technology and then I try to actually use it to see what sort of adoption path there might actually be for it – or not as the case may be…!

        Docker style containerisation is really exciting I think, perhaps even more so when considering linked containers that can work together (eg as per http://blog.ouseful.info/2015/01/14/using-docker-to-build-course-vms/ ).

        The ability to fire stuff up either locally or in the cloud is also rich with possibilities (I just wish Kitematic was developing these alternative modes of deployment a bit faster.. although I can’t help feeling it would be even nicer if there was something like Kitematic that ran through a browser….)

  5. […] RBloggers, I spotted this post on Deploying Your Very Own Shiny Server. I’ve been toying with the idea of running some of my own Shiny apps, so that post provided a […]

  6. Tony Hirst Avatar

    Prompted by this post, I’ve also done a walkthrough, showing how to run shiny server and one or more shiny apps using docker containers: [How to Run A Shiny App in the Cloud Using Tutum, Digital Ocean and Docker Containers] (http://blog.ouseful.info/2015/12/10/how-to-run-a-shiny-app-in-the-cloud-using-tutum-digital-ocean-and-docker-containers/)

  7. bexleymike Avatar

    Hello! Your tutorial is very easy to follow so far. Step by step like this is always helpful for newbies like myself! One issue I am having though is when I am attempting to install the devtools, rsconnect, and rmarkdown packages. I am getting an error when trying to run the statement. The error I receive says, -bash: syntax error near unexpected token `(‘ Any ideas what may be causing this? Please assume you are talking to a young 53 year old child!! 🙂 Thank you!

    1. Morgan Benton Avatar
      Morgan Benton

      @mike, thanks for the feedback! “bash” is the name of the programming language that Linux uses on the command line. A “syntax error” is a fancy way of saying “typo”. “unexpected token” means that the opening parentheses symbol is the one the computer thinks is in the wrong place, but “near” means it is not quite sure. Make sure you type these commands exactly as they appear in the tutorial, including backslashes, and also making sure you don’t mix up single- and double-quotes. Even one character out of place can cause the whole thing to not work. (Also, do NOT type the “$” at the beginning of the line, that’s just to indicate that these are terminal commands, but given the error message, I think you probably knew that.) Write back if this does not resolve your issue! 🙂

      1. bexleymike Avatar

        Hello @morgan! Thanks for the help! I’m not sure where I had the typo ( I even copy/pasted the line!), but when I tried again this evening, it worked fine. The packages are all installed! I have another question though, and I think I know the answer. I installed the 32bit version of Ubuntu when doing the initial set up. I just noticed Shiny Server only supports 64 bit. Does this mean, I need to start over again from scratch? If so, it only proves I learn best from mistakes. Based on the number of errors I have committed so far, I should be a genius by now!! 🙂 Thanks again for your kind assistance!

      2. Morgan Benton Avatar
        Morgan Benton

        Unfortunately, yeah, I think you need to start over. Should go much more quickly this time, though! The 2nd time I did it took way less than half the time. Send us a link to your working apps when you get them up and running!

      3. bexleymike Avatar

        @morgan, thanks for the confirmation! I’m a newbie, but learning quickly. I’d be happy to send that link when everything’s up and working! You have been a great help, so thank you again!!

      4. bexleymike Avatar

        Hello @morgan!! I am soooooo close to having this thing work! It’s been a week and I’ve got a little less hair, but I have the Shiny server showing. Unfortunately, I’m getting errors on the page because devtools and/or its dependencies would not install. I’ve researched the issue and have only found quite a few others that have similar issues. Do you know of a way to get around the problem with what I believe are incompatibility issues? Or maybe in your experience, you may know it is actually something else. I know the question is not worded the best, but I’m hoping you know what I am asking. Thanks @morgan! You can see the results I have so far at https://www.kahlercloud.com

  8. […] server in the cloud and hosting my apps there. Two tutorials posted by veteran users (available here and here) helped me get started, but experience using Linux (and particularly Ubuntu) was helpful […]

  9. lduarte Avatar
    lduarte

    I don’t know if the site is still up.
    https://shinyisat.net/sample-apps/sampdistclt/.

  10. […] testing, I’ll use the self-signed method. If you need a trusted certificate, there’s a good tutorial on using letsencrypt to get a free trusted […]

  11. risingstar265 Avatar

    Hi Morgan.. Very nice & well explained article.
    I am planning to setup the R Shiny Pro at my workplace. Can you suggest the server hardware requirements for the same. Data size would be few GB(2-3 GB) and number of users would be around 20.

    Thanks

    1. Morgan Benton Avatar
      Morgan Benton

      I use an Ubuntu box at Digital Ocean. The $5/month virtual machine has 512MB RAM, 20GB SSD, and should easily be able to handle 20 users. In the event that you outgrow it, it is relatively easy to upgrade to a box with more capacity.

  12. Jeff Paul Botsford

    Deploying Your Very Own Shiny Server ⋆ Quality and Innovation

  13. startup accelerator

    Deploying Your Very Own Shiny Server ⋆ Quality and Innovation

Leave a Reply

I’m Nicole

Since 2008, I’ve been sharing thoughts and insights about Digital Transformation & Data Science for Performance Excellence here. For 20 years, I’ve been helping organizations build teams, programs, and strategies bridging data, analytics, and artificial intelligence (AI)/machine learning (ML)… while building and training models in R and Python on the side. More About Me or Inquire @ Engaging a Team

Let’s connect