如何减少安装 R 库的 Docker 容器的构建时间?

Posted

技术标签:

【中文标题】如何减少安装 R 库的 Docker 容器的构建时间?【英文标题】:How to reduce build time for a Docker container installing R libraries? 【发布时间】:2021-10-13 16:51:24 【问题描述】:

我需要在 Docker 容器中运行一些同时包含 Python 3.8 和 R 4.1.0 的代码。下面是我的 Dockerfile。


FROM python:3.8-slim-buster AS final-image

# R version to install
ARG R_BASE_VERSION=4.1.0

ARG PREBUILD_DEPS="software-properties-common gnupg2"
ARG BUILD_DEPS="build-essential binutils cmake gfortran libblas-dev liblapack-dev libjpeg-dev libpng-dev libnlopt-dev pkg-config"
ARG RUNTIME_DEPS="r-base=$R_BASE_VERSION-* libcurl4-openssl-dev libssl-dev libxml2-dev"
# venv path
ENV PATH="/opt/venv/bin:$PATH"

RUN apt-get update \
    # Adding this to install latest versions of g++
    && echo 'deb http://deb.debian.org/debian testing main' > /etc/apt/sources.list.d/testing.list \
    # Install the below packages to add repo which is then used to install R version 4
    && apt-get install -y --no-install-recommends $PREBUILD_DEPS \
    && add-apt-repository 'deb http://cloud.r-project.org/bin/linux/debian buster-cran40/'\
    # This key is required to install r-base version 4
    && apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-key FCAE2A0E115C3D8A \
    # Update again to use the newly added sources
    && apt-get update \
    && apt-get install -y --no-install-recommends $RUNTIME_DEPS $BUILD_DEPS \
    && python -m venv /opt/venv \
    && /opt/venv/bin/python -m pip install --upgrade pip \
    && rm -rf /var/lib/apt/lists/*

COPY requirements.txt packages.R /

RUN pip install wheel setuptools \
    && pip install --no-cache-dir -r requirements.txt \
    && pip install --no-cache-dir --no-binary xgboost xgboost \
    && Rscript packages.R \
    && strip --strip-unneeded usr/local/lib/R/site-library/Boom/lib/libboom.a \
    && strip --strip-debug /usr/local/lib/R/site-library/*/libs/*so \
    # Uninstall unnecessary dependencies
    && rm -rf /tmp/* \
    && apt-get purge -y --auto-remove $BUILD_DEPS $PREBUILD_DEPS \
    && apt-get autoremove -y \
    && apt-get autoclean -y \
    && rm -rf /var/lib/apt/lists/*

ENTRYPOINT XXX

这是packages.R 文件:

#Setting environment
rm(list = ls())
cat("\014")
print(Sys.time())

# CRAN mirror to use. cran.rstudio.com is a CDN and the recommended mirror.
# Specifying multiple backup CRAN mirrors as Jenkins builds fails
# intermittently due to unavailability of packages in main mirror.
cran_repos = c(MAIN_CRAN_MIRROR = 'https://cran.rstudio.com',
               ALT_CRAN_MIRROR = 'http://cran.r-project.org/')

#Loading Libraries
package_ls <- c(
  "config",
  "crayon",
  "aws.s3",
  "aws.ec2metadata",
  "dplyr",
  "data.table",
  "imputeTS",
  "Metrics",
  "StatMeasures",
  "tseries",
  "purrr",
  "log4r",
  "lubridate",
  "forecast",
  "caret",
  "MASS",
  "stringr",
  "tidyr",
  "uroot",
  "readr",
  "Boruta",
  "bsts"
)

for (pkg_name in package_ls) 
  message("Installing ", pkg_name)
  install.packages(pkg_name, repos = cran_repos)
  if (!(pkg_name %in% installed.packages()[, 'Package'])) 
    stop(pkg_name,
         " is a required package and it could not be installed, stopping!")
  

问题

构建 docker 容器花费的时间比我想的要多得多。这是因为,一些包(例如bsts)需要从源代码构建它们的依赖项(例如the C++ library Boom),这需要很多时间。 有没有办法:

    加快 R 库的构建?或 在本地构建 R 库并仅将二进制文件复制到 Docker 容器。或 以任何其他方式减少 R 包的构建时间。

提前致谢。

更新

来自 cmets 的一些想法:

@botje

    使用install.packages R function 的Ncpus 参数并行安装R 包。 (我有 4 个 CPU 可以使用,设置 Ncpus = 4 可以提高 10% 的速度。)
install.packages(package_ls, repos = cran_repos, Ncpus = 4)
    创建包含本地编译包的自定义 CRAN 镜像,以加快安装速度。

【问题讨论】:

这和c++有什么关系? 许多安装时间最长的 r 库正在编译它们的依赖项,这些依赖项是用 c++ 编写的。例如。在此处查看 Boom 包:github.com/steve-the-bayesian/BOOM 你多久重建一次这个容器镜像?您的 R 依赖项更改更频繁,还是您的 Python 依赖项更改更频繁?是否可以选择并行构建 R 包? 显然有一个 install.packages 命令,如果Ncpu &gt; 1 将并行安装。或者,您可以创建一个自定义 CRAN 镜像,其中还包含本地编译的二进制包以加快安装速度。 @santhisenan 我的意思是建议您致电install.packages 并提供完整的软件包列表,这样您的所有内核都将处于忙碌状态。我认为这应该会带来 2 倍或 3 倍的加速。你目前的方法仍然是串行安装包,所以你对最大的包只有一点并行优势 【参考方案1】:

我把你packages.R的最后一段改写如下:

install.packages(package_ls, Ncpus=16)

与使用Ncpus=1(189s 与 719s)相比,这使我的速度提高了 3 倍。

【讨论】:

对于延迟确认表示歉意。我能够确认 Ncpus 选项将安装时间减少 2-3 倍。

以上是关于如何减少安装 R 库的 Docker 容器的构建时间?的主要内容,如果未能解决你的问题,请参考以下文章

如何在构建时链接 docker 容器?

如何从 docker 容器运行 webpack 构建?

如何构建Memcached Docker容器

如何构建Memcached Docker容器

构建 docker 容器时 gcsfuse 无法挂载

Docker入门系列之四:Docker映像