【问题标题】:How to speed up R packages installation in docker如何在 docker 中加快 R 包的安装速度
【发布时间】:2018-07-24 13:51:22
【问题描述】:

假设您有以下要为 docker 映像安装的软件包列表

("jsonlite","dplyr","stringr","tidyr","lubridate",
"knitr","purrr","tm","cba","caret",
"plumber","httr")

安装这些实际上需要大约 1 小时!

关于如何加快这样的事情的任何建议? (或者如何防止在每次新镜像构建时重新安装?)

旁注

我不会像这样从 dockerfile 安装这些包:

RUN Rscript -e "install.packages('stringr')
...

相反,我创建了一个 R 脚本 Requirements.R 来安装这些包并简单地执行以下操作:

RUN Rscript Requirements.R

这些是否不如直接从 Dockerfile 安装包优化?

【问题讨论】:

    标签: r docker dockerfile


    【解决方案1】:

    尽可能使用二进制包,就像我们在Rocker Project 中经常做的那样,为 R 提供多个 Docker 文件,包括官方的 r-base 文件。

    如果你从 Ubuntu 开始,你会得到 Michael's PPAs 超过 3000 多个软件包;如果您从 Debian 开始,您从发行版中获得的收益会更少,但仍然有很多必不可少的。 (有一些努力为 Debian 带来更多的二进制包,但现在没有任何进展。)

    最后,Dockerfile 创建当然也是编译时间。您花费一次时间(每个容器创建)并在之后可能多次重复使用。此外,通过使用 Docker Hub,您可以避免花费本地 CPU 周期。

    2020 年 9 月编辑:(updated) Ubuntu PPA 现在有超过 4600 个用于三个最新 LTS 版本的包。仍然强烈,强烈推荐。

    【讨论】:

    • 您提到在 Rocker 中使用二进制包,但是当我查看 rocker/tidyverse 代码时,我看到声明 install2.r tidyverse,它似乎是从我的机器上的源代码安装的。有没有办法让这些语句从二进制文件中加载?谢谢!
    • 当然。对于 Ubuntu,指向 Rutter PPA 并使用它;我在我的 r-travis 存储库中这样做(在 Docker 之外)。我刚刚提交了一些 Dockerfiles,例如 this one for Rcpp - 它安装了来自 Debian 的多个软件包作为 r-cran-* 二进制文件和来自 CRAN 的两个不可用的二进制软件包。
    • @DirkEddelbuettel 不幸的是,评论中的链接已失效。我认为您的意思是github.com/RcppCore/Rcpp/blob/master/docker/ci/Dockerfile,我将其添加以供以后参考。谢谢!
    • 感谢指正。我还在 6 月份发表了一篇相关的后续博客文章。没有链接,因为我现在正在旅行并在手机上打字......
    • 亲爱的德克;安装 ubuntu 二进制文件是否还会安装所有依赖项,即插入符号有很多 - 还是您需要逐步浏览依赖项树?
    【解决方案2】:

    我找到了一个article,它描述了如何从预编译的二进制文件安装 R 包。它将我们 Jenkins 服务器上的构建时间从 45 分钟缩短到 3 分钟。

    这是我的Dockerfile

    FROM rocker/r-apt:bionic
    WORKDIR /app
    RUN apt-get update && \
      apt-get install -y libxml2-dev
    
    # Install binaries (see https://datawookie.netlify.com/blog/2019/01/docker-images-for-r-r-base-versus-r-apt/)
    COPY ./requirements-bin.txt .
    RUN cat requirements-bin.txt | xargs apt-get install -y -qq
    
    # Install remaining packages from source
    COPY ./requirements-src.R .
    RUN Rscript requirements-src.R
    
    # Clean up package registry
    RUN rm -rf /var/lib/apt/lists/*
    
    COPY ./src /app
    
    EXPOSE 5000
    CMD ["Rscript", "Server.R"]
    

    您可以添加带有包名的文件requirements-bin.txt

    r-cran-plumber
    r-cran-quanteda
    r-cran-irlba
    r-cran-lsa
    r-cran-caret
    r-cran-stringr
    r-cran-dplyr
    r-cran-magrittr
    r-cran-randomforest
    

    最后,requirements-src.R 用于无法作为二进制文件提供的软件包:

    pkgs <- c(
        'otherpackage'
    )
    
    install.packages(pkgs)
    

    【讨论】:

    • 这为我们节省了数年的构建时间。应标记为该问题的解决方案。
    • 这与我一年前的答案完全相同:在你需要的地方使用二进制文件。而你,就像我一样,指向 Ubuntu 和附加存储库。 Rutter PPA 现在有超过 4600 个预构建的包。
    • 公平,我改写了答案的第一行。这与您的建议非常相似。没有什么不同,只是更具体。
    • 感谢您,您帮助我显着缩短了 dockerfile 构建时间!
    • 链接的文章看起来不相关,而是涉及抽搐视频。看来预定的目标已经移动了。
    【解决方案3】:

    我最终按照@DirkEddelbuettel 的建议使用了rocker/r-base。还要感谢How to avoid reinstalling packages when building Docker image for Python projects?,我以一种不会在每次重建 docker 映像时都重新安装包的方式编写 Dockerfile。

    我想分享我的 Dockerfile 现在的样子,希望这对其他人有所帮助:

    FROM rocker/r-base
    
    RUN apt-get update
    
    # install packages 
    RUN apt-get -y install libcurl4-openssl-dev
    RUN apt-get -y install libssl-dev
    
    # set work directory 
    WORKDIR /myapp
    
    # copy requirments R script
    COPY ./Requirements.R /myapp/Requirements.R
    
    # run requirments R script
    RUN Rscript Requirements.R
    
    COPY . /myapp
    
    EXPOSE 8094
    
    ENV NAME R-test-service
    
    CMD ["Rscript", "my_R_api.R"]
    

    【讨论】:

    • 这仍然更加“昂贵”,因为您可以将这些 R 包安装为预构建的二进制文件。
    猜你喜欢
    • 2015-03-15
    • 1970-01-01
    • 2011-03-27
    • 2019-06-11
    • 2021-04-15
    • 1970-01-01
    • 2013-10-27
    • 2020-05-26
    • 1970-01-01
    相关资源
    最近更新 更多