I have a shiny app where packages are loaded using library()
in the server.R file. This works, but I am not sure if this is the best way to do it.
When I converted this app into an R package, I removed the library
calls. Added a DESCRIPTION file and an R file in which I created a function like this:
...
#' @importFrom tidyr gather spread
#' @importFrom viridisLite viridis inferno magma plasma
#' @importFrom writexl write_xlsx
#' @export
#'
run_my_app <- function(display.mode="normal",launch.browser=TRUE,...) {
appDir <- system.file("app", package="mypackage")
shiny::runApp(appDir,display.mode=display.mode,launch.browser=launch.browser,...)
}
Once the package is installed, run library(mypackage)
and run the function run_my_app()
which launches the app in the browser. Everything works.
Now, I am dockerizing this app/R package. I am trying two ways and it doesn't seem to work. This is the first approach (only showing relevant code from the Dockerfile ).
RUN mkdir /srv/shiny-server/mypackage
RUN Rscript -e 'system(paste0("cp -r ",system.file(package="mypackage"),"/app/* /srv/shiny-server/mypackage"))'
RUN sudo chown -R shiny:shiny /srv/shiny-server
EXPOSE 3838
# run shiny server
CMD ["/usr/bin/shiny-server.sh"]
When run like docker run --rm -p 127.0.0.1:3838:3838 myimage
, this launches the app correctly, but functions from dependency packages do not work, probably because I do not have any library()
or require()
calls.
This is the second approach (just like how a user would use the shiny app r package) which avoids most of the above script.
EXPOSE 3838
RUN Rscript -e 'library(mypackage);mypackage::run_my_app(port=3838,host="127.0.0.1",launch.browser=FALSE)'
But I already get stuck at the docker build image since it starts running the app during the build and the app doesn't work properly either.
Sure, I could skip the R package part and just use the shiny app in docker, but that involves having to maintain another set of code. I think I would prefer to keep the shiny app as an R package.
How is the best way to work with libraries while dockerizing a shiny app R package?
Turns out, there are multiple ways to launch a shiny app inside a docker container. And they differ in how they work. Details are discussed here .
I have ended up choosing the first method (For reasons discussed in the above link) and keeping the library()
calls. The calls have been moved to a file functions.R
(has other helper functions) which is sourced from ui.R
and server.R
like source("functions.R",local=TRUE)
. Not sure if the local=TRUE
is needed. Saw it recommended elsewhere.
Details on how to handle NAMESPACE/ library()
calls and using a shiny app inside R package is not entirely clear to me. Since the helper functions inside functions.R
is used in ui.R
and server.R
, I source them in both. It is not clear to me which file is executed first.
The second method didn't work because I should have used CMD
rather than RUN
. Something like this:
CMD ["R", "-e", "mypackage::run_my_app(port=3838,host='127.0.0.1',launch.browser=FALSE)"]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.