'How to run R Shiny App in Docker Container

I built a Docker Image for an R Shiny App and ran the corresponding container with Docker Toolbox on Windows 10 Home. When trying to open the App with my web browser, only the index is shown. I don't know why the app isn't executed.

The log shows me this:

*** warning - no files are being watched ***
[2019-08-12T15:34:42.688] [INFO] shiny-server - Shiny Server v1.5.12.1 (Node.js v10.15.3)
[2019-08-12T15:34:42.704] [INFO] shiny-server - Using config file "/etc/shiny-server/shiny-server.conf"
[2019-08-12T15:34:43.100] [INFO] shiny-server - Starting listener on http://[::]:3838

I already specified the app host-to-container path by executing the following command which refers to a docker hub image:

docker run --rm -p 3838:3838 -v /C/Docker/App/:/srv/shinyserver/ -v /C/Docker/shinylog:/var/log/shiny-server/  didsh123/ps_app:heatmap

My Docker File looks like the following:

# get shiny serves plus tidyverse packages image
FROM rocker/shiny-verse:latest

# system libraries of general use
RUN apt-get update && apt-get install -y \
    sudo \
    pandoc \
    pandoc-citeproc \
    libcurl4-gnutls-dev \
    libcairo2-dev \
    libxt-dev \
    libssl-dev \
    libssh2-1-dev

##Install R packages that are required--> were already succesfull
RUN R -e "install.packages(c('shinydashboard','shiny', 'plotly', 'dplyr', 'magrittr'))"

#Heatmap related packages
RUN R -e "install.packages('gpclib', type='source')"
RUN R -e "install.packages('rgeos', type='source')"
RUN R -e "install.packages('rgdal', type='source')"

# copy app to image
COPY ./App /srv/shiny-server/App

# add .conf file to image/container to preserve log file
COPY ./shiny-server.conf  /etc/shiny-server/shiny-server.conf


##When run image and create a container, this container will listen on port 3838
EXPOSE 3838

###Avoiding running as root --> run container as user instead
# allow permission
RUN sudo chown -R shiny:shiny /srv/shiny-server
# execute in the following as user --> imortant to give permission before that step
USER shiny

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

So when I address the docker ip and the assessed port in the browser, the app should run there, but only the index is displayed. I use the following line:

http://192.168.99.100:3838/App/

I'm glad for every hint or advice. I'm new to Docker, so I'm also happy for detailed explanations.



Solution 1:[1]

To use shiny with docker, I suggest you use the golem package. golem provides a framework for builing shiny apps. If you have an app developed according to their framework, the function golem::add_dockerfile() can be used to create dockerfiles automatically.

If you are not interested in a framework, You can still have a look at the source for add_dockerfile() to see how they manage the deployment. Their strategy is to use shiny::runApp() with the port argument. Therefore, shiny-server is not necessary in this case.

The Dockerfile in golem looks roughly like this

FROM rocker/tidyverse:3.6.1
RUN R -e 'install.packages("shiny")'
COPY app.R /app.R
EXPOSE 3838
CMD R -e 'shiny::runApp("app.R", port = 3838, host = "0.0.0.0")'

This will make the app available on port 3838. Of course, you will have to install any other R packages and system dependencies.

Additional tips

  • To increase reproducibility, I would suggest you use remotes::install_version() instead of install.packages().
  • If you are going to deploy several applications with similar dependencies (for example shinydashboard), it makes sense to write your own base image that can be used in place of rocker/tidyverse:3.6.1. This way, your builds will be much quicker.

Solution 2:[2]

Check the logs for any useful information? And exec into the container to verify if the App content is copied to the correct location.

Because the way /App content is copied looks incorrect

The content of /App is copied into the image to /srv/shiny-server/App during the build phase and you are trying to override /srv/shiny-server content using -v option when running the container.

Looks like during runtime the App data copied is being overwritten.

Try without -v /C/Docker/App/:/srv/shinyserver/ or use -v /C/Docker/App/:/srv/shinyserver/App/

docker run --rm -p 3838:3838 -v /C/Docker/shinylog:/var/log/shiny-server/ didsh123/ps_app:heatmap

Solution 3:[3]

Minimal Reproducible Example

  1. Create an empty directory (can be called anything you want)

  2. Inside it, create two things:

    i. A file called Dockerfile

    ii. An empty directory called app

  3. Place your shiny app inside the directory called app.

    • Your shiny app can be a single app.R file, or, for older shiny apps, ui.R and server.R. Either way is fine (see here for more on that).
  • If unsure about any of the above, just copy the files found here.

Place this in Dockerfile

FROM rocker/shiny:latest

COPY ./app/* /srv/shiny-server/

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

In the terminal, cd to the root of the empty directory you created in step 1, and build the image with

docker build -t shinyimage . 

Run the container with

docker run -p 3838:3838 shinyimage

Finally, visit this url to see your shiny app: http://localhost:3838/

Here's a copy of all of the above in case anything's unclear.

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Avinash Reddy
Solution 3 stevec