Docker Community Forums

Share and learn in the Docker community.

Using multi-stage docker build for slimming down images with R dependency

build

#1

So, I’m building docker images for some applications that has R dependencies, but the naive build process that I wrote (please see below for Dockerfile, stage 1) leads to, IMO, inflated image size.

Therefore I’m thinking about using multi-stage build, reading how awesome it can be for shrinking down the image size.

Apparently, simply copying the R & Rscript binary and the packages from the build layer won’t work, as I did get the following error message, indicating I also need to copy those dynamic libs dependencies.

/usr/lib/R/bin/R: line 238: /usr/lib/R/etc/ldpaths: No such file or directory
/usr/lib/R/bin/exec/R: error while loading shared libraries: libR.so: cannot open shared object file: No such file or directory

So my question is,

  • is my approach fundamentally flawed (or not worth it at all given the space-saving/maintenance tradeoff), or
  • do I simply need to copy some more libraries?

And a remotely related issue: would it be a similar scenario for Python dependencies as well?

Thanks!


Illustration

####### stage 1: build
FROM ubuntu:18.10 as build

# update OS libs
ARG OS_LIBS="software-properties-common libcurl4-openssl-dev libssl-dev libxml2-dev gpg-agent gnupg"
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get -qqy update --fix-missing && \
    apt-get -qqy full-upgrade && \
    apt-get -qqy install --no-install-recommends \
        ${OS_LIBS} && \
    apt-get autoremove --purge -y && apt-get autoclean -y && \
    rm -rf /var/cache/apt/* /var/lib/apt/lists/* /var/tmp/* /tmp/* /usr/share/man/?? /usr/share/man/??_*

# install base R
ARG R_RELEASE_VERSION="3.5.1"
RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E084DAB9 && \
    add-apt-repository "deb http://cran.rstudio.com/bin/linux/ubuntu cosmic-cran35/" && \
    apt-get -qqy update --fix-missing && \
    apt-get -qqy full-upgrade && \
    apt-get -qqy install --no-install-recommends \
        r-base-core="${R_RELEASE_VERSION}"-1build1 \
        r-base-dev="${R_RELEASE_VERSION}"-1build1
# this is just a toy example
RUN R -e -vanilla 'install.packages("data.table", destdir = "/tmp/R_pkg_download/", clean = TRUE)'



####### stage 2: copy the binary and libs
FROM ubuntu:18.10

RUN mkdir -p /usr/lib/R \
             /usr/local/lib/R/site-library
COPY --from=builder /usr/bin/R /usr/bin/R
COPY --from=builder /usr/bin/Rscript /usr/bin/Rscript
COPY --from=builder /usr/lib/R /usr/lib/R
COPY --from=builder /usr/local/lib/R/site-library /usr/local/lib/R/site-library