Skip to main content

shinyproxy

自动生成shiny的Dockerfile

https://www.jumpingrivers.com/blog/shiny-auto-docker/

functions

glue_sys_reqs = function(pkgs) {
rlang::check_installed("curl")
rspm = Sys.getenv("RSPM_ROOT", "https://packagemanager.rstudio.com")
rspm_repo_id = Sys.getenv("RSPM_REPO_ID", 1)
rspm_repo_url = glue::glue("{rspm}/__api__/repos/{rspm_repo_id}")

pkgnames = glue::glue_collapse(unique(pkgs), sep = "&pkgname=")

req_url = glue::glue(
"{rspm_repo_url}/sysreqs?all=false",
"&pkgname={pkgnames}&distribution=ubuntu&release=22.04"
)
res = curl::curl_fetch_memory(req_url)
sys_reqs = jsonlite::fromJSON(rawToChar(res$content), simplifyVector = FALSE)
if (!is.null(sys_reqs$error)) rlang::abort(sys_reqs$error)

sys_reqs = purrr::map(sys_reqs$requirements, purrr::pluck, "requirements", "packages")
sys_reqs = sort(unique(unlist(sys_reqs)))
sys_reqs = glue::glue_collapse(sys_reqs, sep = " \\\n ")
glue::glue(
"RUN apt-get update -qq && \\ \n",
" apt-get install -y --no-install-recommends \\\n ",
sys_reqs,
"\ && \\\n",
" apt-get clean && \\ \n",
" rm -rf /var/lib/apt/lists/*",
.trim = FALSE
)
}

shiny_write_docker = function(
path = ".", appdir = "app", lockfile = "shiny_renv.lock",
port = 3838, expose = TRUE, rspm = TRUE
) {
rspm_env = ifelse(
rspm,
"ENV RENV_CONFIG_REPOS_OVERRIDE https://packagemanager.rstudio.com/cran/latest\n",
""
)
from_shiny_version = glue::glue("FROM rocker/shiny:{getRversion()}")
renv::snapshot(
project = path,
lockfile = lockfile,
prompt = FALSE,
force = TRUE
)
pkgs = renv::dependencies(appdir)$Package
sys_reqs = glue_sys_reqs(pkgs)
copy_renv = glue::glue("COPY {lockfile} renv.lock")
renv_install = 'RUN Rscript -e "install.packages(\'renv\')"'
renv_restore = 'RUN Rscript -e "renv::restore()"'

copy_app = glue::glue("COPY {appdir} /srv/shiny-server/")
expose = ifelse(expose, glue::glue("EXPOSE {port}"), "")
cmd = 'CMD ["/usr/bin/shiny-server"]'

ret = purrr::compact(list(
from_shiny_version,
rspm_env,
sys_reqs,
copy_renv,
renv_install,
renv_restore,
copy_app,
expose,
cmd
))
readr::write_lines(ret, file = file.path(path, "Dockerfile"))
}

auto-generate dockerfile file

shiny_write_docker(path = ".", appdir = "app")

build docker image

docker build -t your_image_name .

test

docker run --rm -p 3838:3838 your_image_name

docker build issues Alt text

docker build --no-cache -t your_image_name .