为 Golem Shiny 应用程序构建 Docker 镜像由于自带的 golem 包而失败

问题描述 投票:0回答:1

我正在尝试使用 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(),项目处于一致状态。

我认为我有两个选择:

  1. 从 renv.lock 中排除 MyPackage (
    renv::snapshot(exclude = "MyPackage")
    ),将 MyPackage 目录复制到 Docker 中并使用
    remotes::install_local(".")
  2. 在那里构建它
  3. 尝试以
    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()'

我尝试过各种解决方法。

  1. 从 renv.lock 中排除 MyPackage (
    renv::snapshot(exclude="MyPackage")
    ),将其复制到 Docker 镜像并 install_local
COPY . /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:
  1. 与 1 类似,但带有
    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 中的目录相同)

  1. 使用 golem::add_dockerfile() 代替
    Dockerfile 看起来像这样:
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 已被解密。

  1. 我看过这个https://stackoverflow.com/a/72017488/18714313但我认为它不适用于我的问题。
r docker shiny dockerfile golem
1个回答
0
投票

对我有用的是不仅从 renv 快照中删除包,而且从已安装的库中删除包,执行类似的操作

  1. 停用租金
  2. 通过运行
    remove.packages('MyPackage')
  3. 从 R 库中删除 MyPackage
  4. 重新激活 renv 并拍摄新快照,确保 MyPackage 不在锁定文件中

现在您可以

add_dockerfile_with_renv
完成剩下的事情。

© www.soinside.com 2019 - 2024. All rights reserved.