---
title: "Shiny Server Deployment"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Shiny Server Deployment}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

## Overview

ReviewR is designed to support multiple concurrent users when deployed using Shiny Server. When deployed on a centralized server an instance of ReviewR will be served to each connecting user in distinct R sessions allowing multiple participants to simultaneously connect to patient data and submit chart abstraction information. In server deployments, users will access ReviewR directly through a web browser without requiring a local R installation.

## Getting Started

Before deploying ReviewR to your server, you must first configure your environment to securely host Shiny applications. The overall process consists of 5 main components:

* [Obtain a domain](#obtain-a-domain)
* [Shiny Server Setup](#shiny-server-setup)
* [Configuring NGINX to Reverse Proxy Shiny Server](#configuring-nginx-to-reverse-proxy-shiny-server)
* [Securing Shiny Server URL with Let's Encrypt](#lets-encrypt)
* [Deploy ReviewR](#deploy-reviewr)

*Note: This vignette assumes you have access to a server running Ubuntu 18.04.* 

### Disclaimer

This guide **is not** [universally applicable](https://xkcd.com/1654/) to all server environments. It assumes that no prior services have been installed or configured on your server. It is intended for _informational purposes only_. We take no responsibility for suggesting configuration changes that break your operational setup. Please make modifications where necessary to adapt this guide to your specific environment and consult your IT department if applicable or necessary. 

Information provided in this vignette has been adapted from other guides that have been listed in the [Suggested Reading](#suggested-reading) section below.

### Suggested Reading 
* [Shiny Server: Quick Start Guide](https://support.posit.co/hc/en-us/articles/360011458854-Shiny-Server-Quick-Start-Installation-and-Configuration)
* [Shiny Server: Running with a Proxy](https://support.posit.co/hc/en-us/articles/213733868-Running-Shiny-Server-with-a-Proxy)
* [Let's Encrypt Getting Started](https://letsencrypt.org/getting-started/)
* [Secure NGINX with Let's Encrypt](https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-18-04)

## Obtain a Domain

Using a domain registrar of your choosing, obtain a domain name for your server. There are a wide variety of registrars that will  provide am domain name either for free of charge or for a small annual fee. Once you have obtained a domain name for your server, register your server's external IP address with your domain registrar of choice. Ideally, this external IP address is static, though services exist to update DNS records for servers with ephemeral IP addresses.

Once you have registered for a domain name and linked your domain with your server's IP you will be able to access your server with a plain text URL, rather than by a IP address. Additionally, a domain is required to encrypt connections to/from your server. This is because certificate authorities, like Let's Encrypt, are required to verify ownership of domains before security certificates can be issued. These certificates are what allows traffic to be SSL encrypted between clients and your server via the https standard. By registering your server's IP address with a domain registrar and associating it with a domain name, you are verifying that you own the site and take all responsibility for its functions.

## Shiny Server Setup

### Install Shiny Server Dependencies

Before installing Shiny Server, it is necessary to install a few prerequisites to your server. To begin, SSH into your server and perform the following steps:

1. Install R:
```{bash, eval=F}
sudo apt-get install r-base
```

2. Install R Shiny to your System R Package Library:
```{bash, eval=F}
sudo su - \
-c "R -e \"install.packages('shiny', repos='https://cran.rstudio.com/')\""
```

3. Install `gdebi`, which is an operating system package that is used to install Shiny Server, and additional dependencies:
```{bash, eval=F}
sudo apt-get install gdebi-core
```

### Install Shiny Server
Now that all prerequisites have been satisfied, download and install Shiny Server to your system:

```{bash, eval=F}
wget https://download3.rstudio.org/ubuntu-18.04/x86_64/shiny-server-1.5.20.1002-amd64.deb
sudo gdebi shiny-server-1.5.20.1002-amd64.deb
```

At this point, you will have a bare bones basic Shiny Server Installation. If you would like to verify that Shiny has installed correctly, you may attempt a connection from a different machine on the same network by visiting: `your.server.ip_address:3838`

Read on to learn how to secure this connection.

## Configuring NGINX to Reverse Proxy Shiny Server

At this stage, your Server is being hosted on port 3838 of your machine. In order to allow users to access this server via the domain that was acquired in the first portion of this guide, we will need to install and configure a reverse proxy which will direct clients securely to applications hosted on your shiny server. [NGINX](https://www.nginx.com/), an open source web server and reverse proxy will be used for the purposes of this guide.

### Install NGINX
To begin, install NGINX on your server:
```{bash, eval=F}
sudo apt update
sudo apt install nginx
```

You can verify this installation by visiting `your.server.ip_address` from a different machine on the same network. You should see a 'Welcome to nginx!" message if all was successful.

Depending on where your server is hosted, you may have to allow access to the server's IP address on ports 80 and 443. Firewall configuration is outside of the scope of this guide.

### Configure NGINX for use with Shiny Server

Next, we need to configure NGINX to proxy traffic from web clients to the Shiny Server, where Shiny applications will be hosted. To do this, we'll need to add a server block to NGINX with information about our Shiny Server. NGINX server blocks live in `/etc/nginx/sites-available/`. To initialize a server block for our shiny server, issue the following command:

```{bash, eval=F}
## substitute nano for your preferred text editor: emacs, jed, joe, pico, sandy, vi, vim, etc.
sudo nano /etc/nginx/sites-available/shiny
```

Modify the following server block code by replacing `your.shiny.server.url` with the domain name that you obtained in the [Obtain a Domain](#obtain-a-domain) section of this guide. Then, copy this text into the file that you are editing. 
```
server {

        server_name your.shiny.server.url;

        location / {
                proxy_pass http://localhost:3838;
                proxy_redirect / $scheme://$http_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;
        }
```

**Save and exit the file.** Verify that the has been created successfully by running:

```{bash, eval=F}
ls -l /etc/nginx/sites-available
```

A file called "shiny" should be among the files that is returned. 

Next, we need to enable the server block that we just created. With NGINX, this is accomplished by symlinking the server block to the `/etc/nginx/sites-enabled` folder. Run:

```{bash, eval=F}
sudo ln -s /etc/nginx/sites-available/shiny /etc/nginx/sites-enabled/shiny
```

At this point, your Shiny Server should be accessible at `http://your.shiny.server.url` . If the Shiny Server is not immediately available at your domain after completing all of the steps to this point, you may have to restart NGINX; `sudo systemctl reload nginx`

Continue to the next section to secure your server with Let's Encrypt.

## Securing Shiny Server URL with Let's Encrypt <a id="lets-encrypt"></a>

To begin, we will install the Certbot software on our server. This software makes it easy to secure our domain, by automatically verifying ownership, downloading and installing a [Let's Encrypt](https://letsencrypt.org/) certificate, automatically configuring nginx to use the certificate, and renewing the certificate before it expires. You want this software, trust me. To install Certbot, we'll need to add a software repository to our system. This will be accomplished by running:

```{bash, eval=F}
sudo add-apt-repository ppa:certbot/certbot
```

Next, we'll need to update our server's package list, and install the Certbot application for our nginx configuration:

```{bash, eval=F}
sudo apt update
sudo apt install python-certbot-nginx
```

As we have already configured a server block for NGINX in the previous section, we are ready to run the Certbot software to secure our domain. Run the following code block, substituting `your.shiny.server.url` with the domain that you configured in the nginx server block for shiny server:

```{bash, eval=F}
sudo certbot --nginx -d your.shiny.server.url
```

If this is your first time running Certbot, you will be prompted to enter an email address and agree to the terms of service. After doing so, Certbot will initiate a connection with the Let’s Encrypt server and then begin testing your server to verify that you control the domain you’re requesting a certificate for. Certbot will then ask you whether or not you'd like to redirect all HTTP traffic to HTTPS traffic. It is _highly recommended_ to do so. Please select the option for 'Redirect', which will ensure that users are _only_ capable of accessing your site via secure HTTPS.

Congratulations, your Shiny Server is now secured and ready to begin hosting Shiny Applications. Continue to the next section to learn how to deploy ReviewR to your Shiny Server.

## Deploy ReviewR

1. Install the ReviewR package as a _root user_ in order to ensure your system R package library has all of the required dependencies
    + From a **bash terminal**, run:
        ```{bash eval=FALSE}
        # Start R in an interactive root terminal
        sudo -i R
        ```
    *This will open an interactive R console as a root user*
    + From the **R console** that opens, run:
      ```{r eval=FALSE}
      # install.packages('devtools')
      devtools::install_github('thewileylab/ReviewR')
      ```
2. Continuing as the root user, fork the ReviewR repository into the Shiny Server directory (`/srv/shiny-server`) with the `usethis` package. Using the same **R console** from above: 
    ```{r eval=FALSE}
    # install.packages('usethis')
    usethis::create_from_github(repo_spec = 'thewileylab/ReviewR', destdir = '/srv/shiny-server')
    ```
    *This step will fork the most recent version of the ReviewR package from GitHub which includes additional files and development tools not built directly into the package. This includes an `app.R` file which Shiny Server will need to deploy ReviewR. By default, Shiny Server will host all applications that are placed in `/srv/shiny-server`*

That's it! ReviewR can now be accessed from your browser at: `https://your.shiny.server.url/ReviewR`
