Deploying shiny apps on aws using docker

Recently, I decided to migrate my shiny apps to amazon webservices. Most of them were running on the shinyapps.io platform. Why did I decide to migrate my apps?

  • In the free version of shinyapps it is only possible to deploy 5 apps which is not enough for me. The cheapest option then is to have the starter subscription which costs 9 dollar per month. It’s not a lot of money, but I think it can be cheaper to use and AWS instance (though it requires more work)
  • I would like to be flexible and not having to use the shinyapps configuration. For example I want to be able to change the configuration of the shiny server.
  • I would like some more experience with Docker. Docker is an which is a container system, that allows for “Build, Ship and Run Any App, Anywhere”.

Docker  – R Shiny container

To get started with docker you will need an image. An image is an immutable blueprint of an operation environment, while a container is an instance of an image. For programmers, you can compare it with classes and objects where images are the classes and containers the objects.

There are a lot of images already available on docker hub, so you might want to check them out first. For R and shiny server there is also quite some choice. I first used the Rocker/Shiny image to try to deploy my apps. I found out that most of my applications were not starting unfortunately. So, let’s look at the log file..well it’s not there! It turns out that if the R process exits successfully, the log files will be removed by default (to not waste disk space). I turned this setting off, so I could find out what was going on. The problem why my apps were not starting was that some packages were missing. So I installed them, most of them were related to plotting (plotly, shinyjs, leaflet, etc).

Because of these 2 issues, I decided to create a custom DockerFile. It is based on Rocker/shiny but it will install the packages I need by default and it will save the log files.

FROM rocker/shiny:latest 

MAINTAINER Ger Inberg "*****@****.com"

# install ssl
RUN sudo apt-get update; exit 0
RUN sudo apt-get install -y libssl-dev

# install additional packages
RUN R -e "install.packages(c('ggplot2', 'plotly', 'shinyjs', 'shinyBS', 'leaflet', 'ggmap', 'webshot', 'DT', 'shinydashboard'), repos='https://cran.rstudio.com/')"

# copy shiny-server config file
COPY shiny-server.conf /etc/shiny-server/shiny-server.conf

CMD ["/usr/bin/shiny-server.sh"]

On the docker site, you can find how to create an image from a DockerFile.

Shiny Server configuration

Shiny server comes with a default configuration, which includes the default port number (3838), location of the log file directory, etc. I have only added the lines in blue.

# Instruct Shiny Server to run applications as the user "shiny"
run_as shiny;
# preserve logs!
preserve_logs true;

# 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 on;
 }
}

Run docker instance on AWS

I assume you have already a running AWS instance Docker is installed. Furthermore I assume your shiny apps are already installed on the AWS instance. From there on it is easy to get up and running.

Below are the commands I have executed to use my own docker image to host my shiny apps.

# Get the image
docker pull ginberg/shiny

# run the docker image such that shiny server is running on port 80
# furthermore use the -v option to map the application directory and log file directory from aws instance fs to docker fs
docker run --rm -p 80:3838 -v /home/ubuntu/shiny/apps:/srv/shiny-server/ -v /home/ubuntu/shiny/apps/logs:/var/log/shiny-server/ ginberg/shiny & 

# view log files directory
ls -al /home/ubuntu/shiny/apps/logs

# to login on the docker image: view running processes and use the id
docker ps
docker exec -it <id> bash

Result

My deployed apps can be found here

I am wondering how and on which platform are you hosting your shiny apps? Please let me know if you have any questions about this article.

 

 

2 thoughts on “Deploying shiny apps on aws using docker

  1. Hi Ger, it’s been a while :)! I stumbled across your website while searching the Internet regarding an issue I am having with Dockerizing a shiny app that uses Leaflet, and was hoping I could get some tips as to how to solve it as you seem to be quite experienced with it. I have a shiny app that renders a map put together from offline tiles downloaded from OpenStreetMap that works perfectly when run in Rstudio or from an R command-line. Unfortunately when I try to run it on a docker container based on the rocker/shiny-verse image from DockerHub, the map does not render, however the minichart layer that goes on top of the map does. My first thought was that I may have some unmet dependencies, but even with specifically installing the versions that I also have locally I did not succeed. Have you already had similar problems? If so, how did you solve them? Best, Silvia

Comments are closed.