Deploy shiny app in rocker/shiny docker - r

Well, I'm new at Docker and I need to implement a Shiny app in a Docker Container.
I have the image from https://hub.docker.com/r/rocker/shiny/, that includes Shiny Server, but I don't know how to deploy my app in the server.
I want to deploy the app in the server, install the required packages for my app into the Docker, save the changes and export the image/container.
As I said, I'm new at Docker and I don't know how it really works.
Any idea?

I guess you should start by creating a Dockerfile in a specific folder which would look like something like this :
FROM rocker/shiny:latest
RUN echo 'install.packages(c("package1","package2", ...), \
repos="http://cran.us.r-project.org", \
dependencies=TRUE)' > /tmp/packages.R \
&& Rscript /tmp/packages.R
EXPOSE 3838
CMD ["/usr/bin/shiny-server.sh"]
Then go into this folder and build your image, giving it a name by using this command :
docker build -t your-tag .
Finally, once your image is built you can create a container, and if you don't forget to map the volume and the port, you should be able to find it at localhost:3838 with the following command launched from the folder containing the srv folder :
docker run --rm -p 3838:3838 -v $PWD/srv/shinyapps/:/srv/shiny-server/ -v $PWD/srv/shinylog/:/var/log/shiny-server/ your-tag
As said in the Docker documentation at the following address https://hub.docker.com/r/rocker/shiny/, you might want to launch it in detached mode with -d option and map it with your host's port 80 for a real deployment.

The link(https://hub.docker.com/r/rocker/shiny/) covers how to deploy the shiny server.
Simplest way would be:
docker run --rm -p 3838:3838 rocker/shiny
If you want to extend shiny server, you can write your own Dockerfile and start with shiny image as base image.(https://docs.docker.com/engine/reference/builder/)
Dockerfile:
FROM rocker/shiny:latest

Related

How to create a docker image of an existing R Shiny app in windows?

The dockerization process of an R shiny app is done through rocker/shiny image. I require to run the dockerization on an R shiny app from a windows system. The only problem is that rocker/shiny used for this process is a Linux based container. Therefore, I am unable to generate an image that runs on my windows system. Utilization of an external VPS or VM is not an option for me due to security reasons.
I have tried writing a docker file that would run for windows, but the problem is that the container is Linux based.
My Dockerfile
FROM rocker/r-ver:3.5.1
#installing R libraries
RUN R -e "install.packages(c('shiny', 'shinydashboard'), repos='http://cran.us.r-project.org')"
# Copy configuration files into the Docker image
COPY shiny-server.conf /etc/shiny-server/shiny-server.conf
COPY /app/srv/shiny-server/
# Make the ShinyApp available at port 80
EXPOSE 80
#Copy further configuration files into the Docker image
COPY shiny-server.sh /usr/bin/shiny-server.sh
CMD ['Rscript', 'app_run.R']
(original documentation mentions a .sh file which is not running on my system
because of the Linux windows file path issues)
After running there 2 commands I expect my shiny app to run on localhost:8080
Get-Content Dockerfile | docker build -
docker run --name DOCKERapp -p 8080:8080 <image_name>
The base in your dockerfile is rocker/r-ver:3.5.1 and the based of this image is debian. You can check here:
https://hub.docker.com/r/rocker/r-ver/dockerfile
So in your dockerfile you need to use linux commands. You don't need to use windows commands.

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.
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.
Minimal Reproducible Example
Create an empty directory (can be called anything you want)
Inside it, create two things:
i. A file called Dockerfile
ii. An empty directory called app
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.
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

Open RStudio Project from the attached volume when starting Rocker container

I am trying to build my works using Docker System. It would be nice to start Rstudio server when I start a container attaching a project from a mounted volume. For example, I can start the docker as,
docker run -d -p 8787:8787 -v $(pwd):/home/rstudio --name rocker rocker/verse:latest
It runs Rstudio server and I can access it from 8787 port but it would be nice to load the project from /home/rstudio when I start the container.
There's a hidden file you can modify:
~/.rstudio/projects_settings/switch-to-project
Populate it with the path of the project you want RStudio to open at startup.

Mount local volume accessible to R/RStudio in docker (tidyverse)

There are a ton of little-upvoted questions about how to address local folders from inside a docker container, but I can't find one that quite matches mine, so here goes another one:
How can I run a docker container, and mount a local folder so that it's accessible by R/RStudio, inside the container?
That sounds kind of like: mounting local home directory in Rstudio docker? and using an approach similar to that, I can start a container and mount a volume:
docker run -d -p 8787:8787 -v $HOME/my_folder:/LOOKATMEEE -e ROOT=TRUE rocker/tidyverse:3.4
and if I run a bash shell in the container, I can see the folder:
docker exec -it 38b2d6ca427f bash
> ls
bin dev home lib LOOKATMEEE mnt proc run srv tmp var boot etc init lib64 media opt root sbin sys usr
# ^ there is is!
But if I go connect to RStudio server at localhost:8787, I don't see it in the files pane, nor does it show up when run list.files() in the R console:
I'm sure I'm missing something basic, but if someone can tell me what that is... thank you!
In this circumstance, R and RStudio have a default working directory of /home/rstudio, two levels down from /, where I was telling docker to mount the folder.
After the docker run command in the question, you can go list.files('/') to see the folder.
If you want your folder to show up in the default working directory for R, as I do, then modify docker run like this:
docker run -d -p 8787:8787 -v $HOME/my_folder:/home/rstudio/LOOKATMEEE -e ROOT=TRUE rocker/tidyverse:3.4
and there it shall be:
Thank you to user alistaire.
This answer is for future generations :)
The concept is a "match" of the resource from the host with the container:
:
The command structure should be like this:
docker run -d -e PASSWORD= -p 8787:8787 -v
: /home/rstudio/ rocker/rstudio
Check the explanation here

how can I set the working directory in old version of docker in the run command?

I am a bit new to docker and I have been trying to run deploy a meteor container with my meteor application. I have been using the dockerfile and instructions from https://registry.hub.docker.com/u/golden/meteor-dev/
However, I cant run docker run -p 3000:3000 -t -i -v /path/to/meteor/app:/opt/application -w /opt/application meteor-dev because my docker (version 0.5.3) does not recognize the flag (-w) to set the working directory.
Is there some workaround to set the working directory with docker 0.5.3? The work directory is already set in the docker file, but I guess I need to set it again when I run the container.
well, my workaround was to create a bash script that would go to the working directory and call the commands one by one. I created the bash script where my source is located "/path/to/meteor/app" and call docker run -p 3000:3000 -t -i -v /path/to/meteor/app:/opt/application meteor-dev bash /opt/application/start.sh with the bash as command and my script as argument

Resources