Preview Image from shinyproxy.io
One of the neat things about ShinyProxy is that it allows you to package your Shiny applications into Docker containers and then serve them up via centralised “App Store” like front-end with all the goodies you might want (authentication, logging, etc). You get the bonus of building these containers in a container (so some dependency management) and scaling of containers with whatever backend you need.
The deployment with a Shiny package or even a Flask application is very straightforward and well documented on their website, but what about simple html webpages generated from R Markdown or even entire websites. In my experience, there is a middle ground for html reports for single topic issues and larger website frameworks for larger packages. In an enterprise setting you still want to be able to serve all of these products to customers with authentication. So how can we do it?
Generate a Consistent Output Location
No matter what your output, send it to a consistent directory (my favourite is a “docs” directory that contains all my outputs). This can be the output from a single file or an entire website (thinking here something generated from R Markdown, Blogdown, Bookdown, etc).
Tell the Container to Host the Website
Initially, I had tried to write a container as a full Apache webserver, then write out the docs files to the webserver. That was until I realised the power of the {servr} package to abstract that functionality away and keep me in the R domain. The real clue was in this question and it dawned on me to let R do the work for us. We only need to be consistent in our output location and file format and make sure that ShinyProxy knows where to serve the site (and R inside the container).
For Static Htmls Packages
Below can work for generally every kind of output.
FROM openanalytics/r-base
# install required R packages
RUN install.r servr
# install pandoc
RUN wget https://github.com/jgm/pandoc/releases/download/2.6/pandoc-2.6-1-amd64.deb
RUN dpkg -i pandoc-2.6-1-amd64.deb
COPY docs /root/docs/
# use default port for shinyproxy apps, so you don't have to add port in application.yml
EXPOSE 3838
CMD ["R", "-e", "servr::httd('/root/docs', port = 3838, host = '0.0.0.0')"]
For Bookdown
If you wanted to rebuild and serve a bookdown generated book you could do the following:
FROM openanalytics/r-base
# install required R packages
RUN install.r bookdown servr
# install pandoc
RUN wget https://github.com/jgm/pandoc/releases/download/2.6/pandoc-2.6-1-amd64.deb
RUN dpkg -i pandoc-2.6-1-amd64.deb
COPY docs /root/docs/
# use default port for shinyproxy apps, so you don't have to add port in application.yml
EXPOSE 3838
CMD ["R", "-e", "bookdown::serve_book('/root/docs', port = 3838, host = '0.0.0.0')"]
Conclusion
You can see from the above Dockerfile, the solution is pretty easy and allows you to quickly containerise your reporting in addition to application.
Reuse
Citation
@online{dewitt2020,
author = {Michael DeWitt},
title = {ShinyProxy {Serving} {Websites}},
date = {2020-10-03},
url = {https://michaeldewittjr.com/programming/2020-10-03-shinyproxy-serving-websites},
langid = {en}
}