我正在尝试使用 golem::add_dockerfile_with_renv 函数为 Golem Shiny 应用程序创建 Dockerfile。我是 Docker 新手,无法构建镜像,因为我不明白如何处理我自己的 Golem 包的集成。
应用程序以正常方式启动时正在工作(app.R => pkgload::load_all; MyPackage::run_app())。
该应用程序当前正在使用 renv,尽管我希望将来只安装给定摇杆图像中可用的最新软件包。我的 Golem R 包(我们称之为 MyPackage)被快照到 renv.lock 中:
"MyPackage": {
"Package": "MyPackage",
"Version": "0.0.0.9000",
"Source": "Local",
"RemoteType": "local",
"RemoteUrl": "/home/myuser/repos/mypackage",
"Requirements": [
"DBI",
"R",
"RPostgres",
"blastula",
"config",
"dplyr",
"glue",
"golem",
"magrittr",
"pins",
"pkgload",
"plotly",
"rlang",
"scales",
"sf",
"shiny",
"shiny.i18n",
"shinyWidgets",
"shinyalert",
"shinycssloaders",
"shinyhelper",
"shinyjs"
],
"Hash": "f03..."
当我跑步时
golem::add_dockerfile_with_renv(lockfile = "./renv.lock", output_dir = "deploy", from = "rocker/verse")
Dockerfile, Dockerfile_base, README, renv.lock, myPackage_0.0.0.9000.tar.gz
当我按照README中的说明运行时
sudo docker build -f Dockerfile_base --progress=plain -t myPackage_base .
它失败了
#12 36.80 - Downloading MyPackage from Repository ... ERROR [error code 22]
#12 37.02 Warning: failed to find source for 'MyPackage 0.0.0.9000' in package repositories
#12 37.02 Warning: error downloading 'https://cloud.r-project.org/src/contrib/Archive/MyPackage/MyPackage_0.0.0.9000.tar.gz' [error code 22]
#12 37.02 Error: failed to retrieve package '[email protected]'
MyPackage 在 renv.lock 中明确标记为“来源:本地”,并且根据 renv::status(),项目处于一致状态。
我认为我有两个选择:
renv::snapshot(exclude = "MyPackage")
),将 MyPackage 目录复制到 Docker 中并使用 remotes::install_local(".")
或 golem::add_dockerfile_with_renv()
自动理解/正确处理的方式调整renv.lock中的RemoteUrl。我尝试了两种方法(有多种变体),但没有任何效果。 有人能给我指出一个解决方案吗?你如何使用 renv 处理你的 Golem 包裹?您对它进行快照还是排除它?如何将其安装到图像中?提前感谢您的帮助!
Dockerfile_base:
FROM rocker/verse:4.1.3
RUN apt-get update -y && apt-get install -y libpq-dev make libicu-dev libxml2-dev pandoc libcurl4-openssl-dev libssl-dev git libfontconfig1-dev libfreetype6-dev libfribidi-dev libharfbuzz-dev libjpeg-dev libpng-dev libtiff-dev zlib1g-dev libssh2-1-dev libgdal-dev gdal-bin libgeos-dev libproj-dev libsqlite3-dev libudunits2-dev && rm -rf /var/lib/apt/lists/*
RUN mkdir -p /usr/local/lib/R/etc/ /usr/lib/R/etc/
RUN echo "options(renv.config.pak.enabled = FALSE, repos = c(CRAN = 'https://cran.rstudio.com/'), download.file.method = 'libcurl', Ncpus = 4)" | tee /usr/local/lib/R/etc/Rprofile.site | tee /usr/lib/R/etc/Rprofile.site
RUN R -e 'install.packages("remotes")'
RUN R -e 'remotes::install_version("renv", version = "1.0.7")'
COPY renv.lock renv.lock
RUN R -e 'renv::restore()'
我尝试过各种解决方法。
renv::snapshot(exclude="MyPackage")
),将其复制到 Docker 镜像并 install_localCOPY . /app
WORKDIR /app
RUN R -e "remotes::install_local('/app')"
结果:
#12 0.466 > remotes::install_local('/app')
#12 0.478 Error: Failed to install 'unknown package' from local:
COPY /home/myuser/repos/mypackage/ /app
结果:ERROR: failed to solve: failed to compute cache key: failed to calculate checksum of ref cb58...::yqll2...: "/home/myuser/repos/mypackage": not found
(目录存在并且与排除前的 renv.lock 中的目录相同)
FROM rocker/verse:4.1.3
RUN apt-get update && apt-get install -y gdal-bin libcurl4-openssl-dev libgdal-dev libgeos-dev libicu-dev libpq-dev libproj-dev libsqlite3-dev libssl-dev libudunits2-dev libxml2-dev make pandoc zlib1g-dev && rm -rf /var/lib/apt/lists/*
RUN mkdir -p /usr/local/lib/R/etc/ /usr/lib/R/etc/
RUN echo "options(repos = c(CRAN = 'https://cran.rstudio.com/'), download.file.method = 'libcurl', Ncpus = 4)" | tee /usr/local/lib/R/etc/Rprofile.site | tee /usr/lib/R/etc/Rprofile.site
RUN R -e 'install.packages("remotes")'
RUN Rscript -e 'remotes::install_version("magrittr",upgrade="never", version = "2.0.3")'
[...]
RUN mkdir /build_zone
ADD . /build_zone
WORKDIR /build_zone
RUN R -e 'install.packages("remotes");remotes::install_local(path = ".", upgrade="never")'
RUN rm -rf /build_zone
EXPOSE 80
CMD R -e "options('shiny.port'=80,shiny.host='0.0.0.0');MyPackage::run_app()"
结果:
Could not copy /build_zone to /tmp/Rtmp...
在这种情况下,图像仍然会构建,当我进入 docker 容器时
sudo docker run -it ... /bin/bash
我看不到任何阻止复制到 /tmp 的目录权限或磁盘空间等问题。在容器内手动复制也可以。可能不相关,但我已将自己的 tmp 目录设置为这样的外部驱动器
由于 / 上的磁盘空间问题,在 .Renviron 内TMPDIR=/mnt/encrypted_disk/tmp_dir/
。
是的,在使用 R/Docker 之前加密的_disk 已被解密。
对我有用的是不仅从 renv 快照中删除包,而且从已安装的库中删除包,执行类似的操作
remove.packages('MyPackage')
现在您可以
add_dockerfile_with_renv
完成剩下的事情。